I18n Text & Translation

Texts that need to be locale-specific, translated and/or reused across multiple locations can be defined here as attributes in global i18n models. The attributes can then be accessed through bindings in the App Designer and relevant Cockpit artifacts, as well as from JavaScript or TypeScript code.

There is also the possibility to create app-specific models, described in the App Designer documentation.

A note on locale languages

Locales typically support language and REGION, either using language by itself, or combined on the format language_REGION.

  • language as a two character lowercase language code from ISO 639-1, like en for English, no for Norwegian, and ja for Japanese.

  • REGION as a two character uppercase country code from ISO 3166-1 alpha 2, like US for the United States of America, CH for Switzerland, and CN for China.

Valid examples would be en for English and en_US for American English specifically, or de for German and de_CH for Swiss German.

Neptune enforces no restriction on locales, so feel free to specify any locale your users need and their browser software supports, like tlh for klingon (from ISO 639-2) or elvish, should the need arise.

Models

A global model is the top grouping of texts.

i18n model

Identifier for the model, namespaces can be used as needed

Description

Description of the models use

Fallback Locale

The locale used for the default translations

Attributes

Attributes in a model are the definitions of the text attributes to be made available.

Attribute

Attribute identifier. Lower camel case is advised but the choice is yours.

Base text

Attribute text set by developer. Numbered placeholders for parameters can be included in the format {0}, {1}, etc, allowing for re-ordering at translation. Please note that numbering starts at 0.

Annotation type

To provide context for translation, the annotation type consists of a predefined classification.

Length restriction

An optional length restriction advice to provide more context for translation

Description

An optional descriptive text to provide more context for translation and usage

Attribute hierarchy

Attributes can be placed in a hierarchical structure by creating sub attributes. For example, a if a buttonTexts attribute exists, sub elements cancel and ok, can be created, leading to having buttonTexts.cancel and buttonTexts.ok available in a convenient structure.

Translation

There will always be at least the fallback language available but additional supported languages can be maintained as well, as needed.

It is the text from the translation that is used as the attribute value. Changing the base text on the attribute will not be reflected in the attribute value when the attribute is used.

Translations may be done directly in the Cockpit tool, either manually or using Google Translate functionality. Another viable option is to export the attributes to a resource bundle zip, handle the translations in an external tool, and then import the data again. This artifact is also supported by our abapGit extension.

Export/Import

By using the export to file functionality, a zip file containing the main parameter definition and selected translations will be generated.

Importing updated files back into the model will adjust the attributes and translations accordingly.

Where-used

The where-used count and list identify static binding to the model attributes, not custom usage in JavaScript or TypeScript.

Enhancements

An enhancement framework exists that allows for enhancing both global and app-specific models in order to specify translations in an additional language or to change existing translations. This is typically useful when you are not allowed to change the main model, like in relation to models supplied by Neptune Software or a partner solution, but it is also possible to enhance your own models should the need arise.

Accessing global models

In the examples below, imagine a global model named globalTexts containing attributes textHello and textHi greetingText.

Apps via binding

The binding dialog will have available all global models and attributes for selection. The binding format is {i18n.model name>attribute name}, like {i18n.globalTexts>textHello}.

This format can also be used in expression bindings and when using Bind and Concatenate functionality.

JavaScript/TypeScript

When global models are used in bindings, this is automatically detected and all required models are loaded and made available both for bindings and for use in code.

However, when only using a global model from JavaScript or TypeScript code, it is required to explicitly load the model using the AppCache.buildGlobalResourceBundles function. This function takes an array of global model identifiers as parameter and returns an array of promises for their loading.

To get the text value of an attribute, the function AppCache.getText is available, taking the i18n binding string as parameter and returning the text value.

Example code to load the global model globalTexts and getting text values:

const loadingModels = AppCache.buildGlobalResourceBundles(["i18n.globalTexts"]);
Promise.all(loadingModels).then(() => {
    const hello = AppCache.getText("{i18n.globalTexts>textHello}");
    const hi = AppCache.getText("{i18n.globalTexts>textHi}");
    console.log(`${hello}, ${hi}!`);
});

Use the promises to make sure the models are loaded, but once they are they will be available for use in AppCache.getText

Text placeholders

The AppCache.getText function also supports replacing placeholders in texts by supplying additional parameters in the corresponding order. If no replacement is specified, the placeholder will be left as-is.

For example, the following code

console.log(AppCache.getText("{i18n.globalTexts>greetingText}"));
console.log(AppCache.getText("{i18n.globalTexts>greetingText}"),
    "my friend", "internationalization" );

would output the two lines as follows:

Hello {0}! The word of the day is {1}
Hello my friend! The word of the day is internationalization