diff --git a/.spec/specs/2026-10-25_add-blog-i18n/tasks.md b/.spec/specs/2026-10-25_add-blog-i18n/tasks.md index 9472c8e..f7b67a3 100644 --- a/.spec/specs/2026-10-25_add-blog-i18n/tasks.md +++ b/.spec/specs/2026-10-25_add-blog-i18n/tasks.md @@ -5,7 +5,7 @@ ## 阶段一:实现 -- [ ] T1 astro i18n 配置 + locale 管道 +- [x] T1 astro i18n 配置 + locale 管道 - claim: orchestrator - boundary: 只改 astro.config.mjs(i18n 段)与 src/lib/locale.ts(当前语言工具) - verify: `pnpm astro build` @@ -16,13 +16,13 @@ - boundary: 新建 src/i18n/ui.ts(zh/en 字典)并串接 Footer/SearchDialog/gallery/moments/about 页的静态文案;不碰 Header/BaseLayout(orchestrator 的语言切换在那) - verify: `pnpm astro build && grep -q "zh" dist/index.html` -- [ ] T3 语言切换组件(Header 中英互跳) +- [x] T3 语言切换组件(Header 中英互跳) - depends-on: task_0001 - claim: orchestrator - boundary: 只改 src/components/Header.astro 与 src/lib/locale.ts - verify: `pnpm astro build && grep -q 'href="/en/"' dist/index.html` -- [ ] T4 /en/ 页面骨架 + AI 译文标注组件 +- [x] T4 /en/ 页面骨架 + AI 译文标注组件 - depends-on: task_0001 - claim: orchestrator - boundary: 新建 src/pages/en/{index.astro,archives/[...slug].astro,archives/index.astro,gallery,moments,about}(复用组件+locale prop);src/components/AiTranslatedBadge.astro;posts-en 集合定义进 content.config.ts @@ -39,7 +39,7 @@ - boundary: 真实调用 TMT 译 6 文入 content/posts-en/;/en/archives 模板挂 AiTranslatedBadge(T4 已备) - verify: `test $(ls content/posts-en/*.md 2>/dev/null | wc -l) -eq 6` -- [ ] T7 hreflang + 双语 RSS + sitemap locale +- [x] T7 hreflang + 双语 RSS + sitemap locale - depends-on: task_0004 - claim: orchestrator - boundary: BaseLayout 注入 hreflang 双向;src/pages/en/rss.xml.ts;sitemap 配置 i18n diff --git a/astro.config.mjs b/astro.config.mjs index f6e2c20..347b6fd 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -18,6 +18,11 @@ const date = export default defineConfig({ site: 'https://wait4x.online', integrations: [pagefind(), sitemap()], + i18n: { + defaultLocale: 'zh', + locales: ['zh', 'en'], + routing: { prefixDefaultLocale: false }, + }, vite: { define: { 'import.meta.env.GIT_COMMIT_SHA': JSON.stringify(sha), diff --git a/src/components/AiTranslatedBadge.astro b/src/components/AiTranslatedBadge.astro new file mode 100644 index 0000000..a29cd91 --- /dev/null +++ b/src/components/AiTranslatedBadge.astro @@ -0,0 +1,28 @@ +--- +// AI 译文标注(用户拍板:文学内容机器翻译须明示) +import { t } from '../i18n/ui'; +interface Props { locale?: 'zh' | 'en' } +const { locale = 'en' } = Astro.props; +--- + +

{t('ai_translated_note', locale)}TMT

+ + diff --git a/src/components/Header.astro b/src/components/Header.astro index 44dd19b..2d0aeec 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -1,4 +1,6 @@ --- +import { localeOf, localePath } from '../lib/locale'; + // 顶部导航:≤4 项纪律(防 higan 十项复发);当前页 aria-current const nav = [ { href: '/archives/', label: '文章' }, @@ -8,6 +10,11 @@ const nav = [ const path = Astro.url.pathname; const isCurrent = (href: string) => path === href || path === href.replace(/\/$/, '') || path.startsWith(href); + +// 语言切换:同路径跨前缀跳转(zh 无前缀 ↔ /en/),预构建双语毫秒级 +const curLocale = localeOf(path); +const switchHref = localePath(path, curLocale === 'zh' ? 'en' : 'zh'); +const switchLabel = curLocale === 'zh' ? 'EN' : '中'; ---