页面布局契约
从 Halo 2.26.0 开始,主题可以通过 templates/layout.html 提供一个标准页面布局契约。插件提供的前台页面调用这个契约后,可以复用当前主题的页头、页脚、样式和响应式布局;如果当前主题没有适配,Halo 会使用内置的 fallback 布局保证页面可以继续渲染。
这个能力是增量适配项,不会影响主题安装、升级、启用,也不会替代主题内部自用的普通模板片段。
适配主题布局
主题需要在 templates/layout.html 中声明 html(head, content) 片段:
其中:
head:调用方提供的头部片段,通常用于插入页面标题、meta 信息或当前页面需要的资源。传入该片段时,调用方应提供最终的<title>;示例布局只在head为空时输出站点标题,避免同一页面出现两个标题。content:调用方提供的正文片段,应被插入到主题页面主体中。
主题可以自行决定外层容器、页头、页脚、暗黑模式、响应式布局等实现细节。建议保留 <halo:footer />,以便 Halo 和插件继续向页面底部注入必要内容。
如果你的主题已经使用 templates/layout.html 作为内部公共模板,只要它声明了 html(head, content) 片段,就可以同时作为页面布局契约使用。如果这只是主题内部私有模板,建议改用 templates/modules/layout.html 等其他路径,避免被识别为插件页面集成布局。
在主题页面中复用布局
主题自身的页面模板同样可以通过 layout :: html(...) 复用这个公共布局,不需要页头扩展时传 head = null:
放在 templates/modules/layout.html 等其他路径的私有布局,通过 modules/layout :: ... 引用。
插件页面调用布局
插件模板可以通过 layout :: html(...) 调用当前主题的页面布局:
layout 是 Halo 为插件前台页面保留的集成模板名。这个特殊解析只对插件自身提供的模板生效,例如通过 plugin:<plugin-name>:moment 解析出的模板。即使插件包内存在 templates/layout.html,它也不会用于满足主题的页面布局契约。
插件内部私有布局应继续使用其他模板名,并通过 plugin:<plugin-name>: 前缀显式引用。详细方式可参考在插件中提供主题模板。
兼容状态
主题安装、更新或重载后,Halo 会静态检查 templates/layout.html,并在 Theme.status.pageLayout 中记录兼容状态:
SUPPORTED:主题提供了符合html(head, content)契约的布局。MISSING:主题未提供templates/layout.html,使用布局契约的插件页面会使用 Halo 的 fallback 布局。INVALID:主题提供了templates/layout.html,但片段签名不符合当前契约。
缺失或异常不会让主题进入失败状态。Console 会在主题详情和主题列表中展示页面布局状态,帮助用户和主题开发者判断是否需要适配。
版本演进
当前 v1 契约只包含 head 和 content 两个片段参数。主题开发者不应假设调用方一定提供更多片段;插件开发者也不应依赖主题私有变量来渲染核心内容。后续如果需要新增插槽,Halo 会优先考虑新的片段名或新的契约版本,避免破坏已适配的主题。