This example shows you how to implement a central translation dictionary in Luigi Core.
Luigi Core provides a generic API for i18n. We will write a custom translation provider that gathers translation strings from static files hosted either on Luigi Core or on the micro-frontend side.
Create a internationalization provider that will expose the getTranslation
method for settings.customTranslationImplementation
configuration.
File i18n-provider.js
:
class I18nProvider {
init() {
// Could also be an Ajax based implementation.
this.translationTable = {
"en": {
"COMMON": {
"SELECT_ENVIRONMENT": "Select EN Environment ..."
},
"LABEL1": 'Label EN',
"ENVIRONMENT_NUM": "Environment {num} EN"
},
"de": {
"COMMON": {
"SELECT_ENVIRONMENT": "Select DE Environment ..."
},
"LABEL1": "Label DE",
"ENVIRONMENT_NUM": "Environment {num} DE"
},
};
return Promise.resolve();
}
afterInit() {
this.currentLanguage = Luigi.i18n().getCurrentLocale();
Luigi.i18n().addCurrentLocaleChangeListener((locale) => {
this.currentLanguage = locale;
});
}
// This function will be used by Luigi Core for translation
getTranslation(key, interpolations = undefined, locale = undefined) {
if (!key) return '';
this.currentLanguage = locale || this.currentLanguage || Luigi.i18n().getCurrentLocale();
const result = this.findTranslation(
key,
this.translationTable[this.currentLanguage],
interpolations
);
return result ? result : key;
}
/**
* @private
* Finds the translated value based on given key.
* @param {string} key key to be translated
* @param {*} obj translation table
*/
findTranslation(key, obj, interpolations) {
let splitted = key.split('.');
for (let i = 0; i < splitted.length; i++) {
let key = splitted[i];
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object') {
obj = obj[key];
} else {
if (interpolations)
return this.findInterpolations(obj[key], interpolations);
return obj[key];
}
}
}
/**
* @private
* Replaces values that are defiend in translation strings
* @param {string} key key to be translated
* @param {*} interpolations translation table
* @example
* findInterpolations('Environment {num}', {num: 1})
*/
findInterpolations(value, interpolations) {
Object.keys(interpolations).forEach(item => {
value = value.replace(
new RegExp('{' + EscapingHelpers.escapeKeyForRegexp(item) + '}', 'gi'),
interpolations[item]
);
});
return value;
}
}
export const i18nProvider = new I18nProvider();
Specify settings.customTranslationImplementation
:
import { i18nProvider } from './i18n-provider';
const coreConfig = {
// ... partial setting ...
settings: {
customTranslationImplementation = i18nProvider
}
}
Since translations may come from external sources, loaded asynchronously, you should load them ahead before Luigi.setConfig
is triggered. Be aware that other Luigi Core API functionality is only available after initialization.
import { i18nProvider } from './i18n-provider';
const coreConfig = { /* the whole configuration */ }
i18nProvider.init().then(() => {
Luigi.setConfig(coreConfig);
})
Specify customTranslationImplementation
:
import { i18nProvider } from './i18n-provider';
const coreConfig = {
// ... partial setting ...
lifecycleHooks: {
luigiAfterInit: () => {
i18nProvider.afterInit();
}
}
}
You can use the translation keys as node.label
, on other labels in the configuration or programmatically.
const coreConfig = {
navigation: {
nodes: [{
label: 'MF1.LABEL1',
pathSegment: 'overview',
// ...
}],
contextSwitcher: {
defaultLabel: 'COMMON.SELECT_ENVIRONMENT',
options: () => [1,2,3,4,5].map(num => ({
label: Luigi.i18n().getTranslation('ENVIRONMENT_NUM', {num}),
pathValue: 'env' + num
}))
},
}
}
Most of the time, the language selection will be done in a micro-frontend, like user profile. To be able to use LuigiClient.uxManager().setCurrentLocale function, we need to add locale change permissions on the node level.
const coreConfig = {
navigation: {
nodes: [{
label: 'User Profile',
pathSegment: 'profile',
viewUrl: '/profile',
clientPermissions: {
changeCurrentLocale: true
}
}],
In the profile micro-frontend we can then set the desired language:
LuigiClient.uxManager().setCurrentLocale('en');
To read the current active language, use LuigiClient.uxManager().getCurrentLocale. Like all state related functions, it should not be called before Luigi initialization.
function updateCurrentLanguage() {
currentLanguage = LuigiClient.uxManager().getCurrentLocale();
}
LuigiClient.addInitListener(updateCurrentLanguage);
LuigiClient.addContextUpdateListener(updateCurrentLanguage);