fix(admin): 主题设置集合结构修复 + 集合结构构建校验

用户实测后台报错:「主题设置 集合: The file option content/site/theme.yaml is
invalid. It must be the path to a JSON file」——根因是 site_theme 把 `file:`
直接写在集合层级,而 Decap/Sveltia 的文件集合必须是
`files: [{ name, label, file, format, fields }]` 结构;缺 files 包装时 Sveltia
按单文件变体解析并期待 JSON 路径,故报该错。

- site_theme 改为标准 files 集合(format: yaml 显式声明)
- site_pages 三单例补显式 format: yaml(扩展名推断可用但显式更稳)
- config-check.py 增加结构断言:每个集合必须 folder 或 files 二选一、files
  项必须齐 file/label/fields、file 必须指向真实文件——这类"后台整体打不开"
  的结构错从此在构建期拦截

验证: config-check 五文件全 OK(207 字段/64 hint)+ 结构断言通过;
      pnpm astro build exit 0

Spec: none (后台配置结构修复,构建校验加固)

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-11-02 19:35:28 +08:00
1 parent c772236d1a
commit ed473e996a
2 files changed
+29

No files matched your search

+8
View File
@@ -60,8 +60,13 @@ collections:
# 主题旋钮(样式即数据 · 层 4):只放白名单内的 9 组,越界值会被构建期钳制 # 主题旋钮(样式即数据 · 层 4):只放白名单内的 9 组,越界值会被构建期钳制
- name: site_theme - name: site_theme
label: 主题设置
# 文件集合必须是 files: [{file,label,fields}] 结构;把 file 直接写在集合层级会被 Sveltia 判非法(2026-11-02 实测报 "The file option ... is invalid")
files:
- name: theme
label: 主题设置 label: 主题设置
file: content/site/theme.yaml file: content/site/theme.yaml
format: yaml
fields: fields:
- { label: 强调色(亮), name: accent_light, widget: color, required: false, hint: '亮色模式强调色,如 #3454d1;构建期校验正文对比度 ≥4.5' } - { label: 强调色(亮), name: accent_light, widget: color, required: false, hint: '亮色模式强调色,如 #3454d1;构建期校验正文对比度 ≥4.5' }
- { label: 强调色(暗), name: accent_dark, widget: color, required: false, hint: '暗色模式强调色,如 #8ea2ff' } - { label: 强调色(暗), name: accent_dark, widget: color, required: false, hint: '暗色模式强调色,如 #8ea2ff' }
@@ -136,6 +141,7 @@ collections:
- name: home - name: home
label: 主页设置 label: 主页设置
file: content/site/home.yaml file: content/site/home.yaml
format: yaml
# 头像上传落 content/site/assets/,yaml 写 ./assets/xxx(Astro 图片管线优化) # 头像上传落 content/site/assets/,yaml 写 ./assets/xxx(Astro 图片管线优化)
media_folder: content/site/assets media_folder: content/site/assets
public_folder: ./assets public_folder: ./assets
@@ -244,6 +250,7 @@ collections:
- name: about - name: about
label: 关于页 label: 关于页
file: content/site/about.yaml file: content/site/about.yaml
format: yaml
# 块内图片上传落 content/site/assets/,yaml 写 ./assets/xxx(Astro 图片管线) # 块内图片上传落 content/site/assets/,yaml 写 ./assets/xxx(Astro 图片管线)
media_folder: content/site/assets media_folder: content/site/assets
public_folder: ./assets public_folder: ./assets
@@ -521,6 +528,7 @@ collections:
- name: opensource - name: opensource
label: 开源页 label: 开源页
file: content/site/opensource.yaml file: content/site/opensource.yaml
format: yaml
fields: fields:
- label: 叙述(链接前) - label: 叙述(链接前)
name: blurb name: blurb
+21
View File
@@ -69,6 +69,27 @@ def main() -> int:
print(f'[config-check] FAIL {rel}\n {first}') print(f'[config-check] FAIL {rel}\n {first}')
admin = loaded.get('public/admin/config.yml') admin = loaded.get('public/admin/config.yml')
if admin:
# 结构断言(2026-11-02 教训):每个集合必须二选一——folder 集合或
# files 文件集合;files 项必须齐 file/label/fields,且 file 指向真实文件。
# 把 file 直接写在集合层级会被 Sveltia 判非法(后台整体报错)。
for coll in admin.get('collections', []):
name = coll.get('name', '<unnamed>')
has_folder, has_files = 'folder' in coll, 'files' in coll
if not has_folder and not has_files:
failed += 1
print(f'[config-check] FAIL 集合 {name}: 既无 folder 也无 files(Sveltia 会拒绝加载)')
if has_files:
for entry in coll.get('files') or []:
miss = [k for k in ('file', 'label', 'fields') if k not in entry]
if miss:
failed += 1
print(f'[config-check] FAIL 集合 {name} 的文件项缺 {miss}')
continue
if not (root / entry['file']).exists():
failed += 1
print(f"[config-check] FAIL 集合 {name}: 文件不存在 {entry['file']}")
if admin: if admin:
fields = hints = 0 fields = hints = 0