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, likeen
for English,no
for Norwegian, andja
for Japanese. -
REGION
as a two character uppercase country code from ISO 3166-1 alpha 2, likeUS
for the United States of America,CH
for Switzerland, andCN
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.
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