[i18n] Theme translations

Hey folks, i think it would be really cool to have translation strings available in theme.toml like in config.toml. This would allow to people to swap theme to compare layout without breaking translations used in the theme.

I’ve worked on this on my side i’ll open a PR if you’re interested to give feedback :slight_smile:

1 Like

I do want to switch to something like https://projectfluent.org/ soonish so I wouldn’t add the string approach to themes I think. Better to have everything use Fluent.

1 Like

Hey that system looks great, thanks for sharing! I would love to have something like that though i’m sure simple strings are more than enough for my usecase (multilingual personal blogs).

Coming back to zola after a few months I was really pleasantly surprised by the great i18n progress on zola 10.1 so i wanted to thank you from the depth of my heart for making such a great SSG. I’m preparing a cheatsheet on my blog. I’ll post the link here on the forums when it’s done.

With lang in taxonomy templates and lang param in get_url template function around the corner, the next minor Zola version could be finally THE i18n version (that’s a big thing, cheers!) So if there’s not going to be a new release until Fluent integration, don’t mind me but if there’s going to be 0.10.2 before Fluent please consider including my PR

1 Like

Hello people, it’s been almost two years and the situation hasn’t changed so i figured it’s time for a revival of this topic! To me the question is how can we empower themes to empower users while retaining user capability to override any part of the theme?

The topic was originally about theme translations specifically, but there’s a number of other concerns (related to themeing and i18n) i’d like to discuss. I’m willing to try and make patches for the first three problems outlined if other people agree they are actual problems, about the fourth i’m not sure what the best course of action is and would like more feedback.

Problem #1: themes can’t package translation strings

It’s common for a theme to have translatable strings, for example for “next/previous page” buttons, or for the date format. If the theme is not able to provide/query those, it means it’s not really i18n-friendly and the user will have to rewrite parts of the theme to support localization. However, it’s important that the user retains the possibility to use different wording if they so please, and that they can add new translation strings for their own widgets/shortcodes.

Currently, the only way to achieve that is to use the [extra] section from config/theme.toml, because they are properly merged recursively when the build starts. However, it means templates can’t use the trans function, which sort of defeats its purpose. Instead, you have to explicitly call config.extra.translations|get(key=lang)|get(key="myTranslation").

Proposal: i’d like to have some mechanism for translations to inherit from themes but allow site-wide override. The simplest form of that would be supporting a [translations] or [languages] section in theme.toml, although i would see an interest in supporting other translation mechanisms (per-lang locale files using TOML or po)

Problem #2: missing translations cause build to fail

Currently, if a translation is missing in a language, the build will fail. This is a good default setting as it prevents many stupid mistakes. However, it can happen for volunteer-run sites that translations are out of sync. In this case, erroring is not a solution because it will incentivize users to place placeholders in their actual translation strings just to have their site built, at which point missing translations will go unnoticed unless there is a manual review.

Proposal: have a configuration switch to determine how to act on missing translations:

  • error and abort (default for build mode)
  • print a warning a use a placeholder containing the name of the missing key (default for serve mode)
  • print a warning and fallback to the translation in the default_language

Printing a warning during build (but allowing to build) may prove useful to get the stuff translated in the long run.

Problem #3: site/theme inheritence rules are not intuitive

This is a different issue but since we’re talking about site/theme inheritance, it’s worth mentioning here: extending a theme from your site is not as easy as it could be. Having to spell out the theme path in extends is not intuitive. Changing your customized templates in order to try a different theme is in my view an antipattern, because as soon as you start customizing a theme you’re “stuck” and every other theme you want to try (just to get a quick overview, even if your customizations aren’t relevant anymore) takes you several minutes of adjusting your templates just to get the site to build and display anything.

Also very relevant: supporting theme extensions that are not tied to a theme name enables interoperability between theme. So if a single person maintaining several themes, or several theme maintainers want to “standardize” the blocks you can override, it would make it possible to retain customizations across themes.

Proposal: template lookup rules should support a magic string like THEME so you would extends "THEME/templateName.html" without having to spell out the theme name (which may change in the future). Related: it would be nice to be able to print warnings when the site overrides a block which does not exist in the theme.

Problem #4: sites can’t override theme-provided macros

Still unrelated to the original problem, but worth discussing: the only way for a site to override a theme-provided macro is if the macros each live in a separate file (like shortcodes), which creates an “import hell”.

Proposal 1: Reuse HTML shortcodes as site/template-provided macros. It’s already possible to import them one-by-one, but that’s not desirable. A default shortcodes:: would be more handy, although loading it by default in every template might create a resource overhead, especially since some of these shortcodes are only supposed to be called from markdown and will never be used in themes. Alternatively, providing a shortcode function with a reserved keyword for the shortcode name looks like a fair alternative. If supported by the tera templating engine, having a shortcode function which returns the macro itself (shortcode(name="mything")(param1=foo, param2=bar)) would be more convenient as it would not reverse a special keyword in shortcodes.

Proposal 2: Allow to override macros from templates. This can take place on a macro level or on a block level. On a macro level, it appears macros are not properly inherited by the extends directive and in any case tera would prevent it (with Macro `mymacro` is duplicated error):

Reason: Failed to render 'page.html'
Reason: Macro `widgets::theme_macro` not found in template `page.html`

(where theme_macro is defined in the theme’s widgets.html, and the site’s widgets.html extends the theme’s widgets.html)

On a block level (defining a block macro_t in the theme’s widgets and overriding it in the site’s widgets) there’s also some shenanigans:

* Failed to parse "/REDACTED/themes/water/templates/widgets.html"
   --> 138:1
    |
138 | {%- macro t(key) -%}␊
    | ^---
    |
    = unexpected tag; expected an endblock tag (`{% endblock block_name %}` or some content
1 Like

For 1 and 2 I would prefer moving to use Fluent rather than adding more things to the trans function. I would go with either error or fallback to default language+warning, not 3 separate modes though.

For 3, I’m not sure how that would work in practice. Themes maintainer can use whatever structure they want for their templates so you will still need to override random files to customise things and even if it’s something like page.html they will have completely different block structure.

For 4, it’s more of an issue in Tera that should be taken into account for its v2 - it’s not going to be fixed in v1.

As I’ve mentioned before I think, I have never used themes in Zola or other SSGs so it’s not really something I think a lot about or would spend time on.