diff --git a/public/admin/config.yml b/public/admin/config.yml index 19ed8c1..ccaabfa 100644 --- a/public/admin/config.yml +++ b/public/admin/config.yml @@ -61,28 +61,33 @@ collections: # 主题旋钮(样式即数据 · 层 4):只放白名单内的 9 组,越界值会被构建期钳制 - name: site_theme label: 主题设置 - file: content/site/theme.yaml - fields: - - { label: 强调色(亮), name: accent_light, widget: color, required: false, hint: '亮色模式强调色,如 #3454d1;构建期校验正文对比度 ≥4.5' } - - { label: 强调色(暗), name: accent_dark, widget: color, required: false, hint: '暗色模式强调色,如 #8ea2ff' } - - { label: 图片圆角, name: radius_img, widget: number, required: false, value_type: int, min: 4, max: 16, hint: '范围 4–16(建议 ≤14)' } - - { label: 一级标题字号, name: text_h1, widget: number, required: false, value_type: int, min: 22, max: 32, hint: '22–32,且必须大于 h2' } - - { label: 二级标题字号, name: text_h2, widget: number, required: false, value_type: int, min: 22, max: 32, hint: '22–32,必须小于 h1、大于 h3' } - - { label: 三级标题字号, name: text_h3, widget: number, required: false, value_type: int, min: 16, max: 32, hint: '16–32,必须小于 h2' } - - { label: 书评正文字号, name: prose_size_reading, widget: number, required: false, value_type: int, min: 16, max: 22, hint: '16–22' } - - { label: 技术文正文字号, name: prose_size_tech, widget: number, required: false, value_type: int, min: 16, max: 22, hint: '16–22' } - - { label: 书评行高, name: leading_reading, widget: number, required: false, value_type: float, min: 1.5, max: 2.0, step: 0.05, hint: '1.5–2.0' } - - { label: 技术文行高, name: leading_tech, widget: number, required: false, value_type: float, min: 1.5, max: 2.0, step: 0.05, hint: '1.5–2.0' } - - { label: 间距 3, name: space_3, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 < 间距 4' } - - { label: 间距 4, name: space_4, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 > 间距 3 且 < 间距 5' } - - { label: 间距 5, name: space_5, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 > 间距 4 且 < 间距 6' } - - { label: 间距 6, name: space_6, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 > 间距 5' } - - { label: 段间距, name: flow_p, widget: number, required: false, value_type: float, min: 0, max: 2, step: 0.05, hint: '0–2(em)' } - - { label: 标题下间距, name: flow_h2_post, widget: number, required: false, value_type: float, min: 0, max: 2, step: 0.05, hint: '0–2(em)' } - - { label: 过渡时长, name: dur, widget: number, required: false, value_type: int, min: 150, max: 600, hint: '150–600(毫秒)' } + # 文件集合必须是 files: [{file,label,fields}] 结构;把 file 直接写在集合层级会被 Sveltia 判非法(2026-11-02 实测报 "The file option ... is invalid") + files: + - name: theme + label: 主题设置 + file: content/site/theme.yaml + format: yaml + fields: + - { label: 强调色(亮), name: accent_light, widget: color, required: false, hint: '亮色模式强调色,如 #3454d1;构建期校验正文对比度 ≥4.5' } + - { label: 强调色(暗), name: accent_dark, widget: color, required: false, hint: '暗色模式强调色,如 #8ea2ff' } + - { label: 图片圆角, name: radius_img, widget: number, required: false, value_type: int, min: 4, max: 16, hint: '范围 4–16(建议 ≤14)' } + - { label: 一级标题字号, name: text_h1, widget: number, required: false, value_type: int, min: 22, max: 32, hint: '22–32,且必须大于 h2' } + - { label: 二级标题字号, name: text_h2, widget: number, required: false, value_type: int, min: 22, max: 32, hint: '22–32,必须小于 h1、大于 h3' } + - { label: 三级标题字号, name: text_h3, widget: number, required: false, value_type: int, min: 16, max: 32, hint: '16–32,必须小于 h2' } + - { label: 书评正文字号, name: prose_size_reading, widget: number, required: false, value_type: int, min: 16, max: 22, hint: '16–22' } + - { label: 技术文正文字号, name: prose_size_tech, widget: number, required: false, value_type: int, min: 16, max: 22, hint: '16–22' } + - { label: 书评行高, name: leading_reading, widget: number, required: false, value_type: float, min: 1.5, max: 2.0, step: 0.05, hint: '1.5–2.0' } + - { label: 技术文行高, name: leading_tech, widget: number, required: false, value_type: float, min: 1.5, max: 2.0, step: 0.05, hint: '1.5–2.0' } + - { label: 间距 3, name: space_3, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 < 间距 4' } + - { label: 间距 4, name: space_4, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 > 间距 3 且 < 间距 5' } + - { label: 间距 5, name: space_5, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 > 间距 4 且 < 间距 6' } + - { label: 间距 6, name: space_6, widget: number, required: false, value_type: int, min: 8, max: 80, hint: '8–80,必须 > 间距 5' } + - { label: 段间距, name: flow_p, widget: number, required: false, value_type: float, min: 0, max: 2, step: 0.05, hint: '0–2(em)' } + - { label: 标题下间距, name: flow_h2_post, widget: number, required: false, value_type: float, min: 0, max: 2, step: 0.05, hint: '0–2(em)' } + - { label: 过渡时长, name: dur, widget: number, required: false, value_type: int, min: 150, max: 600, hint: '150–600(毫秒)' } - # 瞬间:随手发(text/image 至少其一——Sveltia 无法表达条件必填,两者都设可选, - # 保存前自查;pubDate 必填)。图片走图库媒体库(content/photos 同源可复用) + # 瞬间:随手发(text/image 至少其一——Sveltia 无法表达条件必填,两者都设可选, + # 保存前自查;pubDate 必填)。图片走图库媒体库(content/photos 同源可复用) - name: moments label: 瞬间 folder: content/moments @@ -136,6 +141,7 @@ collections: - name: home label: 主页设置 file: content/site/home.yaml + format: yaml # 头像上传落 content/site/assets/,yaml 写 ./assets/xxx(Astro 图片管线优化) media_folder: content/site/assets public_folder: ./assets @@ -244,6 +250,7 @@ collections: - name: about label: 关于页 file: content/site/about.yaml + format: yaml # 块内图片上传落 content/site/assets/,yaml 写 ./assets/xxx(Astro 图片管线) media_folder: content/site/assets public_folder: ./assets @@ -521,6 +528,7 @@ collections: - name: opensource label: 开源页 file: content/site/opensource.yaml + format: yaml fields: - label: 叙述(链接前) name: blurb diff --git a/scripts/build-perf/config-check.py b/scripts/build-perf/config-check.py index 7213af6..7eb310c 100755 --- a/scripts/build-perf/config-check.py +++ b/scripts/build-perf/config-check.py @@ -69,6 +69,27 @@ def main() -> int: print(f'[config-check] FAIL {rel}\n {first}') 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', '') + 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: fields = hints = 0