Loading...
Loading...
Complete guide for Halo CMS theme development. Covers theme directory structure, Thymeleaf template syntax, template route mapping, template variables, Finder API, global variables, theme settings, static asset management, Vite integration, and custom tags. Use when: creating or modifying Halo themes, writing Thymeleaf templates, calling Finder APIs, configuring theme.yaml / settings.yaml, integrating Vite, adding settings forms, handling static asset references, or implementing comment/footer extension points.
npx skill4agent add halo-dev/dev-skills halo-theme-dev<!-- 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>themes/metadata.nametheme.yamltheme.yamlsettings.yamltemplates/SPRING_THYMELEAF_CACHE=falsespring.thymeleaf.cache: falseassets/assets/theme-minimal/assets/theme-vite/vite-plugin-halo-themethemes/metadata.nametheme.yaml| 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 |