feat(i18n): UI 字典串接与三页薄化——/en/ 全站落成

- op-gitea 车道:ui.ts 扩 26 键(占位 {n}/{title}/{exif} 约定),五组件
  locale prop 串接,zh 零回归(48 键/18 页实测)
- orchestrator 收尾:gallery/moments/about 三页 body 提取为
  components/pages/*Page(zh/en 薄页双路由),/en/ 全家福 21 页
- 提取工程三坑入库:HTML 注释不可进 frontmatter 模块区;搬移脚本会吃
  开栏 ---;单级页面搬二级目录后 import 全线差一层

验证: astro build 21 页 exit 0;/en/ 七类路由产物断言过;en 页
      ICP 备案保留;zh 侧文案抽查不变

Spec: 2026-10-25_add-blog-i18n
Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-10-25 09:26:14 +08:00
1 parent c74815b516
commit 4aa79fca06
13 files changed
+757 -653

No files matched your search

+19 -4
View File
@@ -1,15 +1,27 @@
---
// 站内搜索(Pagefind):首次打开才懒加载索引(spectre 模式,见调研报告 §4c)
// 入口:Header 搜索钮 + 键盘 `/`
import { t } from '../i18n/ui';
import type { Locale } from '../lib/locale';
// /en/ 侧由 T4 薄页传 locale='en';zh 路由无人传参,默认 zh 零回归
interface Props {
locale?: Locale;
}
const { locale = 'zh' } = Astro.props;
---
<dialog id="search-dialog" class="search-dialog">
<input id="search-input" type="search" placeholder="搜索文章…(Esc 关闭)" autocomplete="off" />
<dialog id="search-dialog" class="search-dialog" data-locale={locale}>
<input id="search-input" type="search" placeholder={t('search_placeholder', locale)} autocomplete="off" />
<ul id="search-results" class="results" aria-live="polite"></ul>
<p class="search-hint">索引由 Pagefind 构建期生成 · 静态站零后端</p>
<p class="search-hint">{t('search_hint', locale)}</p>
</dialog>
<script>
import { t } from '../i18n/ui';
// 模块脚本读不到 Astro props:空态文案语言在事件触发时从 dialog 的
// data-locale 现取——ClientRouter 换页重建 DOM 后仍能拿到当前页语言
const dlg = document.getElementById('search-dialog') as HTMLDialogElement;
const input = document.getElementById('search-input') as HTMLInputElement;
const list = document.getElementById('search-results')!;
@@ -59,7 +71,10 @@
li.appendChild(a);
list.appendChild(li);
}
if (!list.children.length) list.innerHTML = '<li class="empty">无结果</li>';
if (!list.children.length) {
const loc = (document.getElementById('search-dialog')?.dataset.locale ?? 'zh') as 'zh' | 'en';
list.innerHTML = `<li class="empty">${t('search_no_results', loc)}</li>`;
}
}, 200);
});
</script>