Files
blog/public/admin/config.yml
T
wait4xandGLM-5.3 328ab68f18 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
2026-11-02 15:46:41 +08:00

184 lines
9.1 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# yaml-language-server: $schema=https://unpkg.com/@sveltia/cms/schema/sveltia-cms.json
# Sveltia CMS 配置(T3 试水):仅 photos 集合,见 docs 预研报告
# 纪律:不开内建图片优化(transformations 会把原图转 webp 抹掉 EXIF,构建期提取报废)
backend:
name: gitea
repo: wait4x/blog
branch: main
# 走博客域同源反代(nginx /gitea/ → 127.0.0.1:13020):
# ①绕开 git.wait4x.online 的 ESA 522 ②同源无 CORS ③ESA 缓存规则已排除 /artalk/api
base_url: https://wait4x.online/gitea
api_root: https://wait4x.online/gitea/api/v1
media_folder: content/photos
site_url: https://wait4x.online
output:
# Astro zod optional 兼容:空可选字段不写文件(官方 Astro 指南建议)
omit_empty_optional_fields: true
collections:
# 文章(含书评/技术/照片三轨;书=category:reading 的文章,同一集合管理)
- name: posts
label: 文章
label_singular: 文章
folder: content/posts
create: true
# 中文主稿;英文为 TMT 预翻译入仓的 .en.md(posts-en 集合不在后台,防误改译文)
slug: '{{slug}}'
summary: '{{pubDate}} · {{title}}'
sortable_fields: [pubDate, title]
# 注意:Sveltia 对 folder 集合的 media_folder 按"相对集合目录"解析
# (写成 content/posts/assets 会二次嵌套成 content/posts/content/posts/assets,
# 实测 2026-11-02 首上传即踩),故这里必须写 assets
media_folder: assets
public_folder: ./assets
fields:
- { label: 标题, name: title, widget: string }
- { label: 日期, name: pubDate, widget: datetime, date_format: 'YYYY-MM-DD', time_format: false, format: 'YYYY-MM-DD' }
- { label: 分轨, name: category, widget: select, options: [{label: 阅读, value: reading}, {label: 技术, value: tech}, {label: 照片, value: photo}] }
- { label: 标签, name: tags, widget: list, required: false }
- { label: 情绪色(书评色脊), name: mood, widget: color, required: false, hint: '#RRGGBB,仅阅读轨使用' }
- { label: 原书作者, name: bookAuthor, widget: string, required: false }
- { label: 一句话描述(书架策展语), name: description, widget: text, required: false }
- { label: 书封图, name: cover, widget: image, required: false, hint: '上传后自动生成,无需手填路径;仅阅读轨展示' }
- label: 附视频(可选)
name: video
widget: file
required: false
media_folder: public/media
public_folder: /media
hint: '展示在正文之后;mp4/webm ≤50MB(走 public/media,构建时原样拷贝,不做转码)'
- label: 视频封面(可选)
name: poster
widget: string
required: false
hint: '填 /media/xxx.jpg(先上传到 public/media 取路径);缺省浏览器自取首帧'
- { label: 隐藏(不进列表/sitemap), name: hiddenTag, widget: boolean, required: false, hint: '对应 tags 含 hidden;保存后请人工核对' }
- { label: 草稿, name: draft, widget: boolean, required: false, default: false }
- { label: 正文, name: body, widget: markdown }
# 瞬间:随手发(text/image 至少其一——Sveltia 无法表达条件必填,两者都设可选,
# 保存前自查;pubDate 必填)。图片走图库媒体库(content/photos 同源可复用)
- name: moments
label: 瞬间
folder: content/moments
create: true
slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
summary: '{{fields.pubDate}} · {{fields.text}}'
sortable_fields: [pubDate, text]
fields:
- { label: 时间, name: pubDate, widget: datetime, date_format: 'YYYY-MM-DD', time_format: false, format: 'YYYY-MM-DD' }
- { label: 文字, name: text, widget: text, required: false, hint: '一句话(与图片至少填一项)' }
- { label: 图片, name: image, widget: image, required: false, hint: '与文字至少填一项;建议先压缩' }
- label: 标签
name: tags
widget: list
required: false
- name: photos
label: 图库照片
folder: content/photos
# 整文件 JSON(非 frontmatter)= 现有 sidecar 同构;不设 format 条目不列出
format: json
create: true
# 入口相对:jpg 与 sidecar 同目录;image 引用写裸文件名(loader new URL 等价解析)
media_folder: ''
public_folder: ''
summary: '{{fields.group}} · {{fields.title}}'
# 照片无 frontmatter 日期(JSON sidecar,时间在 exif/文件侧)——列表按标题/分组排序
sortable_fields: [title, group]
fields:
# title 必填:Astro schema z.string() 无 .optional(),omit 纪律下必需且有值才会落键(空 title 会让 main 不可构建)
- { label: 标题, name: title, widget: string, required: true }
- { label: 图片, name: image, widget: image }
- { label: 分组, name: group, widget: select, options: [street, landscape] }
- { label: 替代文本, name: alt, widget: string, required: false }
- { label: 人为描述, name: caption, widget: text, required: false, hint: 展示在灯箱里的人为描述(一句话策展文案) }
- label: EXIF 覆盖(一般留空,构建期自动从图提取)
name: exif
widget: object
required: false
fields:
- { label: 机身, name: make, widget: string, required: false }
- { label: 镜头, name: lens, widget: string, required: false }
- { label: 光圈值, name: fNumber, widget: number, required: false }
- { label: 曝光秒, name: exposureTime, widget: number, required: false }
- { label: ISO, name: iso, widget: number, required: false }
# 页面文案单例(cms 车道 A):三个文件型入口,保存即写 content/site/*.yaml,
# 字段与 Astro siteHome/siteAbout/siteOpenSource 的 schema 一一对应(zh/en 双字段,留空回落默认)
- name: site_pages
label: 页面文案
files:
- name: home
label: 主页设置
file: content/site/home.yaml
# 头像上传落 content/site/assets/,yaml 写 ./assets/xxx(Astro 图片管线优化)
media_folder: content/site/assets
public_folder: ./assets
fields:
- label: 身份语
name: tagline
widget: object
fields:
- { label: 中文, name: zh, widget: string, required: false }
- { label: 英文, name: en, widget: string, required: false }
- label: 头像(可选)
name: avatar
widget: image
required: false
hint: '留空 = 内置渐变占位;上传后自动优化为 60px WebP'
- label: 站点图标 favicon
name: favicon
widget: string
required: false
hint: 'public 下的路径,如 /icons/my.ico 或 /icons/my.svg;留空回退 /favicon.svg。经「图标」媒体库上传'
- label: 社交链接(顺序即展示顺序)
name: socials
widget: list
required: false
summary: '{{fields.label}} → {{fields.url}}'
fields:
- { label: 名称(无障碍文字), name: label, widget: string }
- { label: 链接, name: url, widget: string }
- label: 图标
name: icon
widget: select
required: false
options: [github, rss, email, bilibili, x]
hint: '不在列表里的留空 → 显示纯文字按钮'
- name: about
label: 关于页
file: content/site/about.yaml
fields:
- label: 正文(markdown,多段)
name: intro
widget: object
hint: 渲染在「关于」标题下方、名片之上;支持段落/列表/粗斜体/链接;留空用默认文案
fields:
- { label: 中文, name: zh, widget: markdown, required: false }
- { label: 英文, name: en, widget: markdown, required: false }
- name: opensource
label: 开源页
file: content/site/opensource.yaml
fields:
- label: 叙述(链接前)
name: blurb
widget: object
fields:
- { label: 中文, name: zh, widget: string, required: false }
- { label: 英文, name: en, widget: string, required: false }
- { label: 仓库链接地址, name: repo_url, widget: string, required: false }
- { label: 仓库链接文字, name: repo_label, widget: string, required: false }
- label: 叙述(链接后)
name: blurb_after
widget: object
fields:
- { label: 中文, name: zh, widget: text, required: false }
- { label: 英文, name: en, widget: text, required: false }
- label: 置顶项目(仓库短名,顺序即展示顺序)
name: pinned
widget: list
required: false
hint: '如 blog;留空则回落默认 blog。填写的名字须与仓库短名一致'