兼容 fallback 会让内容重复渲染
机制
- 新路径:
section.body直接取块状富文本(skills→content.skills,summary/awards/portfolio→ 对应顶层字段)。 - 旧路径:旧模板只有
section.items,为了让块状模块也能显示,deriveItems把同一份富文本包成一个「假 item」塞进item.bullets。
新模板同时写了 <slot data-bind="section.body"> 和 <slot data-bind="section.items" data-template="item">,两条路径各渲染一次 → 重复。
解法:在渲染器里记「本 section 是否已有新槽」
渲染时记录当前 section 模板是否含 section.body;若该 section 是 kind === "block" 且模板已有 section.body,就跳过 fallback 的假 item。
第二种来源:迁移脚本把「一行」替换成「一组」
模板批量迁移时,占位符被替换成「渲染全部 X」的循环,也会造成重复:旧模板本来有多行联系方式(电话 / 邮箱 / 地点 / 网站各一行),迁移时每一行都被换成 profile.contacts 循环,于是 4–5 行变成 4–5 组重复联系方式。
同一批迁移还会顺带造成另一种坏结果:把模板专属类换成通用类(.modern-contact-item → .contact-item),原 CSS 选择器不再命中,图标变大、挤成奇怪的两行 —— 「重复」和「样式丢失」可能出自同一次迁移,但根因不同,要分开定位。
判据:迁移脚本里凡是「把一个占位符替换成对集合的循环」,都要先确认原位置的语义是一行还是一组;是「一行」就不能换成循环。
可迁移的判断
- 加兼容层时,要问「新路径和旧路径会不会同时命中同一份数据」,并给新路径一个已消费标记。
- 列表模块不出问题不代表机制对 —— 只是因为它的
section.body为空,两条路径天然互斥。只在块状数据上暴露的 bug,最容易被判成「个别模板的问题」。 - 反过来也说明
section.body不能随便往存量模板上加:曾经加它导致过块状模块双渲染。
相关
- 简历模板的三层渲染协议与迁移 —— block / list 两种形态与本条同源
- 仓库残留会误导对现状的判断 —— 兼容层是「旧的东西还在运行时活着」
- 可调与固定的边界按语义划分 —— 同一天同一项目的另一处修改