Summary
This feature aims to make Zola support multilingual sites for both content and templates.
Note that content and template translations are mostly orthogonal and can be implemented separately.
Motivation
Some sites are in multiple languages and want to share templates/content while only translating bits of the UI of the actual markdown content. Some sites also have (some) of their content in multiple languages.
Guide-level explanation
Overview
Configuration
The default language is set by default_language
in the config.toml which currently exists.
To allow supporting many languages, a new lang
or translations
directory can be added, containing files for each language. Format to be chosen is still up in the air but we don’t want to invent something new so we need to definitely go for something standard. See https://github.com/getzola/zola/pull/111#issuecomment-410634780 for some discussion on that.
A user should probably also need to define which languages they want to add to their site so we can warn on invalid languages (eg a typo in a filename should not create a new language in Zola).
Url
The default language base url will be equal to config.base_url
.
Other languages will be available at {config.base_url}/{language}
.
There will be an option (force_i18n_redirect
or something similar) in the config to always redirect to a URL with a language code in it, ie base_url
would redirect to {base_url}/{default_language}
.
File organisation
The content files have to have the same name for multiple languages.
The language is defined in the extension prefix: {name}.{language_code}.{extension}
The language code can be omitted for the default language.
content
├── _index.md
├── _index.fr.md
├── about.md
├── about.fr.md
└── some_section
├── _index.md
└── _index.fr.md
Templates
All templates will get an additional parameter: lang
for the current language (en
, fr
, etc) and a new global Tera function will be added to get the i18n values out of the config.toml.
{{ trans(key="title", lang=lang) }}
If lang
is not provided, it will look up the key in the default language map.
get_page
, get_section
and get_url
will also have to take an optional lang
parameter.
Each page/section will have a languages
map pointing to al the other languages pages of the same content.
Content
Internal links in the markdown text will refer to the current lang and fallback to the actual file if nothing was found.
Reference-level explanation
Loading
We need to revamp the whole content loading:
- load every page/section and add the language if there is one, we can set it to
config.default_language
automatically - if we have several languages, we try to reconcile pages/sections based on filename in a map {lang -> key} on each page/section to point to other version of the same content
- we populate sections as usual except we filter by language for pages/subsections, eg a
_index.fr.md
will only get.fr.md
pages
Template and rendering
Rendering will be done language by language and the lang
will be passed in all Tera context.
RSS
A separate RSS file will be rendered for each language:
-
{base_url}/rss.xml
-
{base_url}/fr/rss.xml
and so on.
Taxonomies
How do we handle them? Are users going to use the same taxonomy name (let’s say authors
for example) for content in English/French/Italian or people would create a auteurs
taxonomy in French and so on. The issue with putting everything in the same taxonomy is that the URL would look like fr/authors
with no way of changing the url apart from making the taxonomy config more complex.
Drawbacks
This change requires changing pretty much all the logic in Zola to account for multiple languages for a feature used by a minority of people. Not having it is a deal breaker for those people.
Rationale and Alternatives
This design is similar to Hugo and Lektor and is the simplest to use from a user point of view, as far as I know.
Alternative design: do nothing
A user could create a fr
section and mirror the content of the default language for example.
This is even simpler than the solution in the RFC but it doesn’t work well with posts with assets as those will need to be duplicated or put in the static
folder.
i18n in the templates could be solved by adding a lang
attribute in the extra
of the front-matter of section of pages by the user and using that.
Pros
-
Easy to implement: pretty much nothing to do
-
Easier to understand (imo)
Cons
-
No RSS per language
-
Harder to get started for a user
-
No way to link articles from different languages unless it is done manually in the front-matter
Unresolved questions
RSS
How to only render a RSS feed for a given language if generate_rss
is set to true. Do we even care about that feature?
Content with url set
Some content can have a path hardcoded in the front-matter: what to do with multiple languages version of such content?
Prepending the language code to the URL is the obvious solution but is not intuitive and change implicitly the meaning of the url field so it’s not an option.
I think having 2 files with the same url in front-matter should not be allowed.