把蝉知 CMS 整站迁到 Joomla 5:AI + 自写工具链怎么做
先说结论:CMS 迁移这件事,靠手搬一定会出事故,靠 AI 直接生成也不行。可靠的做法是写一条工具链,让每一步都有产物、能核对。
这篇文章拆解我是怎么把蝉知 CMS(ZSITE 8.x)整站迁到 Joomla 5 的。工具链已开源:github.com/zseagate/chanzhi-to-joomla(Python / MIT)。
为什么这件事难
蝉知 CMS(ZSITE 8.x)官方停止维护后,摆在面前的问题不是「能不能升级」,而是「升级这条路已经不存在了」。能选的只有换系统,而换系统意味着内容要整体迁移。
难点在三个地方:
- 内容与模板强耦合。蝉知的正文里大量内链指向站内路径,模板调用的字段和 Joomla 的模型不是一回事。直接导出导入,链接全断、样式对不上。
- 栏目结构互相咬合。蝉知允许一篇文章挂在多个栏目下,Joomla 的分类模型不同。这里处理不好,搬过去就是「栏目是空的」或者「文章重复出现」。
- 最大的风险是搬完才发现少了一块。迁移最怕的不是搬不动,而是验收的时候才发现某几个栏目的附件根本没过来。这时候回溯成本极高。
所以我的原则是:不做「一次性脚本」,做「可重复、可核对、可回滚的工具链」。
四步做法
第一步:ETL 抽取
把蝉知库里的文章、栏目、附件、标签抽成中间格式(JSON)。这一步的目的是脱离原系统——中间格式一旦生成,后续所有检查都可以脱离源库做,不反复打扰生产环境。
这一步要记录每个对象的来源主键。后面出了对不上的情况,能追溯到源。
第二步:多栏目补副本
蝉知一篇文章可以挂多个栏目,Joomla 的分类模型不支持同样的挂法。处理方式是补副本,并在映射表里记录「源文章 ID → 目标文章 ID 列表」的对应关系。
这一步最容易踩的坑是重复计数:校验的时候如果把副本当成独立文章统计,总数会虚高,看起来「都迁完了」,其实内容是重复的。映射表必须以源 ID 为准去重。
第三步:增量追平
迁移不可能一天完成,而老站还在更新。做法是设一个增量窗口:全量抽取之后,记录时间戳,迁移期间老站新增和修改的内容按时间戳追平。
这避免了「为了迁移把站停更一周」。代价是需要在某个时间点做一次短暂的停更窗口做最终追平,这个窗口要和客户提前约定。
第四步:模板 1:1 校验
写校验脚本逐页对比新旧页面:栏目数量、文章数量、附件是否都在、内链是否指向了新地址。这一步必须是脚本,不能靠肉眼翻——人眼翻一百页就会漏。
校验不通过的项会生成清单,逐条处理完再验收。
AI 用在哪,不用在哪
这是我最想说清楚的一段。AI 用于提速,不用在决策。
AI 擅长的部分
- 读老库表结构:把几十张表的字段含义整理成文档,人工要一两天,AI 加速明显。
- 生成字段映射初稿:源字段到目标字段的对应关系,AI 给初稿,人来审。审这一步比写快得多。
- 写批量校验脚本:描述清楚校验规则,AI 生成脚本骨架,人补边界条件。
- 翻译报错:迁移中最耗时的往往是「读一长串报错」。AI 把报错翻译成人话,人再决定改什么。
AI 不能替代的部分
- 迁移顺序:先迁什么后迁什么、哪个环节可以并行,取决于业务约束,AI 不知道。
- 回滚点:在哪一步设置回滚点、回滚点怎么验证,这是责任问题,不能交给模型。
- 哪些内容允许丢:有些内容客户自己都不确定要不要,这种决定必须人来拍板、写进清单。
一句话总结:AI 把「写脚本、读文档、看报错」的时间压缩了,但「决定怎么做、错了怎么办」依然是人的事。
边界与风险
- 动库前全量备份。没有备份的迁移我不会开工。这一条没有商量余地。
- 模板差异过大不承诺 1:1。如果老站模板是高度定制的手写模板,1:1 校验的标准要先谈清楚,而不是做完再说。
- 增量追平需要配合。最终追平需要在老站停更的窗口内做,这个窗口需要客户配合,提前约定。
- 不同 CMS 之间不可直接套用。这套工具链针对蝉知 → Joomla 写的,思路可以复用,脚本不能照搬到别的 CMS。
如果你也面对一个停更的老 CMS:先别急着选新系统,先把老站的内容量、栏目结构、附件数量、模板定制程度摸清楚。这四项决定迁移的工作量,也决定要不要自己做。摸不清的话,把后台截图发我,我先帮你判断工作量,诊断不收费。