Internationalization
In this section, we will explain how internationalization is handled by the framework.
In fact, it comes with a fully featured internationalization system that handles string translation
and date localization
.
Configuration
The supported locales must be declared in the application configuration:
{
"default": {
"locales": ["en-US", "pt-PT", "fr-FR", "hu-HU"]
}
}
Locales identifiers are based on the “RFC 5646: Tags for identifying languages” standard itself referenced by “BCP 47: Tags for identifying languages”.
The expected supported subset is in ABNF syntax:
langtag = language
["-" region]
["-" private_use]
language = 2*3ALPHA ; shortest ISO 639
region = 2ALPHA ; ISO 3166-1 code
private_use = "x" 1*("-" (1*8alphanum))
Here are some examples:
en-GB
,fr-FR
,fr-FR-x-project
.
Caution
If you need to define translation in a module, just have a look in Modularisation’s section.
Caution
If you need to define translation in a vendor, just have a look in Vendor’s section.
Default locale
The I18nManager
has a defaultLocale configuration parameters which takes the locale identifier to be loaded at the application startup.
Caution
If not specified, the first locale defined in the locales array will be used.
Moreover, the default language can also be overridden with a query string parameter (lang=<localeIdentifier>)
. For example, if you open the application with the following url http://localhost/defaut.html?lang=fr-FR
, you will get French translation being loaded at startup.
String translation
The I18nManager
is in charge of the translation of all labels and texts in the application.
It works in a very simple way:
- just put the definition of keys that are representing some text or label in the UI.
- for each key, you just have to associate as many as needed translations.
- those keys are used in the application and replaced accordingly to the current language.
Locales bundles
Locales bundles are defined in JSON files into the i18n
directory of the application.
There is one file per locale, named LocaleString<LocaleIdentifier>.json
.
For example:
en-GB
:LocaleStringEnGB.json
fr-FR
:LocaleStringFrFR.json
fr-FR-x-project
:LocaleStringFrFRXProject.json
The JSON structure is defined as follows:
{
"id": "en-GB",
"strings": {
"app.hello": "Hello"
"app.world": "World"
"app.welcome": "Welcome %1!"
}
}
How to get a translation
In order to get a translation of a defined string, just proceed as follows:
var i18n = $I18nManager.getInstance();
// Choose your language
i18n.setLocale("fr-FR");
// Get some translations
i18n.getStr(βapp.helloβ); // βHelloβ
i18n.getStr(βapp.whateverβ); // βapp.whateverβ
i18n.getStr(βHey! %1 %2%3β, βapp.helloβ, βapp.worldβ , β!β); // βHey! Hello World!β
i18n.getStr(βapp.welcomeβ, βPaulβ); // Welcome Paul!β
Caution
- If a key isn’t defined, it returns the key (i.e. the key can be your default translation for non defined keys or non-supported languages)
- You can compose a string with several keys using the
%X
value and provide a key as argument for each%X
you used. - You can parameterize the translation if it contains
%X
, you just need to provide as much as needed arguments.
Usage with Widgets, text and labels
A widget/node should/must always use the i18n
manager to define static texts and labels.
Widgets and nodes provide a specific method for that which is named updateText()
.
import $Widget from "@Widget";
export default $Widget.declare("I18nWidget", {
properties: {
id: βi18nWidgetβ,
text: βapp.helloworldβ // Define a text/label key
},
methods: {
createNodes : function(){
this.textNode = document.createElement(βspanβ);
this.textNode.className = βtextβ;
this.append(textNode);
},
updateText : function(){ // Function to update all widget texts and labels
this.textNode.textContent = wtv.i18nManager.getStr(this.text);
}
}
});
All labels and texts has to be set in this specific method.
And updateText()
is automatically called:
- during the widget/node initialization.
- each time the
setLocale()
method of the I18nManager is called to refresh all widgets/nodes texts and labels.
Date localization
The LocalizedDate
class offer an API to deal with localized date:
- All “non deprecated” standard Date methods are available,
- Those that had “platform specific” behavior are stabilized,
- Those that are generated “American representation” (ex:
{@link LocalizedDate#toString}
) are using the application locale instead, - The standard i18n related methods are also using the application locale.
As it is tied to the I18nManager
, the date formatting depends on the current locale set up by the application.
import $LocalizedDate from '@LocalizedDate';
$LocalizedDate.format("isoDate");
The core offers LocalizedDate
support for a great number of locales; you can however add your own or override the core ones at level application.