feat(cms): 后台扩展五件——关于页 markdown 化/社交/头像/favicon/分轨首页

- T1 关于页=markdown 文档:about.yaml intro 扩为多段 markdown(zh/en),
  AboutPage 用 @astrojs/markdown-remark 的 createMarkdownProcessor(进程
  内单例复用)+ set:html 渲染,正文 p/ul/strong/a 对齐站点排版;名片与
  技能卡结构不动
- T2 社交链接单一数据源:home.yaml socials[](label/url/icon)+
  SocialLinks.astro(图标注册表白名单:github/rss/email/bilibili/x,
  未登记 icon 回退纯文字),首页 zh/en 内联硬编码社交块删除
- T3 头像与 favicon 可上传:schema avatar: image()(Astro Image 出 60px
  WebP,未设回退渐变 SVG);home.yaml favicon → BaseLayout link[rel=icon]
  按扩展名给 type,留空回退 /favicon.svg
- T4 首页分轨:PostList perTrack → 阅读轨/技术轨两段各限 6,各自出口
  (阅读→/books/ 技术→/archives/,en 同构);E2E 断言改为两段各≤6+各自
  出口+阅读在前
- T5 后台列表日期:posts summary「{{pubDate}} · {{title}}」、moments
  「{{fields.pubDate}} · {{fields.text}}」+sortable;photos 无 frontmatter
  日期(JSON sidecar)保持分组 · 标题并在文档写明原因
- 顺手修 content-lint 漏报:中文文件名在 HTML 里为 %XX 编码,脚本直接
  拼盘上路径导致 6 条"缺图"误报 → 加 decodeURI
- 清理:删除书封误传遗留的双重嵌套目录文件

车道:op-gitea(5/5,build+E2E 37/37+lint 47 页 0/0/0);收编复验:
build 46 页 + E2E 37/37 连跑(首跑两红为车道并发构建擦 dist 的瞬时态,
复跑绿)

验证: node v26.13.0 + astro 7.4.4 全量构建 46 页 exit 0;E2E 37/37;
      content-lint 0/0/0;books details/命令面板 playwright 实测

Spec: none (后台能力扩展,车道级交付)

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-11-02 15:46:41 +08:00
1 parent 227bc24797
commit 328ab68f18
16 files changed
+409 -146

No files matched your search

+4 -1
View File
@@ -13,6 +13,7 @@ import Footer from '../components/Footer.astro';
import ThemeScript from '../components/ThemeScript.astro';
import Keyboard from '../components/geek/Keyboard.astro';
import { localeOf, localePath } from '../lib/locale';
import { siteFavicon } from '../lib/site-content';
import SearchDialog from '../components/SearchDialog.astro';
import BuildInfo from '../components/geek/BuildInfo.astro';
import { ClientRouter } from 'astro:transitions';
@@ -30,6 +31,8 @@ const rawPath = Astro.url.pathname.replace(/\/index\.html$/, '');
const zhPath = localeOf(rawPath) === 'en' ? localePath(rawPath, 'zh') : rawPath;
const enPath = localePath(rawPath, 'en');
const withSlash = (p: string) => (p.endsWith('/') ? p : `${p}/`);
// 站点图标可配置(后台「主页设置 → 站点图标」):缺省回退 /favicon.svg
const favicon = await siteFavicon();
// 自指 canonical(T2):SEO 权重收敛到当前页自身,与 hreflang 组合覆盖双轨
const canonicalUrl = new URL(withSlash(rawPath), Astro.site).href;
---
@@ -39,7 +42,7 @@ const canonicalUrl = new URL(withSlash(rawPath), Astro.site).href;
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type={favicon.type || undefined} href={favicon.href} />
<meta name="generator" content={Astro.generator} />
<meta name="description" content={description} />
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />