13 October 2026, 22:07 (GMT+8)
2026年10月13日 22:07(东八区 / 北京时间)
看板命名与 URL 唯一化:多天 / 全天 / 上午 / 下午 / 晚上 五类各自独立可达 · 修复 path collisions
概述
本轮处理新建看板后构建直接失败的问题,并一次把它根治:
- 报错:新建 2026-10-13 晚上看板后,构建报
Found path collisions,两块不同日期的看板抢同一条 URL; - 根因:Zola 会把文件名开头的
YYYY-MM-DD当成页面日期剥离,只剩「晚上」参与 slug,于是2026-08-11_晚上.md与2026-10-13_晚上.md都会变成/kanban/wan-shang/;编辑器此前只保证文件名唯一,没管 URL 唯一; - 修复(URL):每块看板都由编辑器自动写入
slug(= URL 安全化的文件名),让五类看板各有唯一可达的 URL; - 修复(命名与锁定):多天看板改用
周开始-周结束-打开编辑器时的时分命名(如2026-06-16-06-22-2236.md),从文件名上就和单日「全天」区分开;同时收紧编辑锁定 —— 单日看板的周开始、周结束都锁定,多天看板只锁定周开始;新建时还会提示「该时间段已有看板」; - 收尾:把 2026-06/07 创建的 4 块多天看板也统一迁移到新命名,并用
aliases保住旧 URL。
一、报错现象
在 GUI 里新建单日看板,按提示在仓库里创建文件、粘贴生成的 Markdown 并保存后,本地 zola serve 与 zola build 同时失败:
ERROR Failed to build the site
ERROR Found path collisions:
- `/kanban/wan-shang/` from files
{content/kanban/2026-08-11_晚上.md, content/kanban/2026-10-13_晚上.md}粘贴的 Markdown 本身没有语法问题:front matter 合法、栏目与卡片规则也正确。问题出在文件名 → URL 这一层。
二、根因:文件名的日期段被剥离成页面日期
Zola 会把页面文件名开头的 YYYY-MM-DD 当作页面日期,并从 slug 里去掉,只让剩下的部分参与 URL:
| 文件 | 生成的 URL |
|---|---|
2026-06-16.md | /kanban/2026-06-16/ |
2026-08-11_晚上.md | /kanban/wan-shang/ ← 只剩「晚上」被转写成拼音 |
2026-10-13_晚上.md | /kanban/wan-shang/ ← 与上一行撞车 |
结论:只要两块单日看板的时段相同(上午 / 下午 / 晚上),无论日期差多远,都会落到同一条输出路径。命名规则 week_start_时段 只保证了文件名唯一,而 Zola 恰好把日期前缀吃掉了。
复现方式:在最小 Zola 工程里放两个不同日期、同一时段的文件,得到一字不差的同一条报错;给其中一块补上 slug 后立刻构建通过。
三、修复方案
3.1 编辑器自动写入 slug
static/js/kanban-editor.js:新增时段拼音映射与buildUrlSlug():- 上午 →
shang-wu、下午 →xia-wu、晚上 →wan-shang; stateToBoard()把slug = URL 安全化的文件名写进 front matter(五类看板都写,不再依赖 Zola 从文件名推导)。
- 上午 →
static/js/kanban-rules.js:serializeMarkdown()在date之后输出slug行;解析器本来就能读任意顶层键,所以用 GUI 修改已有看板时也不会把slug弄丢。
3.2 文件名与 URL 方案
| 看板类型 | 文件名 | 生成的 URL |
|---|---|---|
| 多天(跨天周计划) | 2026-06-16-06-22-2236.md(周开始 - 周结束的月-日 - 打开编辑器时的时分) | /kanban/2026-06-16-06-22-2236/ |
| 单日「全天」(不选时段) | 2026-10-13.md | /kanban/2026-10-13/ |
| 单日 上午 | 2026-10-13_上午.md | /kanban/2026-10-13-shang-wu/ |
| 单日 下午 | 2026-10-13_下午.md | /kanban/2026-10-13-xia-wu/ |
| 单日 晚上 | 2026-10-13_晚上.md | /kanban/2026-10-13-wan-shang/ |
- 文件名同时就是「生成并复制到剪贴板 / 同步到仓库」提示的目标文件名;多天看板的时分取自打开 GUI 编辑器的那一刻,编辑过程中不再变化;
- 修改已有看板时沿用原文件名、并保留已有
slug,所以改内容不会改 URL。
3.3 编辑锁定规则
| 看板类型 | 周开始 | 周结束 | 时段 |
|---|---|---|---|
| 单日(含「全天」) | 锁定 | 锁定(起止同一天) | 锁定 |
| 多天(跨天) | 锁定 | 可改(开始 +13 天以内) | 不适用 |
3.4 现有文件与文档
出问题的
content/kanban/2026-10-13_晚上.md补上slug = "2026-10-13-wan-shang",构建立刻恢复;旧的
2026-08-11_晚上.md保持原样,URL 仍是/kanban/wan-shang/,不影响既有链接;2026-06/07 创建的 4 块多天看板已统一迁移到新命名,并同时写入
slug(新 URL)与aliases(旧 URL):旧文件名 新文件名 新 URL 旧 URL(redirect) 2026-06-16.md2026-06-16-06-22-0934.md/kanban/2026-06-16-06-22-0934//kanban/2026-06-16/2026-06-22.md2026-06-22-06-23-0934.md/kanban/2026-06-22-06-23-0934//kanban/2026-06-22/2026-06-25.md2026-06-25-06-30-1316.md/kanban/2026-06-25-06-30-1316//kanban/2026-06-25/2026-07-13.md2026-07-13-07-19-1800.md/kanban/2026-07-13-07-19-1800//kanban/2026-07-13/(迁移用的时分取自各文件原本的最后修改时间;旧 URL 会 301/跳转到新 URL,历史 nanolog 里指向
/kanban/2026-06-16/的链接依旧可用。)content/kanban/kanban-mapping.md补上命名规则、URL 对照表、编辑锁定规则、带slug的 front matter 示例与字段说明;scripts/verify-kanban-build.mjs同步按新规则推导输出目录(多天 / 全天 / 时段三种命名都能校验)。
3.5 新建时的重复看板提示
- 编辑器会读取列表页内嵌的看板清单(热力图容器的
data-json),在新建时判断所选时间段是否与已有看板重叠; - 完全相同 → 提示「该时间段已有看板:<核心任务>(起 ~ 止),建议点它的「✎ 编辑」修改」;部分重叠 → 提示会并存两块重叠看板;
- 修改已有看板时不显示该提示。
3.6 让 aliases 在 GUI 修改后仍然保留
kanban-rules.js:parseFrontMatter()识别顶层aliases = ["…"],serializeMarkdown()在slug之后重新输出aliases;kanban-editor.js:boardToState()读入 aliases、stateToBoard()写回;- 这样用 GUI 编辑迁移后的看板再保存,旧 URL 的跳转不会丢。
四、验证
- 逻辑 + 端到端:直接加载真实的规则引擎、并从编辑器源码里抽取真实的
buildSlug()/buildUrlSlug()跑用例(新建五类 + 修改三类 + 同一天「多天 vs 全天」互不冲突),再把生成的 Markdown 放进一个最小 Zola 工程构建 —— 五类看板的 URL 各自唯一,无冲突; - 重复提示:用真实的看板清单数据跑冲突判定 —— 完全相同 / 部分重叠 / 不重叠 / 修改模式四种情况结果正确;
- front matter 回写:解析后再序列化,
slug与aliases都能原样保留; - 真站构建:
zola build通过(285 个页面 = 原有页面 + 4 个旧 URL 跳转页),scripts/verify-kanban-build.mjs通过(6 块看板,列表卡片与周页一一对应); - 页面可达:新看板详情页
/kanban/2026-10-13-wan-shang/、迁移后的 4 个新 URL 全部生成;4 个旧 URL 均生成跳转页(如/kanban/2026-06-16/→/kanban/2026-06-16-06-22-0934/);旧看板/kanban/wan-shang/不受影响。
五、注意事项
- 新命名生效后,多天、全天、上午、下午、晚上五类看板可以在同一天共存,URL 各自唯一;4 块历史多天看板已迁移到新命名并通过
aliases保住旧链接,只有更早的2026-08-11_晚上.md还保留着「URL 只剩余下时段」的历史形态; - 旧的 2026-08-11 晚上看板如果日后用 GUI 编辑并保存,会自动获得
slug = "2026-08-11-wan-shang",其 URL 会从/kanban/wan-shang/变为/kanban/2026-08-11-wan-shang/(如需保住旧链接,可再加aliases); - 新建看板若与已有看板时间段重叠,编辑面板会给出提示,避免无意间建出两块同周看板;
- 顺带调整:
/kanban/热力图的月份选择器改为默认当前月份;若当月还没有看板,卡片列表会自动回退展示最近一个有看板的月份并给出提示,避免整屏空白。
相关链接:周计划看板 · 映射说明 · Ametrine 主题
26 September 2026, 16:30 (GMT+8)