-
Notifications
You must be signed in to change notification settings - Fork 6
Internationalization
dcat-ap-viewer supports multiple languages. Although there are standard ways how to translate/localize application, many of them are not ready to be used in our case. The reason is that many of the labels are resolved online and are not part of the application e.g. codelists. This lead to a situation where we have static and dynamic content that needs to be translated.
Overall there are three areas where the translation is needed:
- strings (static text as in i18next)
- labels (for RDF entities like publishers, datasets, etc.)
- URLs (as we do URL path resolution on client site, to minimize server configuration)
Existing solution: i18next
There are standard libraries for React like react-i18next. The main disadvantage is their size and a fact that they would still require considerable effort to integrate especially because of the Language detection. There are nice tutorials how to use react-i18next.
The basic idea behind react-i18next is to use Component composition to provide function t in the props, that is responsible for the translation. Example:
function Gator({ gator }) {
return (
<I18n>
{(t) => (
<div>
<label>{ t('name.label') }</label>
</div>
)}
</I18n>
)
}
What is the most compelling part of react-i18next is the babel-plugin-i18next-extract that can extract keys from the code, so they can be easily translated.
Another issue is, that we need to know all the translation of URLs up-front so we can decide about the language. This would require custom implementation on top of the react-i18next.
For the above reasons, we decided to go with a custom implementation of translation inspired by the react-i18next. That support not only static content but also dynamic content and URLs.
We adopt the use of t
function from react-i18next in order to be compatible with i18next.
The tLiteral
can be used to select value form a language string. For resource labels selectLabel
function should be used. This function is returned by useLabelApi
hook. The label API monitor loaded JSON resources for labels, but is also able to make a fetch request to obtain missing labels.
The tUrl
function can be used to get URL in given language together with provided query arguments.
The translation of static content and URL string must be provided as a part of a component registration using the register
function. It is recommended to create separate translation file per-view, with following structure:
{
"${language}": { }
}
import it into the component code:
import translations from "./publisher-list.json";
and use when registering the component:
register({
"url": "/publishers",
"name": "publishers-list.view",
"view": PublisherList,
"navigation": {
"cs": {
"/publishers": "/poskytovatelé",
},
"en": {
"/publishers": "/publishers",
},
},
"translations": translations,
});
From the example we can see that the navigation translation map is part of the component code.
We do not support the translation of keywords as it is not supported by DCAT-AP.