TTWeb Basics 7. Localization And Internationalization

Localization settings are specified in _config.yml file, e.g.:

default_lang: 'en'
languages: ['en', 'es']

This will copy pages for each non-default locale from the generated website to a locale sub-folder. A default language copy is stored under the project root. So a 3-page site

/index.html
/about.html
/contact.html

with an en (defaul) and es locale would be generated as:

/index.html
/about.html
/contact.html
/es/index.html
/es/about.html
/es/contact.html

Translation Tags

To add localized content (e.g. labels, captions, etc), translation keys and files should be used. This is also the recommended approach for setting site-wide static content such as contact information, footer text, etc.

{% t <translationkey>[, locale: <locale>] %}

Locale files are stored in the _locales folder (e.g. _locales/en.yml) in yaml format. In jekyll-processed pages, the liquid tag t can be used to render content from these files.

For example, given _locales/en.yml:

en:
  language_name: EN
  footer:
    section_1: 'EN Footer Area 1'

and _locales/es.yml:

es:
  language_name: ES
  footer:
    section_1: 'ES Footer Area 1'

The html

<footer>
  <div>
    <h4>{% t 'footer.section_1' %}</h4>
    <span>{% t 'language_name', locale: 'en' %}</span>
    <span>{% t 'language_name', locale: 'es' %}</span>
  </div>
</footer>

will render the following content for the en locale:

<footer>
  <div>
    <h4>EN Footer Area 1</h4>
    <span>EN</span>
    <span>ES</span>
  </div>
</footer>

Making translations live-editable

If you want the user to be able to edit a translatable piece of text, set the parameter “editable” to true. For example

<a href="booking-url">
    {% t 'header.book_now_button', editable:true %}
</a>

NOTE: Be careful not to make html attributes live-editable. If you’re setting an alt tag <img src="/lobby.jpg" alt="{% t 'lobby_description' %}" /> do NOT add “editable:true”.

Localizable Properties

A page’s Front Matter can contain different variables which might be rendered via Liquid the liquid code: ``. For example: page.title is used in the default.html layout file. It can be localized using the following syntax:

---
title_localized:
  en: EN Page Title
  es: ES Page Title
---

The reference to title’s value will use current language, so EN and ES pages will have translated titles accordingly.

Localizing Content Models

For Content Models, you can specify which fields will be localized (e.g. the name or description of an event) and which will remain “global” for all locales (e.g. the date or entry price of an event). To make a content model field localizable, just add “localizable”: true to the field definition.

When a content model has localizable fields, the editing interface will show a dropdown at the top to allow the user to toggle between langauges. When a user switches to the non-default language, the non-localizable fields will become un-editable and the localizeable fields will display the current default language value for that field as an extra “hint.”

When localizable fields are saved in JSON data, the field names will be appended with _localized just like with localizable front matter. And instead of a single string value, the field value will be a hash of key-value pairs (with each key being a locale). For example:

{
  "name_localized": {
    "en": "Name",
    "es": "Nombre"
  }
}

NOTE: You will still reference this in templates as the name field. For example:

{% for event in site.data._models.events %}
  {{ event.name }}
{% endfor %}

When the site is generated in each language, the corresponding value within name_localized will be used in the name field.

References to a page’s translations

To obtain a localized URL to the current page, there is a simple synatax:

{{ page | permalink: locale: <language> }}

To iterate over languages, the site.languages variable can be used, for example:

{% for lang in site.languages %}
  <a href="{{ page | permalink: locale: lang }}">{{ lang | upcase }}</a>
{% endfor %}

To handle current language there is site.active_lang variable. The liquid if tag allows highlighting current page’s language.

The entire example of a language drop-down is shown below:

<select id="language" onchange="location = this.options[this.selectedIndex].value;">
  {% for lang in site.languages %}
    <option {% if lang == site.active_lang %} selected="true" {% endif%} value="{{ page | permalink: locale: lang }}">
      {% t 'language_name', lang %}
    </option>
  {% endfor %}
</select>