feat(cms): 文章页标题下说明后台可编辑 + 文章数 {n} 占位符随数量变化

后台「页面文案」新增「文章页说明」(中/英 markdown,与瞬间/书架同构的
压平结构);{n} 在构建期替换为当前可见文章数。顺修默认文案错字
(月分分组→按月分组),en 文章页补齐标题与说明行(此前只有裸列表)。

验证: pnpm astro build exit 0;dist 断言「共 10 篇」动态计数与 en 侧文案;config-check 通过;E2E 61/61

Spec: none (页面文案体系的小增量,随 5l/5m 后续直落)

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-11-05 19:20:02 +08:00
1 parent 9b11070dd4
commit d37fe581c0
6 files changed
+44 -3

No files matched your search

+4
View File
@@ -9,3 +9,7 @@ moments:
books:
note_zh: 点一行展开封面与简介 · 置顶的书默认展开
note_en: 'Tap a row for the cover and blurb · pinned books start open'
archives:
note_zh: 按年份折叠 · 按月分组 · 共 {n} 篇
note_en: 'Folded by year · grouped by month · {n} posts in total'
+7
View File
@@ -170,6 +170,13 @@ collections:
fields:
- { label: 中文, name: note_zh, widget: markdown, required: false, hint: '一行小字;排版(字体/颜色)选中文字 → Insert ▸ 排版' }
- { label: English, name: note_en, widget: markdown, required: false }
- label: 文章页说明
name: archives
widget: object
required: false
fields:
- { label: 中文, name: note_zh, widget: markdown, required: false, hint: '一行小字;{n} 会替换为当前可见文章数(构建期);排版用 Insert ▸ 排版' }
- { label: English, name: note_en, widget: markdown, required: false }
- name: home
label: 主页设置
file: content/site/home.yaml
+1
View File
@@ -246,6 +246,7 @@ export const collections = {
schema: z.object({
moments: pageNoteSchema.optional(),
books: pageNoteSchema.optional(),
archives: pageNoteSchema.optional(),
}),
}),
siteTheme: defineCollection({
+9 -2
View File
@@ -181,6 +181,10 @@ const PAGE_NOTE_DEFAULTS = {
zh: '点一行展开封面与简介 · 置顶的书默认展开',
en: 'Tap a row for the cover and blurb · pinned books start open',
},
archives: {
zh: '按年份折叠 · 按月分组 · 共 {n} 篇',
en: 'Folded by year · grouped by month · {n} posts in total',
},
} as const;
/**
@@ -191,13 +195,16 @@ const PAGE_NOTE_DEFAULTS = {
* 「可选对象嵌可选对象不渲染子编辑器」的缺陷结构(#446/#654)。
*/
export async function pageNote(
page: 'moments' | 'books',
page: 'moments' | 'books' | 'archives',
locale: Locale,
/** 占位符替换(在 markdown 渲染前做):文章页用 {n}=可见文章数 */
vars?: Record<string, string | number>,
): Promise<PageNote> {
const entry = await getEntry('sitePages', 'pages');
const data = entry?.data?.[page];
const fallback = PAGE_NOTE_DEFAULTS[page];
const text = (locale === 'en' ? data?.note_en : data?.note_zh) || fallback[locale];
let text = (locale === 'en' ? data?.note_en : data?.note_zh) || fallback[locale];
if (vars) for (const [k, v] of Object.entries(vars)) text = text.replaceAll(`{${k}}`, String(v));
const html = await renderRich(text, { inline: true });
return { html, className: 'page-note' };
}
+4 -1
View File
@@ -5,16 +5,19 @@ import { isVisiblePost } from '../../lib/post-visibility';
import BaseLayout from '../../layouts/BaseLayout.astro';
import PostList from '../../components/PostList.astro';
import { sortPosts } from '../../lib/post-order';
import { pageNote } from '../../lib/site-content';
// 置顶优先 → 时间倒序(sortPosts 契约见 src/lib/post-order.ts)
const posts = sortPosts(
await getCollection('posts', ({ data }) => isVisiblePost(data)),
);
// 标题下说明:后台「页面文案 → 文章页说明」可改;{n} 占位符=可见文章数(构建期替换)
const note = await pageNote('archives', 'zh', { n: posts.length });
---
<BaseLayout title="文章 · wait4x">
<h1 class="page-title">文章</h1>
<p class="page-note">按年份折叠 · 月分分组 · 共 {posts.length} 篇</p>
<p class="page-note" set:html={note.html} />
<PostList {posts} fold />
</BaseLayout>
+19
View File
@@ -5,6 +5,7 @@ import { isVisiblePost } from '../../../lib/post-visibility';
import BaseLayout from '../../../layouts/BaseLayout.astro';
import PostList from '../../../components/PostList.astro';
import { sortPosts } from '../../../lib/post-order';
import { pageNote } from '../../../lib/site-content';
const posts = sortPosts(
await getCollection('posts', ({ data }) => isVisiblePost(data)),
@@ -12,8 +13,26 @@ const posts = sortPosts(
const enTitle = Object.fromEntries(
(await getCollection('postsEn')).map((e) => [e.id, e.data.title]),
);
const note = await pageNote('archives', 'en', { n: posts.length });
---
<BaseLayout title="Posts · wait4x" description="All posts">
<h1 class="page-title">Posts</h1>
<p class="page-note" set:html={note.html} />
<PostList {posts} locale="en" titleOverrides={enTitle} fold />
</BaseLayout>
<style>
.page-title {
font-size: var(--text-h1);
line-height: var(--leading-heading);
color: var(--ink-1);
margin-top: var(--space-5);
text-wrap: balance;
}
.page-note {
font-size: 13px;
color: var(--ink-4);
margin-block: var(--space-1) var(--space-4);
}
</style>