理想情况下,在通过主题或插件自定义 Discourse 时,您应使用 CSS、JavaScript 插件 API 或 插件出口。如果这些方法都不适用于您的用例,请随时向 Discourse 核心提交 PR,或在此处的 Meta 上发起一个 Development 主题。我们非常乐意讨论添加新的出口或 API 以简化自定义工作。
如果您已穷尽所有其他选项,可能不得不采用模板覆盖技术。该技术允许您从主题或插件中覆盖任何 Ember 组件或路由的完整模板。
这不是推荐的自定义 Discourse 的方式。 Discourse 核心的日常变更 最终 会与您的模板覆盖发生冲突,可能导致论坛渲染时出现灾难性错误。
如果您决定采用这种方法,请确保您拥有足够的自动化测试和质量保证流程来检测回归问题。如果您分发了包含模板覆盖的主题或插件,请务必让论坛管理员了解该主题或插件带来的稳定性风险。
![]()
![]()
2023 年 10 月更新:对于新功能,Discourse 正越来越多地采用使用 Ember 的
.gjs文件格式编写的组件。这些组件的模板是内联定义的,无法被主题或插件覆盖。今后,所有模板自定义都应使用 插件出口 进行。
我理解这将在不久的将来失效,但仍请向我展示文档
覆盖组件模板
要覆盖 Ember 组件模板(即 Discourse 核心中 components/* 下的所有内容),您应在主题或插件中创建一个同名的 .hbs 文件。例如,要覆盖 Discourse 核心中的 badge-button 组件模板,您需要在主题或插件中的以下位置创建模板文件:
{theme}/javascripts/discourse/templates/components/badge-button.hbs
{plugin}/assets/javascripts/discourse/templates/components/badge-button.hbs
覆盖文件必须始终嵌套在 /templates 目录内,即使核心组件使用的是“共置”模板。
覆盖路由模板
覆盖路由模板(即 templates/* 下所有非组件模板)的方式与组件相同。请在主题或插件中创建一个同名的模板文件。例如,要覆盖核心中的 discovery.hbs,您可以创建如下文件:
{theme}/javascripts/discourse/templates/discovery.hbs
{plugin}/assets/javascripts/discourse/templates/discovery.hbs
多个主题/插件之间的交互
如果多个已安装的主题或插件覆盖了同一模板,则“胜出者”是以下列表中排名最低(数字最小)的一个:
- 主题覆盖(主题 ID 最大的获胜)
- 插件覆盖(按字母顺序排列的最新插件名称获胜)
- 核心
这种优先级也意味着您可以从主题中覆盖插件模板。从技术上讲,您甚至可以从其他主题覆盖主题模板,或从其他插件覆盖插件模板,但由于依赖于插件名称和主题 ID,其行为可能会令人意外。
这是如何工作的?
Discourse 在 DiscourseTemplateMap 类中组装并优先处理模板。对于共置的组件模板,该信息用于 应用初始化期间 替换核心模板关联。对于所有其他模板,该映射由 运行时的解析器 使用,以获取正确的模板。
本文档受版本控制 - 请在 GitHub 上提出修改建议。