If you are creating a private theme for a single language blog, you may skip this part.
We do not expect you to translate themes to multiple languages, but the theme should be translatable. It means that all strings in the template files should be translatable. This is a requirement if you are planning to publish the theme.
If you are creating a private theme for a single language blog, you may skip this part.
Internationalization is easy. Instead of writing this:
<h1>Welcome</h1>You have to write this:
<h1>{{ 'welcome' | lang }}</h1>Here, 'welcome' is a key in en.yaml. And, lang is a custom
Twig filter defined by HB. HB will display the correct language based on the language of the user's blog.
The /lang folder contains .yaml language files. A language file may look like
this:
welcome: WelcomeEnglish (en.yaml) is the default language and it is required. You may also define
other languages. Language codes should be ISO 639-1 Codes.
Let's see another example:
welcome: "Welcome to our blog"
usersCount: "* users"
byAuthor: "by {authorName}"In Twig templates, use the lang filter to render these strings with placeholders replaced.
<h1>
{{ 'welcome' | lang }}
</h1>
<p>{{ 'byAuthor' | lang(authorName=_author.name) }}</p>
<p>{{ 'usersCount' | lang(2) }}</span>As you can see there are two placeholders types:
*named{authorName}Sometimes you may want to display a different message when a number is zero, one, or more than
one. Instead writing a bunch of if conditions, you may use the lang_by_number custom Twig
filter.
# en.yaml
posts_num_zero: No Posts
posts_num_one: 1 Post
posts_num_multi: "* Posts"Number of posts:
{{ _pagination.total | lang_by_number(
zero="posts_num_zero",
one="posts_num_one",
multi="posts_num_multi"
) }}_pagination.total is a number. The * in posts_num_multi will be replaced by the given number.
You may take a look at the languages guide. It explains how to change the language or set up multiple languages in a blog.
Let's say that the blogger changes his site's language to French (fr). Then, we check
if a fr.yaml is available in the lang folder. If not, we'll just show
English strings. However, anyone can easily add a fr.yaml from the Console (even someone
without technical knowledge can do that). Keys don't change, only the strings.
Here's how an fr version of the above file will look like.
welcome: "Bienvenue sur notre blog"
usersCount: "* utilisateurs"
byAuthor: "par {authorName}"DO NOT use nested keys in YAML language files. Keep it to simple key-value pairs.
Usually, you want to render a language switcher in multi-language blogs to allow visitors to switch between languages.
{% if _blog.languages | length > 1 %}
<script>
function toggleLanguageDropdown() {
document.querySelector('.dropdown').classList.toggle('open');
}
</script>
<div class="language-switcher">
<a class="current-language" onclick="toggleLanguageDropdown()">{{ _lang.code }}</a>
<div class="dropdown">
{% for lang in _blog.languages %}
<a
href="{{ lang.code | language_variant_url }}"
class="{% if lang.code == _lang.code %}active{% endif %}"
>{{ lang.name }}</a>
{% endfor %}
</div>
</div>
{% endif %}{% if _blog.languages | length > 1 %} checks if the blog has more than one language.
There is no need to have a language switcher in single-language blogs._lang is the current language. So, {{ _lang.code }} displays the current
language code.{% for lang in _blog.languages %} loops through all the languages in the blog
and renders an <a> element for each language inside the dropdown.language_variant_url helper filter is used to generate the URL. This
filter finds out the best possible language variant of the current page. For example, if the current
page is a post, this function will give the URL of the language variant of that post only if that
variant exists. If not, the URL of the index page (in the given language code) will be returned.