企业 Knowledge 开发

Odoo 企业版 Knowledge 模板为什么不是“复制一篇文章”而已:子文章自动创建、ref 重绑定与属性继承链路讲透

Knowledge 模板实例化真正复杂的部分,是整棵模板树生成、嵌入引用重绑到新文章,以及属性、stage、封面等内容在复制时的分层继承。

Odoo 开发 企业
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

Knowledge 的模板系统如果只看界面,很像“用一篇标准文章复制出一篇新文章”。但 knowledge_article.py 里的实现告诉你,它实际上是在做一次模板树实例化,不是单记录复制。

主要参考:

  • enterprise/knowledge/models/knowledge_article.py

一、模板展开的起点不是 body,而是模板树

源码会先从根模板开始,把 (template, article) 成对压栈,递归展开所有需要自动创建的子模板。这里最关键的判断是 template_child_default_create:并不是每个子模板都无脑复制,只有符合“默认随父模板创建”的节点,才会一起实例化。

这就解释了为什么 Knowledge 模板能做出“套件化文档”:一个母模板下面带任务清单、阶段项、记录索引、子页面,但真正创建文章时可以只生成默认需要的那部分。

二、stage 和 child article 是成套复制的,不只是文本内容

官方实现先建 stage,再建 child article,最后才回填正文。这个顺序很重要,因为 child article 在创建时可能要对齐父模板上的 stage 归属。

也就是说,Knowledge 模板复制的不只是“长得像”的页面,而是一套内容结构。结构先落地,正文后渲染,这比单纯 copy 更稳。

三、最容易被忽略的高级点:ref() 会被重绑到新文章

模板正文里的嵌入视图、文章链接、article index,并不会继续指向原模板自身。源码在 _prepare_template / _render_template 里会把 ref('module.xml_id') 解析后,重绑到本次新建出来的文章 ID。

这一步非常关键。否则模板 A 复制出文章 A1,A1 内部的链接还会跳回原模板,而不是跳到 A1 的子文章。官方通过构建 template_xml_id -> article_id 映射,解决了这个问题。

四、属性继承不是“复制所有字段”,而是有明确分层

实例化时,以下内容会被成批拷贝或回填:

  • article_properties / article_properties_definition
  • cover_image_id
  • full_width
  • icon
  • origin_template_id
  • 渲染后的 body

这说明模板和文章的关系并不是一次性脱钩。origin_template_id 明确保留了“我是从哪个模板生成的”这层血缘关系,后续统计、筛选、按模板追溯都依赖它。

五、容易误解的地方:模板 preview 和实例 body 不是同一个概念

template_preview 看起来也在渲染模板,但它只是用于模板预览。真正创建文章时,会带上目标文章 ID、模板映射关系等上下文重新跑一遍渲染。

所以开发里不要偷懒把 preview 当正式 body。你少了 target article 上下文后,引用、索引、嵌入块都可能不对。

六、实战建议

Knowledge 模板相关二开,最推荐遵守三条:

  • 先处理模板树和结构,再处理正文 HTML
  • 不要跳过 ref() 重绑定逻辑
  • origin_template_id 当成追踪与演进的重要字段保留

Knowledge 模板之所以好用,不是因为它“复制得快”,而是因为它把结构、引用、属性和内容一起安全地迁移到了新文章上。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。