feat: implement ui i18n support

This commit is contained in:
草师傅 2025-08-11 16:06:14 +08:00
parent 457fb93718
commit 698c411c71
Signed by: gb
GPG key ID: 43330A030E2D6478
13 changed files with 162 additions and 54 deletions

View file

@ -4,16 +4,20 @@ import { getCollection } from 'astro:content';
import NewsLetter from "../components/NewsLetter.astro";
import {siteConfig} from "../config";
import ArticleList from "../components/ArticleList.astro";
import { getLangFromUrl, useTranslations, useTranslatedPath } from '../i18n/utils';
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
const translatePath = useTranslatedPath(lang);
const posts = await getCollection('posts');
posts.sort((a, b) => new Date(b.data.pubDate).getTime() - new Date(a.data.pubDate).getTime());
---
<Layout title="Blog Posts" description="List all files and folders in the directory.">
<Layout title="Blog Posts" description="List all posts on the website.">
<h1 class="title">~/blog</h1>
<div class="content">
<p class="typewriter">Posts from the terminal.</p>
<p class="typewriter">{t('posts.description')}</p>
<div style="margin-top: 2rem;">
<span class="command">ls -la posts/</span>
@ -22,9 +26,9 @@ posts.sort((a, b) => new Date(b.data.pubDate).getTime() - new Date(a.data.pubDat
<div style="margin-top: 2rem;">
<p>
<span class="command">cat rss.txt</span>
<span class="command">cat subscribe.txt</span>
<br />
<a href="/rss.xml" style="margin-left: 1rem;">Subscribe to RSS feed</a>
<a href="/rss.xml" style="margin-left: 1rem;">{t('subscribe.rss')}</a>
</p>
{siteConfig.newsletter.enabled && <NewsLetter listmonkInstance={siteConfig.newsletter.listmonk.instanceDomain} listuuid={siteConfig.newsletter.listmonk.listuuid} />}
</div>

View file

@ -10,6 +10,11 @@ import { ExtractFirstImage } from '../../plugins/extract-images';
import AuthorInfo from "../../components/helper/authors/Info.astro";
import TableOfContents from "../../components/TableOfContents.astro";
import "katex/dist/katex.css"
import { getLangFromUrl, useTranslations, useTranslatedPath } from '../../i18n/utils';
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
const translatePath = useTranslatedPath(lang);
export async function getStaticPaths() {
const blogEntries = await getCollection('posts');
@ -29,6 +34,9 @@ const author = Array.isArray(entry.data.author) ? entry.data.author : (entry.dat
const wordcount = remarkPluginFrontmatter.wordcount;
const lastUpdated = remarkPluginFrontmatter.lastModified;
const pubDate = new Date(entry.data.pubDate).toISOString().split('T')[0]
const lastUpdatedDate = new Date(lastUpdated).toISOString().split('T')[0]
// Get author data
const authorData = await Promise.all((author).map((singleAuthor) => getEntry(singleAuthor).then(authorEntry => authorEntry?.data)))
const authorInfo = authorData.includes(undefined) ? [{data: siteConfig.defaultAuthor}] : authorData;
@ -56,10 +64,10 @@ const cover = customFeaturedImage || matchedImage_src?.src || firstImageURL || `
<article>
<h1 class="title">{entry.data.title}</h1>
{authorInfo.map((a: any) => <AuthorInfo data={a} />)}
<span class="date">{new Date(entry.data.pubDate).toISOString().split('T')[0]}</span>
<span class="date">(Updated on {new Date(lastUpdated).toISOString().split('T')[0]})</span>
<span class="date">{pubDate}</span>
{pubDate === lastUpdatedDate && <span class="date">({t('article.last_update')} {lastUpdatedDate})</span>}
<span>|</span>
<span class="wordcount">{wordcount.words} words</span>
<span class="wordcount">{wordcount.words} {t('article.word_count')}</span>
{ (cover && cover !== firstImageURL && cover !== `/blog/${slug}/featured.png`) && <Image class="cover" width=720 height=480 src={cover} alt={`cover of ${entry.data.title}`} /> }
{headings.length !== 0 && <TableOfContents headings={headings} />}
{entry.data.summary && <p class="summary">{entry.data.summary}</p> }
@ -70,8 +78,8 @@ const cover = customFeaturedImage || matchedImage_src?.src || firstImageURL || `
<div class="extra-post" style="margin-top: 2rem; border-top: 1px solid var(--border-color); padding-top: 1rem;">
<ReplyViaEmail title={entry.data.title} email={authorInfo[0].email} />
<br>
<a href="/blog">&larr; Back to posts</a>
{!noscript && <h2>Comments</h2> <Comments />}
<a href="/blog">&larr; {t('article.back_to_posts')}</a>
{!noscript && <h2>{t('article.comments')}</h2> <Comments />}
{!noscript &&
<script>
import "katex/dist/contrib/copy-tex.js"