先说结论
在 Odoo 里,项目任务内部链接的预览卡片,默认就不是“只把任务 name 原样吐出来”。
/home/ubuntu/odoo-temp/addons/project/models/project_task.py 明确给 project.task 维护了一个 link_preview_name 计算字段:
- 先取
task.display_name - 如果任务属于某个项目,再拼上
| project_name
也就是说,系统天然倾向于把任务链接预览做成:
任务名 + 项目上下文
而不是“一个没有上下文的裸标题”。
再看测试 addons/project/tests/test_task_link_preview_name.py,你会发现官方不仅验证了:
/odoo/all-tasks/<id>这种路径能回到预览元数据/odoo/my-tasks/<id>这种路径也能回到预览元数据
还显式断言响应中包含 link_preview_name。
所以正确理解应该是:Odoo 内部链接预览是“记录元数据服务”,任务标题只是它的一部分。
1. 为什么 Odoo 单独做了 link_preview_name
如果只是把内部链接展示成记录名称,理论上直接回 display_name 就够了。
但项目任务有个很实际的问题:
- 任务名很容易重名
- 不同项目里经常都有“开发”“联调”“上线检查”这类标题
- 在富文本评论、邮件、知识库里,脱离项目上下文后几乎不可读
因此 _compute_link_preview_name() 采取的策略非常务实:
- 以
display_name为基础 - 若存在
project_id,再追加项目名
这会带来一个很实际的效果:
- 在聊天、富文本、文档里的链接预览,不需要用户点进去,也能先知道“这是哪个项目下的哪张任务卡”
这不是 UI 花活,而是典型的信息去歧义设计。
2. 为什么测试要同时覆盖 all-tasks 和 my-tasks
很多人会以为内部链接预览只认一种固定路由,但测试恰恰不是这样写的。
它分别请求:
/html_editor/link_preview_internal+preview_url=/odoo/all-tasks/<task_id>/html_editor/link_preview_internal+preview_url=/odoo/my-tasks/<task_id>
两次都要求:
- HTTP 200
- 响应文本中包含
link_preview_name
这说明 Odoo 在设计内部链接预览时,考虑的不是“某一张菜单里复制出来的 URL”,而是:
只要是合法的项目任务内部入口,富文本预览服务都应该能识别并返回统一元数据。
这对前端一致性非常重要,因为同一条任务记录可能从不同入口被复制出来:
- 全部任务视图
- 我的任务视图
- 项目任务菜单
如果预览服务不能兼容这些路径,用户会觉得系统“一会儿有卡片、一会儿没卡片”。
3. 为什么这里的关键不是 URL,而是“URL 能否映射回记录元数据”
/html_editor/link_preview_internal 的存在,本质上说明 Odoo 把富文本预览设计成了一个独立服务层:
- 前端提交某个内部 URL
- 服务端解析它对应的记录
- 返回可供编辑器渲染的内部预览元数据
对项目任务来说,link_preview_name 就是这层元数据里最关键的一项之一。
因此不要把它理解成“编辑器把标题抄一遍”。 真正发生的是:
- 前端传 URL
- 后端识别 URL 属于哪种内部路径
- 后端拿到对应任务
- 再按任务模型的预览命名规则生成预览字段
这也是为什么测试断言的是响应里是否存在 link_preview_name,而不是简单断言页面标题。
4. 实施上为什么这件事值得重视
项目型组织很容易在这些地方大量使用内部链接:
- chatter 讨论
- knowledge 文档
- wiki 操作手册
- 内部周报
- 需求澄清记录
如果链接预览只显示一个模糊标题,就会出现两个问题:
问题一:同名任务难以分辨
“测试”“Review”“Fix bug” 这种标题在不同项目里太常见了。
问题二:上下文丢失后,知识沉淀质量会下降
一段文档里放十个任务链接,如果每个卡片都不带项目名,后续阅读者只能反复点开确认。
所以 link_preview_name = display_name + project_name 其实是在给知识沉淀做基础设施。
5. 二开时最容易犯的错
错一:只改前端模板,不改模型预览字段
这样你可能能让某个页面看起来正常,但换一个内部 URL 路径或换一个编辑器入口,元数据仍然不一致。
错二:把预览名硬写成 task name
一旦项目上下文丢掉,跨项目协作的可读性会明显下降。
错三:只测试一个 URL 路由
官方测试已经告诉你:至少 all-tasks 和 my-tasks 都要覆盖。你自己定制了别的任务入口,也最好同步补测试。
一句落地建议
如果你在做 Odoo 项目知识库、评论协作或内部文档增强,不要把任务链接预览当成小功能。它其实承担的是:
- 任务去歧义
- 项目上下文补充
- 多入口 URL 的一致预览
这三件事做好了,团队长期使用 Odoo 的知识可读性会明显更好。
参考源码
/home/ubuntu/odoo-temp/addons/project/models/project_task.pylink_preview_name_compute_link_preview_name()/home/ubuntu/odoo-temp/addons/project/tests/test_task_link_preview_name.pytest_01_task_link_preview_name()test_my_tasks_path()/html_editor/link_preview_internal/odoo/all-tasks/<id>/odoo/my-tasks/<id>
DISCUSSION
评论区