
Halo 主题如何实现页面布局契约 templates/layout.html 复用主题外壳【免费下载链接】haloHalo 是一款强大易用的开源建站工具从个人博客、知识库到企业官网、在线商城Halo 都能助您轻松实现一站式满足您的多样化建站需求。项目地址: https://gitcode.com/GitHub_Trending/ha/halo如果你的主题是插件页面渲染时的“外壳”而插件页面或任何非主题原生模板渲染的前台页面又需要复用这个外壳Halo 提供了页面布局契约主题在根模板目录提供templates/layout.html并声明html(head, content)片段插件模板通过layout :: html(...)调用它。主题没有提供或提供异常时Halo 会回退到系统内置的 fallback 布局主题仍可正常安装、升级、启用和渲染——契约是增量能力不会让不兼容的主题进入失败状态。v1 契约只包含 head 和 content 两个片段v1 契约的完整定义就一条templates/layout.html中必须有一个html片段接受head和content两个片段参数。head插入到文档的head中content插入到body中。外层容器、页头、页脚、暗黑模式、响应式布局等实现细节由主题自行决定。当前 v1 只有这两个插槽后续如果要新增插槽Halo 优先考虑新片段名或新契约版本避免已适配的主题因为新增必填参数而渲染失败。Halo 内置的 fallback 布局是 application/src/main/resources/templates/layout.html它对head做了空值保护并在body中保留halo:footer /注入点!DOCTYPE html html xmlns:thhttps://www.thymeleaf.org th:lang${#locale.toLanguageTag} th:fragmenthtml (head, content) head meta charsetUTF-8 / meta http-equivX-UA-Compatible contentIEedge / meta nameviewport contentwidthdevice-width, initial-scale1.0 / th:block th:if${head ! null} th:block th:replace${head} / /th:block /head body th:block th:replace${content} / halo:footer / /body /html这个 fallback 是有意做得极简的它保证契约页面在任何主题下都能渲染出合法的html/head/body结构但不追求与主题视觉一致。即使页面没有传head片段fallback 布局也会正常渲染不会报错。主题侧提供 templates/layout.html在主题的根模板目录注意是templates/layout.html不是templates/modules/layout.html添加契约布局。官方示例文档标注为契约参考写法modules/header、modules/footer是主题内部模板可替换为主题自己的模块!doctype html html xmlns:thhttps://www.thymeleaf.org th:lang${#locale.toLanguageTag} th:fragmenthtml (head, content) head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / th:block th:replace${head} / /head body th:block th:replace~{modules/header} / th:block th:replace${content} / th:block th:replace~{modules/footer} / halo:footer / /body /html关键约束只有一个html片段的签名必须是html (head, content)。Halo 在主题 reconciliation 时做的是静态签名校验不做预渲染——校验只看模板是否声明了 v1 契约要求的片段签名。这也是为什么“文件存在”不等于“支持契约”对一批现有主题的调研显示已有主题中提供的templates/layout.html的片段签名并不统一所以兼容性必须由签名校验得出而不是由文件存在性得出。插件侧用 layout :: html(...) 调用主题外壳插件自己的前台模板通过下面模式把页面交给主题或 fallback布局渲染!doctype html html xmlns:thhttps://www.thymeleaf.org th:replace~{layout :: html(head ~{::head}, content ~{::content})} th:block th:fragmenthead title插件页面标题/title /th:block th:block th:fragmentcontent main插件页面正文/main /th:block /html解析规则是这条链路的核心当调用方模板是插件拥有的plugin-owned且请求的模板名为layout时Halo 按契约解析优先使用当前激活主题的、通过校验的templates/layout.html激活主题没有提供兼容布局时回退到系统 fallback 布局插件包内即使存在自己的templates/layout.html也不会被用来满足这个契约——layout是 Halo 保留的集成模板名。插件内部私有布局请换一个模板名。这个特殊解析只作用于插件模板请求layout这一种情况插件相对模板解析的其他行为保持不变。没有引用layout :: html(...)的既有插件页面渲染行为与之前完全一致。如何验证契约是否生效主题安装、更新或重载后Halo 会检查templates/layout.html并在Theme.status.pageLayout中记录状态对应字段定义见 api/src/main/java/run/halo/app/core/extension/Theme.javaSUPPORTED主题提供了符合html(head, content)契约的布局MISSING主题未提供templates/layout.html使用布局契约的页面将走 Halo 的 fallback 布局INVALID主题提供了templates/layout.html但签名不符合 v1 契约状态中会附带简短的诊断原因reason/message字段。两种状态都不会让Theme.status.phase变为失败。Console 的主题管理界面会展示这些状态对应实现见 ui/console-src/modules/interface/themes/ThemeDetail.vueSUPPORTED指示页面布局集成受支持MISSING警告使用布局契约的页面将使用 Halo 的 fallback 布局可能和主题视觉不一致INVALID警告主题布局契约未通过校验并在可用时展示诊断原因。所以核对流程是主题安装/更新/重载后打开 Console 主题管理页查看布局兼容状态或检查 Theme 资源status.pageLayout的state与诊断字段前台访问插件页面观察页面是被主题外壳包裹支持契约的主题还是只有极简结构走了 fallback。边界与限制契约检查是静态签名校验只表示契约可用性不是完整的主题渲染健康检查布局被标记为SUPPORTED后如果模板里某个无关运行时表达式出错仍可能在渲染时失败。fallback 布局只保证可渲染不保证与主题视觉一致MISSING状态下的插件页面看起来可能“不像这个主题”这是预期行为。本契约不要求所有主题先提供支持才能安装、升级、激活或渲染也不迁移主题现有的modules/layout.html、common/layout.html等内部布局文件。v1 只有head和content两个插槽需要脚本时放在head或content中即可不要等待未发布的插槽。参考docs/developer-guide/page-layout.md主题与插件两侧的契约写法openspec/specs/page-layout-contract/spec.md解析规则、状态机与 Console 展示要求application/src/main/resources/templates/layout.html系统 fallback 布局api/src/main/java/run/halo/app/core/extension/Theme.javaTheme.status.pageLayout字段与PageLayoutState定义【免费下载链接】haloHalo 是一款强大易用的开源建站工具从个人博客、知识库到企业官网、在线商城Halo 都能助您轻松实现一站式满足您的多样化建站需求。项目地址: https://gitcode.com/GitHub_Trending/ha/halo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考