Translation
This platform is designed to be multilingual, and leverages the translations being maintained in a separate repository:
This document provides an overview of how the platform accomplishes this, and how it can be extended.
Throughout this discussion of translation, there will be repeated mention of "translation keys". See the glossary page in the "translation keys" section for a definition.
Translation data¶
In order to compile the platform in multiple languages, Jekyll needs the translations themselves. The recommended way to pull in the translations is through the data repository. Note that the open-sdg-data-starter comes pre-configured to use this approach.
Adding new languages¶
There are 4 requirements for adding a new language to the platform
- Check that the new language is implemented in the repository mentioned above. If it is not, you can copy that repository and implement the language yourself.
- Specifically, you will need to translate all the YAML files in this folder English source.
- Make sure that translated goal icons have been created. These are currently maintained in the sdg-translations project.
- Specifically, you will need to produce translated versions of all the PNG files in this folder of goal images and this folder of high-contrast goal images (for high contrast versions).
- Add the new language in the 'languages' list in your site config (
_config.yml
) and data config (config_data.yml
) files. - Create new versions of any Jekyll pages that you would like to have available in the new language. Note that the open-sdg-site-starter project includes a script to make this easier.
Using translated text in Jekyll templates¶
When writing Jekyll templates for this platform, there should never be any direct text written. For example, you should never see anything like this:
<h1>Sustainable Development Goals</h1>
Instead, you should see something like this:
<h1>{{ page.t.general.sdg }}</h1>
The page.t
variable contains a nested structure of translation values, corresponding to the folder structure of the repositories mentioned above. For example, in the example above, the "general" refers to this general.yml translation file, and the "sdg" refers to that particular line within the translation file.
Jekyll will display translated text according to the "language" specified in the "front matter" of the current document.
Translating variables in Jekyll templates¶
Sometimes you may need to translate something that exists as a Liquid variable in a Jekyll template. This can be accomplished using the "t" filter, that is provided by the jekyll-open-sdg-plugins Ruby gem. A contrived example of how this works is as follows:
{% assign foo = "general.sdg" %}
<h1>{{ foo | t }}</h1>
Note that it is always safe to run variables through this t
filter, even if you aren't sure whether it actually contains a translation key. If the variable doesn't actually contain a translation key, then it will be unchanged.
Translating indicator metadata¶
The translate indicator metadata, you put "translation keys" directly into the indicator metadata. For example, instead of:
un_custodian_agency: UN Habitat
You might do:
un_custodian_agency: agencies.un_habitat
Assuming that agencies.un_habitat
refers to an actual translation key in your translations, this will translate the field according to that entry.
Alternative approach: subfolders¶
Another mechanism available for translating metadata is to place pre-translated versions of your metadata files into subfolders, named by the language. The pre-translated versions need not contain all the fields - only the particular fields that you have translated.
For example, suppose you have a metadata file called 1-1-1.md
containing the following:
indicator_name: My English indicator name
some_other_field: XYZ
If you want to translate the indicator name into Spanish, you could create a subfolder called es
and place inside a file called 1-1-1.md
containing the following:
indicator_name: My Spanish indicator name
This will translate the indicator name into Spanish, but will leave some_other_field
alone.
Subfolders vs translation keys¶
You may be wondering which of the above approaches you should use - subfolders, or translation keys. The answer depends on your preference. You can use either approach - or even both approaches - as you see fit.
A practical tip: You may find that using translation keys is preferable for smaller pieces of content that are shared by multiple indicators. Translation keys work best here, because they allow you to maintain the translation in only one place. By contrast, using the subfolder approach would require you to copy/paste the translation into each metadata file in the subfolder.
However, the subfolder approach can be more straightforward and direct, may be preferable for larger chunks of content that are specific to one indicator only, such as indicator descriptions.
Translation in Javascript¶
There is a global object translations
available to your Javascript. It can be used similarly to the t
variable in Liquid templates. For example:
var translatedText = translations.general.sdg;
It also includes a function t()
which can be used similarly to the t
Liquid filter. For example:
var translationKey = 'general.sdg';
var translatedText = translations.t(translationKey);
NOTE: In contrast to Jekyll, any translation keys you will need in Javascript need to be "imported" before they can be used. The mechanism for importing translating keys is the Jekyll include multilingual-js.html
. You can use this to import an entire translation group. For example, this is how you can import all the translation keys in the "general" group:
{% include multilingual-js.html key="general" %}
Translating data disaggregations and columns¶
To translate the disaggregations and columns in your data (such as "Age", "Sex", "Female", etc.) you will need to make sure that the disaggregation values in your CSV files correspond to translation keys. For example, instead of a column called Sex
you could call it data.Sex
. Assuming that data.Sex
refers to an actual translations key in your translations, this will translate the disaggregation according to that entry.
Similarly, instead of a values like Female
, you could use data.Female
to correspond to a translation by that key.
NOTE: There is a shortcut available here. Because data disaggregations/columns will almost always refer to the
data
group, you can actually leave thedata.
off.
Available translation-related variables¶
In addition to the page.t
variable for displaying translations, there are 3 other Liquid variables of general use:
page.language
: The 2-letter code for the current languagepage.language_public
: Version of the code for use in public URLspage.baseurl
: A version of site.baseurl including any language code
These variables are available in all Jekyll documents.
Overriding and extending translation data¶
Inevitably an implementation of this platform will need to display some text that is not already included in the repositories mentioned above, and that is likely specific to a particular country. There are two recommended options for this:
- Maintain your translations in a
translations
folder of any Git repository. An easy way to get started with this is to copy the sdg-translations project and then clear out thetranslations
folder. More detail on this process is below. - Put the translations directly into your data repository, in a
translations
folder. See this folder in the data starter for an example.
Whichever approach you take, make sure to adjust your data repository's configuration as needed. See this example of a data repository's translation configuration.
NOTE: If you make a translation that you think would be useful to others, please submit it as a pull-request!
Maintaining translation data in a separate repository¶
An implementation of Open SDG can pull its translations from any number of Git repositories. Out of the box, the starter repositories are configured to pull translations from the sdg-translations project. To see an example, see that part of the data starter configuration.
However as mentioned above, you likely will need custom translations of text that are specific to your region. For a direct approach, as mentioned above, you can add these translations directly to a translations
folder in the data repository. The starter repository is configured to pull translations from this folder, if it exists (see that part of the data starter configuration).
But perhaps you would prefer to maintain your translations in a separate Git repository. The recommended approach here is to copy sdg-translations by going there and clicking the green "Use this template" button. This will allow you to name it whatever you would like, and will give you an exact copy of sdg-translations.
You likely don't want to maintain all of the translations in sdg-translations, so it is recommended that you clear out the contents of the translations
folder of your copied version. Next, you can add only the translations that you need. Then, you will need to update your data repository configuration so that it pulls from sdg-translations AND your copied version.
For example, if you named your copied version my-github-org/my-translations-repo
, then you would update your data repository configuration from this:
translations:
- class: TranslationInputSdgTranslations
source: https://github.com/open-sdg/sdg-translations.git
tag: master
...to this:
translations:
- class: TranslationInputSdgTranslations
source: https://github.com/open-sdg/sdg-translations.git
tag: master
- class: TranslationInputSdgTranslations
source: https://github.com/my-github-org/my-translations-repo.git
tag: master
Note that because your copied version is after the sdg-translations entry, you can "override" anything in the sdg-translations project by duplicating (and changing) it in your copied version.
Also note, as a good practice you should point at "tags" (such as "1.0.0") instead of "branches" (such as "master"). In other words, a better configuration would be something like:
translations:
- class: TranslationInputSdgTranslations
source: https://github.com/open-sdg/sdg-translations.git
tag: 1.0.0
- class: TranslationInputSdgTranslations
source: https://github.com/my-github-org/my-translations-repo.git
tag: 1.0.0