edbf78f236
- Halo Plugin 后端(Java/Gradle),含 DarkModePlugin 主类和测试 - Vue 3 + TypeScript 前端 UI,包含主题切换组件和设置页面 - 暗色模式 CSS 变量和覆盖样式(布局/编辑器/表单/滚动条等) - 设计文档和调查文档 - Halo 插件/主题开发 Agent Skills Co-Authored-By: Claude <noreply@anthropic.com>
3.4 KiB
3.4 KiB
Model Metadata (Annotations)
Themes can extend built-in Halo models with custom fields via AnnotationSetting resources (e.g. adding an icon to menu items, or a download URL to posts), then read those values in templates via the #annotations utility.
Defining a Metadata Form (AnnotationSetting)
Create a file (any name) in the theme root, e.g. annotation-setting.yaml, and declare an AnnotationSetting resource:
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
name: theme-foo-menuitem-abc123 # recommended: add theme prefix + random suffix to avoid conflicts
spec:
targetRef:
group: ""
kind: MenuItem
formSchema:
- $formkit: text
name: icon
label: Menu icon class
value: ""
Multiple models can be declared in the same file separated by ---:
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
name: theme-foo-post-abc123
spec:
targetRef:
group: content.halo.run
kind: Post
formSchema:
- $formkit: text
name: download_url
label: Download URL
value: ""
---
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
name: theme-foo-menuitem-abc123
spec:
targetRef:
group: ""
kind: MenuItem
formSchema:
- $formkit: text
name: icon
label: Icon
value: ""
Supported Models
| Model | group |
kind |
|---|---|---|
| Post | content.halo.run |
Post |
| Single page | content.halo.run |
SinglePage |
| Post category | content.halo.run |
Category |
| Post tag | content.halo.run |
Tag |
| Menu item | "" |
MenuItem |
| User | "" |
User |
Notes
- All values in
metadata.annotationsare strings, so form values must also be strings. - Do not use components with non-string output such as
number,group, orrepeater. - For
checkbox, explicitly seton-value/off-valueto string values (e.g."true"/"false"). - Use a theme-name prefix plus a random suffix for
metadata.nameto avoid conflicts with other themes/plugins, e.g.theme-earth-post-wanfs5.
Reading Metadata in Templates
Halo provides a #annotations utility object in Thymeleaf with three methods:
#annotations.get(object, key) — Get a value
<div th:with="menu = ${menuFinder.getPrimary()}">
<li th:each="item : ${menu.menuItems}">
<i th:class="${#annotations.get(item, 'icon')}"></i>
<a th:href="${item.status.href}" th:text="${item.status.displayName}"></a>
</li>
</div>
#annotations.getOrDefault(object, key, defaultValue) — Get a value with fallback
<i th:class="${#annotations.getOrDefault(menuItem, 'icon', 'fa fa-link')}"></i>
#annotations.contains(object, key) — Check if a key exists
<i
th:if="${#annotations.contains(menuItem, 'icon')}"
th:class="${#annotations.get(menuItem, 'icon')}"
></i>
Online Docs
AnnotationSettingspec and supported models may change across Halo versions. Fetch the relevant doc if unsure about supportedgroup/kindcombinations or form schema constraints.
- Using metadata in templates: https://raw.githubusercontent.com/halo-dev/docs/refs/heads/main/docs/developer-guide/theme/annotations.md
- Defining annotation forms: https://raw.githubusercontent.com/halo-dev/docs/refs/heads/main/docs/developer-guide/annotations-form.md