feat(cms): 内容管理闭环——站点单例三件套+文章视频字段
- A 站点文案单例:content/site/{home,about,opensource}.yaml +
src/lib/site-content.ts 访问层(字段级回落默认,默认值=原文案逐字
一致,零回归);接线主页 tagline(en 首页新增该块)、关于页 intro、
开源页叙述三段 + PINNED 参数化(projects.ts: loadProjects(pinned)
/orderPinned,PINNED_DEFAULT 仅缺省兜底)
- loader 语义修正(返工如实入档):Astro 7 的 file() 把 YAML 顶层对象
按 Object.entries 拆成多条目(id=key、data=value),单例字段必炸
schema;改 glob 精确到单文件 = 真单例语义,data 即文件根对象,
Sveltia 可编辑根字段零嵌套(比包 main: 层的方案后台体验更好)
- B 文章媒体:posts +video/+poster;Sveltia file 字段
(media_folder=public/media、public_folder=/media、hint ≤50MB);
正文后渲染 video controls preload=metadata playsinline,无则不渲染;
图片链路核对本已一致(./assets 走 Astro 管线);链接 markdown 原生
- docs/写作指南.md 补「后台上传」节(三类媒体 + 三单例操作 + 体积纪律)
Sveltia 集合:posts / moments / photos / site_pages(三单例)
车道:op-gitea(实测 tagline 改 yaml 产物联动、置空回落默认、pinned
改名排序变、视频临时件渲染全对、构建绿 + lint 45 页 0/0/0);收编
复验:构建 44 页 + E2E 37/37 + 三 yaml 扁平键就位
验证: pnpm astro build 44 页 exit 0;E2E 37/37 PASS;content-lint
0/0/0;播放器/单例/置顶 playwright 实测全过
Spec: none (内容管理闭环,车道级交付)
Co-authored-by: GLM-5.3
This commit is contained in:
1 parent
5be09b6f32
commit
264148f0a6
15 files changed
+346
-12
No files matched your search
@@ -15,6 +15,9 @@ export const POST_TRACKS = {
|
||||
export type PostCategory = keyof typeof POST_TRACKS;
|
||||
export type PostTrack = (typeof POST_TRACKS)[PostCategory];
|
||||
|
||||
/** 双语文案字段:两语言各自可选,缺一回落一(回退逻辑在 src/lib/site-content.ts) */
|
||||
const bilingual = z.object({ zh: z.string().optional(), en: z.string().optional() });
|
||||
|
||||
export function trackOf(category: PostCategory): PostTrack {
|
||||
return POST_TRACKS[category];
|
||||
}
|
||||
@@ -30,6 +33,10 @@ const postsSchema = z.object({
|
||||
description: z.string().optional(),
|
||||
/** 原书作者(书架卡署名) */
|
||||
bookAuthor: z.string().optional(),
|
||||
/** 文章附视频(单文件):存 public/media,frontmatter 写 /media/<name>.mp4 */
|
||||
video: z.string().optional(),
|
||||
/** 视频封面(可选):同 public/media 下的图片 URL */
|
||||
poster: z.string().optional(),
|
||||
draft: z.boolean().optional(),
|
||||
});
|
||||
|
||||
@@ -63,6 +70,30 @@ const _exifShapeOk: _PhotoExifOut extends PhotoExif
|
||||
: never = true;
|
||||
|
||||
export const collections = {
|
||||
// 站点文案单例(后台「页面文案」可改):一文件一集合
|
||||
// 用 glob(pattern 精确到单文件) 而非 file():Astro 的 file() 把 YAML 顶层对象当“条目映射”
|
||||
// (每个顶层键各自成一条 entry,见 astro/dist/content/loaders/file.js),根级字段会被拆碎;
|
||||
// glob 每文件一条 entry(id=文件名)、data=文件根对象,正是单例语义且 Sveltia 可直接编根字段
|
||||
// 双语文案用 {zh,en} 对象字段(各自可选):任一语言空/缺字段 → src/lib/site-content.ts 回落默认
|
||||
siteHome: defineCollection({
|
||||
loader: glob({ pattern: 'home.yaml', base: './content/site' }),
|
||||
schema: z.object({ tagline: bilingual.optional() }),
|
||||
}),
|
||||
siteAbout: defineCollection({
|
||||
loader: glob({ pattern: 'about.yaml', base: './content/site' }),
|
||||
schema: z.object({ intro: bilingual.optional() }),
|
||||
}),
|
||||
siteOpenSource: defineCollection({
|
||||
loader: glob({ pattern: 'opensource.yaml', base: './content/site' }),
|
||||
schema: z.object({
|
||||
blurb: bilingual.optional(),
|
||||
blurb_after: bilingual.optional(),
|
||||
repo_url: z.string().optional(),
|
||||
repo_label: z.string().optional(),
|
||||
/** 置顶仓短名,顺序即展示顺序(原 projects.ts 硬编码名单迁于此) */
|
||||
pinned: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
// slug 即文件名(glob loader 默认按文件名生成 id)
|
||||
posts: defineCollection({
|
||||
loader: glob({ pattern: '**/*.md', base: './content/posts' }),
|
||||
|
||||
Reference in new issue
Block a user