# Internationalization (i18n) Halo themes support i18n via `.properties` files under an `i18n/` directory. Thymeleaf provides the `#messages` object for reading translations in templates. --- ## Directory Structure ``` my-theme/ ├── i18n/ │ ├── default.properties # Fallback / default language │ ├── zh_CN.properties # Simplified Chinese │ ├── zh_TW.properties # Traditional Chinese │ └── es.properties # Spanish ├── templates/ └── theme.yaml ``` > Halo uses `default.properties` as the fallback when no locale-specific file matches the user's preference. --- ## Properties File Format Simple key-value pairs: ```properties # default.properties page.author.title=Author: {0} common.previousPage=Previous common.nextPage=Next common.noPosts=No posts yet. ``` ```properties # zh_CN.properties page.author.title=作者:{0} common.previousPage=上一页 common.nextPage=下一页 common.noPosts=暂无文章。 ``` Placeholders `{0}`, `{1}` ... are filled by the arguments passed to the message function. --- ## Using i18n in Templates ### `#messages.msg(key)` — Get a message ```html

``` ### `#messages.msgOrNull(key)` — Get a message or null if missing ```html ``` ### Thymeleaf shorthand `#{key}` — Standard expression ```html Previous ``` --- ## `#locale` — Current Locale Useful for rendering language-specific UI or setting ``: ```html ``` --- ## Frontend i18n Pattern Some themes also need translations in JavaScript. A common pattern is to inject the needed strings into a global object via inline script: ```html ``` > Note: `[(#{key})]` is Thymeleaf's unescaped inlining syntax. It evaluates the expression and inserts the raw value into the script. --- ## Online Docs https://raw.githubusercontent.com/halo-dev/docs/refs/heads/main/docs/developer-guide/theme/global-variables.md