# 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: 副标题(可选,markdown 短文本) name: subtitle widget: object hint: 渲染在身份语下方;留空不渲染 fields: - { label: 中文, name: zh, widget: string, required: false } - { label: 英文, name: en, widget: string, required: false } - label: 最新影像张数 name: latestPhotos widget: number required: false default: 4 min: 0 max: 6 hint: '1-6;填 0 = 隐藏「最新影像」区块。留空默认 4' - label: 首页每轨文章条数 name: perTrackLimit widget: number required: false default: 6 min: 4 max: 8 hint: 阅读轨/技术轨各显示条数,留空默认 6 - label: 区块开关 name: sections widget: object required: false hint: 关掉的区块不渲染(默认全开) fields: - { label: 文章列表, name: tracks, widget: boolean, required: false, default: true } - { label: 最新影像, name: photos, widget: boolean, required: false, default: true } - { label: 贡献热力图, name: heatmap, widget: boolean, required: false, default: true } - { label: 项目墙, name: projects, widget: boolean, required: false, default: true } - 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。填写的名字须与仓库短名一致' - label: 项目墙模式 name: mode widget: select required: false default: all options: [{ label: 全部, value: all }, { label: 仅白名单, value: only }, { label: 排除黑名单, value: exclude }] hint: only/exclude 需配合下面的名单 - label: 白名单(仓库短名) name: include widget: list required: false hint: 'mode=仅白名单时生效,如 pi-board' - label: 黑名单(仓库短名) name: exclude widget: list required: false hint: 'mode=排除黑名单时生效,如 blog' - label: 排序 name: sort widget: select required: false default: pinned-first options: - { label: 置顶优先,其余按星数, value: pinned-first } - { label: 星数降序, value: stars } - { label: 最近更新, value: updated } - label: 来源过滤 name: perSource widget: select required: false default: both options: [{ label: 双源合并, value: both }, { label: 仅 GitHub, value: github }, { label: 仅自托管 gitea, value: gitea }] - label: 开篇文案来源 name: intro_from widget: select required: false default: 'off' options: - { label: 用本页叙述(默认), value: 'off' } - { label: GitHub profile README, value: github-readme } hint: 'github-readme = 构建期取 wait4xx/wait4xx 的 README 渲染为开篇;缓存入仓 content/.github-readme.md,取不到自动回落叙述'