feat(pages): /books 书架与 /opensource 开源页——导航第四项(T2/T5)

- BooksPage:色脊排版卡(mood 竖脊+文楷书名+作者+三行截断策展语)
  × 年份分组规整网格;zh/en 双路由;阅读轨标题旁「书架 →」入口
- /opensource:全量仓墙(ProjectWall 加 limit prop,首页精选 6 不变)
  + 热力图 + 本站开源叙事段;导航第四项「开源」(i18n nav_opensource)
- 五书 frontmatter 策展字段(含泥潭=刘楚昕)

验证: build 28 页 exit 0;books/opensource zh/en 五路由产物断言过;
      五书卡与作者 grep 在案;E2E 30/30 PASS

Spec: 2026-10-25_add-terminal-books-admin

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-10-25 13:46:56 +08:00
1 parent 3bd8369eda
commit 90574edce7
9 files changed
+180 -2

No files matched your search

+6 -1
View File
@@ -3,6 +3,11 @@
// 双源数据见 src/lib/projects.ts;语言色点用 linguist 常用色映射
import { loadProjects, type RepoCard } from '../../lib/projects';
interface Props {
/** 展示上限:首页精选 6;/opensource 全量传大数 */
limit?: number;
}
const { limit = 6 } = Astro.props;
const LANG_COLORS: Record<string, string> = {
Astro: '#ff5a03', TypeScript: '#3178c6', JavaScript: '#f1e05a',
Python: '#3572a5', Go: '#00add8', Rust: '#dea584', Shell: '#89e051',
@@ -11,7 +16,7 @@ const LANG_COLORS: Record<string, string> = {
let projects: RepoCard[] = [];
try {
projects = await loadProjects();
projects = (await loadProjects()).slice(0, limit);
} catch {
projects = []; // 兜底已在 lib 内处理,此处再守一层:空墙不破构建
}