halo-theme-dev
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHalo Theme Development
Halo主题开发
Halo is built on Spring Boot + Spring WebFlux + Thymeleaf. Themes use Thymeleaf templates for frontend page rendering.
Halo 基于Spring Boot + Spring WebFlux + Thymeleaf构建。主题使用Thymeleaf模板进行前端页面渲染。
Thymeleaf Quick Reference
Thymeleaf快速参考
Core syntax cheatsheet:
html
<!-- Output text -->
<h1 th:text="${site.title}"></h1>
<!-- Output unescaped HTML -->
<div th:utext="${post.content.content}"></div>
<!-- Links -->
<a th:href="@{${post.status.permalink}}">Post link</a>
<link rel="stylesheet" th:href="@{/assets/dist/style.css}" />
<!-- Loop -->
<li th:each="post : ${posts.items}" th:text="${post.spec.title}"></li>
<!-- Conditionals -->
<div th:if="${posts.hasNext()}">Next page</div>
<div th:unless="${posts.hasNext()}">Last page</div>
<!-- Local variable -->
<div th:with="menu = ${menuFinder.getPrimary()}">...</div>
<!-- Fragment include -->
<div th:replace="~{fragments/header :: header}"></div>
<!-- Layout reuse: layout.html declares a parameterized fragment; pages pass head/content via th:replace -->
<!-- templates/layout.html -->
<html th:fragment="html (head, content)">
<head>
<th:block th:if="${head != null}" th:replace="${head}" />
</head>
<body>
<th:block th:replace="${content}" />
</body>
</html>
<!-- templates/index.html -->
<html th:replace="~{layout :: html(head = null, content = ~{::content})}">
<th:block th:fragment="content"><!-- page body --></th:block>
</html>
<!-- Inline JavaScript -->
<script th:inline="javascript">
var url = '[(${#theme.assets("/dist/main.iife.js")})]';
</script>核心语法速查表:
html
<!-- Output text -->
<h1 th:text="${site.title}"></h1>
<!-- Output unescaped HTML -->
<div th:utext="${post.content.content}"></div>
<!-- Links -->
<a th:href="@{${post.status.permalink}}">Post link</a>
<link rel="stylesheet" th:href="@{/assets/dist/style.css}" />
<!-- Loop -->
<li th:each="post : ${posts.items}" th:text="${post.spec.title}"></li>
<!-- Conditionals -->
<div th:if="${posts.hasNext()}">Next page</div>
<div th:unless="${posts.hasNext()}">Last page</div>
<!-- Local variable -->
<div th:with="menu = ${menuFinder.getPrimary()}">...</div>
<!-- Fragment include -->
<div th:replace="~{fragments/header :: header}"></div>
<!-- Layout reuse: layout.html declares a parameterized fragment; pages pass head/content via th:replace -->
<!-- templates/layout.html -->
<html th:fragment="html (head, content)">
<head>
<th:block th:if="${head != null}" th:replace="${head}" />
</head>
<body>
<th:block th:replace="${content}" />
</body>
</html>
<!-- templates/index.html -->
<html th:replace="~{layout :: html(head = null, content = ~{::content})}">
<th:block th:fragment="content"><!-- page body --></th:block>
</html>
<!-- Inline JavaScript -->
<script th:inline="javascript">
var url = '[(${#theme.assets("/dist/main.iife.js")})]';
</script>Development Workflow
开发工作流
- Create a theme folder under in the Halo working directory (must match
themes/inmetadata.name)theme.yaml - Write (required) and
theme.yaml(optional)settings.yaml - Create template files under
templates/ - Install and activate the theme in Console → Theme Management
- Visit the frontend to verify
Disable Thymeleaf caching during development: set env var (Docker), or in config (source mode).
SPRING_THYMELEAF_CACHE=falsespring.thymeleaf.cache: false- 在Halo工作目录的下创建主题文件夹(必须与
themes/中的theme.yaml一致)metadata.name - 编写(必填)和
theme.yaml(可选)settings.yaml - 在下创建模板文件
templates/ - 在控制台→主题管理中安装并激活主题
- 访问前端页面进行验证
开发期间禁用Thymeleaf缓存:设置环境变量(Docker环境),或在配置文件中设置(源码运行模式)。
SPRING_THYMELEAF_CACHE=falsespring.thymeleaf.cache: falseStarter Templates
入门模板
The directory provides two ready-to-use theme templates:
assets/- — Zero-build-tool minimal theme with all 8 template files; ideal for quick prototyping or simple themes
assets/theme-minimal/ - — Vite project template with
assets/theme-vite/(recommended for new themes); includes partial layout reuse and CSS toolchainvite-plugin-halo-theme
Usage: copy the directory into in your Halo working directory, ensure the folder name matches in , then install and activate in Console.
themes/metadata.nametheme.yamlassets/- — 无需构建工具的极简主题,包含全部8个模板文件;适合快速原型开发或简单主题
assets/theme-minimal/ - — 带有
assets/theme-vite/的Vite项目模板(推荐用于新主题开发);包含部分布局复用和CSS工具链vite-plugin-halo-theme
使用方法:将目录复制到Halo工作目录的下,确保文件夹名称与中的一致,然后在控制台中安装并激活。
themes/theme.yamlmetadata.nameReferences Index
参考索引
| File | Content | When to read |
|---|---|---|
| references/structure-and-config.md | Directory structure, theme.yaml fields, settings.yaml form definition | Creating a theme, configuring theme.yaml/settings.yaml |
| references/vite-plugin.md | vite-plugin-halo-theme integration guide, include/slot template syntax, TailwindCSS integration | Setting up a Vite-based theme (recommended) |
| references/templates.md | Template route mapping, available variables per template | Writing template files |
| references/global-variables.md | Global variables (site, theme, theme.config) and type definitions | Accessing site info or theme setting values |
| references/finder-apis.md | All Finder APIs (postFinder, categoryFinder, tagFinder, menuFinder, singlePageFinder, etc.) | Querying data from any template |
| references/static-resources.md | Static asset reference methods ( | Referencing CSS/JS/images in plain HTML themes |
| references/template-tags.md | Custom tags (halo:comment extension point, halo:footer injection) | Integrating comment plugins, injecting footer code |
| references/annotations.md | AnnotationSetting for model custom fields, | Adding custom fields to menu items/posts/categories and using them in templates |
| references/packaging.md | Packaging a theme as a ZIP using | Preparing a theme for release or upload |
| 文件 | 内容 | 阅读时机 |
|---|---|---|
| references/structure-and-config.md | 目录结构、theme.yaml字段、settings.yaml表单定义 | 创建主题、配置theme.yaml/settings.yaml时 |
| references/vite-plugin.md | vite-plugin-halo-theme集成指南、include/slot模板语法、TailwindCSS集成 | 搭建基于Vite的主题时(推荐) |
| references/templates.md | 模板路由映射、各模板可用变量 | 编写模板文件时 |
| references/global-variables.md | 全局变量(site、theme、theme.config)及类型定义 | 访问站点信息或主题设置值时 |
| references/finder-apis.md | 所有Finder API(postFinder、categoryFinder、tagFinder、menuFinder、singlePageFinder等) | 在任意模板中查询数据时 |
| references/static-resources.md | 静态资源引用方法( | 在纯HTML主题中引用CSS/JS/图片时 |
| references/template-tags.md | 自定义标签(halo:comment扩展点、halo:footer注入) | 集成评论插件、注入页脚代码时 |
| references/annotations.md | 模型自定义字段的AnnotationSetting、在模板中读取元数据的 | 为菜单项/文章/分类添加自定义字段并在模板中使用时 |
| references/packaging.md | 使用 | 准备发布或上传主题时 |