Internationalizing applications
Internationalizing applications
You can internationalize Zoweâ„¢ application plug-ins using Angular and React frameworks. Internationalized applications display in translated languages and include structures for ongoing translation updates.
The steps below use the Zowe Sample Angular Application and Zowe Sample React Application as examples. Your applications might have slightly different requirements, for example the React Sample Application requires the react-i18next library, but your application might require a different React library.
For detailed information on Angular or React, see their documentation. For detailed information on specific internationalization libraries, see their documentation. You can also reference the Sample Angular Application internationalization tutorial, and watch a video on how to internationalize your Angular application.
After you internationalize your application, you can view it by following steps in Changing the desktop language.
Internationalizing Angular applications​
Zowe applications that use the Angular framework depend on .xlf
formatted files to store static translated content and .json
files to store dynamic translated content. These files must be in the application's web/assets/i18n
folder at runtime. Each translated language will have its own file.
To internationalize an application, you must install Angular-compatible internationalization libraries. Be aware that libraries can be better suited to either static or dynamic HTML elements. The examples in this task use the ngx-i18nsupport library for static content and angular-l10n for dynamic content.
To internationalize Zowe Angular applications, take the following steps:
To install internationalization libraries, use the
npm
command, for example:npm install --save-dev ngx-i18nsupport
npm install --save-dev angular-l10nNote
--save-dev
commits the library to the application's required libraries list for future use.To support the CLI tools and to control output, create a
webClient/tsconfig.i18n.json
typescript file and add the following content:{
"extends": "../../zlux-app-manager/virtual-desktop/plugin-config/tsconfig.ngx-i18n.json",
"include": [
"./src"
],
"compilerOptions": {
"outDir": "./src/assets/i18n",
"skipLibCheck": true
}
}For example, see this file in the Sample Angular Application.
In the static elements in your HTML files, tag translatable content with the i18n attribute within an Angular template, for example:
<div>
<p i18n="welcome message@@welcome">Welcome</p>
</div>The attribute should include a message ID, for example the
@@welcome
above.To configure static translation builds, take the following steps:
a. In the
webClient/package.json
script, add the following line:"i18n": "ng-xi18n -p tsconfig.i18n.json --i18nFormat=xlf --outFile=messages.xlf && xliffmerge -p xliffmerge.json",
b. In the in
webClient
directory, create axliffmerge.json
file, add the following content, and specify the codes for each language you will translate in thelanguages
parameter:{
"xliffmergeOptions": {
"srcDir": "src/assets/i18n",
"genDir": "src/assets/i18n",
"i18nFile": "messages.xlf",
"i18nBaseFile": "messages",
"i18nFormat": "xlf",
"encoding": "UTF-8",
"defaultLanguage": "en",
"languages": ["fr","ru"],
"useSourceAsTarget": true
}
}When you run the i18n script, it reads this file and generates a
messages.[lang].xlf
file in thesrc/assets/i18n directory
for each language specified in thelanguages
parameter. Each file contains the untranslated text from the i18n-tagged HTML elements.Run the following command to run the i18n script and extract i18n tagged HTML elements to
.xlf
files:npm run i18n
Note If you change static translated content, you must run the
npm run build
command to build the application, and then re-run thenpm run i18n
command to extract the tagged content again.In each
.xlf
file, replacetarget
element strings with translated versions of thesource
element strings. For example:<source>App Request Test</source>
<target>Test de Demande à l'App</target>Run the following command to rebuild the application:
npm run build
When you switch the Zowe Desktop to one of the application's translated languages, the application displays the translated strings.
For dynamic translated content, follow these steps:
a. Import and utilize angular-l10n objects within an Angular component, for example:
import { LocaleService, TranslationService, Language } from 'angular-l10n';
Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [HelloService]
})
export class AppComponent {
@Language() lang: string;
public myDynamicMessage:string = '';
constructor(
public locale: LocaleService,
public translation: TranslationService) { }
sayHello() {
this.myDynamicMessage = `${this.translation.translate('my_message')}`;
});
}
}b. In the related Angular template, you can implement
myDynamicMessage
as an ordinary substitutable string, for example:<div>
<textarea class="response" placeholder="Response" i18n-placeholder="@@myStaticPlaceholder" >{{myDynamicMessage}}</textarea>
</div>Create logic to copy the translation files to the
web/assets
directory during the webpack process, for example in the sample application, the following JavaScript in thecopy-webpack-plugin
file copies the files:var config = {
'entry': [
path.resolve(__dirname, './src/plugin.ts')
],
'output': {
'path': path.resolve(__dirname, '../web'),
'filename': 'main.js',
},
'plugins': [
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, './src/assets'),
to: path.resolve('../web/assets')
}
])
]
};Note: Do not edit files in the
web/assets/i18n
directory. They are overwritten by each build.
Internationalizing React applications​
To internationalize Zowe applications using the React framework, take the following steps:
Note: These examples use the recommended react-i18next library, which does not differentiate between dynamic and static content, and unlike the Angular steps above does not require a separate build process.
To install the React library, run the following command:
npm install --save-dev react-i18next
In the directory that contains your
index.js
file, create ani18n.js
file and add the translated content, for example:import i18n from "i18next";
import { initReactI18next } from "react-i18next";
// the translations
// (tip move them in a JSON file and import them)
const resources = {
en: {
translation: {
"Welcome to React": "Welcome to React and react-i18next"
}
}
};
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources,
lng: "en",
keySeparator: false, // we do not use keys in form messages.welcome
interpolation: {
escapeValue: false // react already safes from xss
}
});
export default i18n;Import the
i18n
file from the previous step intoindex.js
file so that you can use it elsewhere, for example:import React, { Component } from "react";
import ReactDOM from "react-dom";
import './i18n';
import App from './App';
// append app to dom
ReactDOM.render(
<App />,
document.getElementById("root")
);To internationalize a component, include the
useTranslation
hook and reference it to substitute translation keys with their translated values. For example:import React from 'react';
// the hook
import { useTranslation } from 'react-i18next';
function MyComponent () {
const { t, i18n } = useTranslation(); // use
return <h1>{t('Welcome to React')}</h1>
}
Internationalizing application desktop titles​
To display the translated application name and description in the Desktop, take the following steps:
For each language, create a
pluginDefinition.i18n.<lang_code>.json
file. For example, for German create apluginDefinition.i18n.de.json
file.Place the
.json
files in theweb/assets/i18n
directory.Translate the
pluginShortNameKey
anddescriptionKey
values in the application'spluginDefinition.json
file. For example, for the file below you would translate the values"sampleangular"
and"sampleangulardescription"
:{
"identifier": "org.zowe.zlux.sample.angular",
"apiVersion": "1.0.0",
"pluginVersion": "1.1.0",
"pluginType": "application",
"webContent": {
"framework": "angular2",
"launchDefinition": {
"pluginShortNameKey": "sampleangular",
"pluginShortNameDefault": "Angular Sample",
"imageSrc": "assets/icon.png"
},
"descriptionKey": "sampleangulardescription",
"descriptionDefault": "Sample App Showcasing Angular Adapter",Add the translated values to the translation file. For example, the German translation file example,
pluginDefinition.i18n.de.json
, would look like this:{
"sampleangular": "Beispiel Angular",
"sampleangulardescription": "Beispiel Angular Anwendung"
}Create logic to copy the translation files to the
web/assets
directory during the webpack process. For example, in the Sample Angular Application the following JavaScript in thewebClient/webpack.config.js
file copies files to theweb/assets
directory:var config = {
'entry': [
path.resolve(__dirname, './src/plugin.ts')
],
'output': {
'path': path.resolve(__dirname, '../web'),
'filename': 'main.js',
},
'plugins': [
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, './src/assets'),
to: path.resolve('../web/assets')
}
])
]
};