Internationalization (i18n)

SINCE VERSION 9.0

What is Internationalization (i18n)?

Internationalization (often abbreviated as i18n, where "18" stands for the number of letters between the first 'i' and the last 'n' in "internationalization") refers to the process of designing and developing a software application so that it can be easily adapted to various languages and regions without requiring engineering changes to the source code. This approach allows the same software to be used globally, supporting multiple languages, character sets, and cultural conventions.

How does it work in PIPEFORCE?

Enable i18n per app

Because of performance reasons, customized i18n on app level is disabled by default.

In order to enable it, you have to set "i18n": true in your app config. For example:

{ "title": "My app", "i18n": true }

Language key (locale) detection

Whenever the UI is loaded in the portal, the application will in first step check for the currently selected language key (= locale) in this order (first finding wins):

  1. There is a request parameter locale (for example ?locale=en).

  2. The currently logged-in user has the attribute locale set in IAM (for example locale:en).

  3. The default language of the browser is used.

i18n URI (key)

After the locale was detected, it will be used to translate all i18n URIs in the UI having a format like this:

$uri:i18n:<app>/<context>/<key>
  • <app>
    Is optional and represents the name of the app which contains the i18n translation messages. If missing, the io.pipeforce.common app will be used as default.

  • <context>
    Represents a specific group of translation messages. This way, messages can be better organized. Is optional for common i18n keys and If missing, the name portal is used here. For app specific i18n keys, the context is mandatory and must be individually given.

  • <key>
    The key of the translation message.

Let’s assume for example an i18n URI like this:

$uri:i18n:com.acme.myapp/form/hello_world

This example defines these sections:

  • <app> = com.acme.myapp

  • <context> = form (mandatory since this i18n key is app specific)

  • <key> = hello_world

Here is another example with key only (no app and no context are given):

This example defines these sections:

  • <app> = io.pipeforce.common (default app if none is given)

  • <context> = portal (default context name if none is given)

  • <key> = hello_world

And some last example with context and key but no app is given:

This example defines these sections:

  • <app> = io.pipeforce.common (default app since none is given)

  • <context> = form (default context name since none is given)

  • <key> = hello_world

i18n message resources

The translation (i18n) messages are defined in JSON format having a simple key-value structure:

And the file name of the JSON is the same as the locale of the language.

For example de.json:

For example en.json:

These i18n JSON properties are stored inside the same app, they belong to, below the i18n folder. For example:

  • global/

    • app/

      • com.acme.myapp/

        • i18n/

          • default-de.json

          • default-en.json

In this example, the i18n URI $uri:i18n:com.acme.myapp/default/hello_world with a detected locale of de would finally return the translated text Hello World to be displayed in the UI.

Using a context, you can group multiple i18n message JSONs in a structured way. Lets assume we will have the two custom groups form and report, then we could have a structure of i18n messages in the app like this:

  • global/

    • app/

      • com.acme.myapp/

        • i18n/

          • form-de.json

          • form-en.json

          • report-de.json

          • report-en.json

Inside the form-* JSON properties, all translations for all forms could be placed and inside report-* JSON properties all translations related to reportings could be placed. Whether you use contexts and how you name those contexts (groups) is up to you.

For example, the i18n URI $uri:i18n:com.acme.myapp/form/hello_world with a detected locale of de would expect the i18n translation to reside inside the property global/app/com.acme.myapp/i18n/form-de.json with a key-value-pair in it like this:

The i18n.message command

In order to return the messages for a given app, context and locale via remote API call or inside a data pipeline, you can use the command i18n.message. This command is also used in the portal UI.

The commands supports these parameters:

Parameter

Description

Parameter

Description

app

The name of the app to load the messages from inside its i18n folder. If null or empty, the default io.pipeforce.common will be used.

context

The context name to be used to select the messages inside the i18n folder. If null or empty, the value default will be used.

locale

The language locale to be used. If null or empty, the value en will be used as default.

For example when calling the command i18n.messages like this:

… it will try to load the messages from a JSON property global/app/com.acme.myapp/i18n/portal-en

It will load the JSON from this property and embed it into a JSON envelope.

The resulting JSON document, returned by the command i18n.messages will then look similar to this:

In case no specific locale message could be found, the message from the en resource will be returned as default.

In case there is also no i18n key in the default en resource, the key itself will be returned as translation text. No error.

Frontend locations supported for i18n

In case i18n is enabled in your app, then in these frontend resource locations you can use custom i18n URIs like $uri:i18:<app>/<context>/<key> so they will be automatically replaced by the translated text depending on currently selected locale.

App Config

You can translate:

  • The title of the app

  • The description of the app

Example:

Form Schema

You can translate:

  • The title of a field

  • The description of a field

Example:

Form Config

You can translate:

  • The title of the form

  • The description of the form

  • Validation Messages

Example:

List Config

You can translate:

  • The title of the list

  • The description of the list

Example:

Workflow and Task Names

You can translate:

  • The display name of the workflow

  • The display name of a task

Task Name

In order to translate the name of a workflow task, you have to specify the i18n URI in the first line of the description of the task as this example shows:

image-20240424-145624.png

Everywhere in the UI where this task is displayed (for example in the task list), the translation for the task name is shown depending on the currently active locale.

Workflow Name

If you want to translate the name of a workflow, you have to create a i18n messages property of type application/json using this path:

Replace <appName> by the name where the workflow property resides in.

Replace <commonWfName> by the name of the workflow, which is currently shown in UI and you would like to provide a translation for.

Replace <locale> by the locale key (for example en or de) of the translation you would like to provide.

For example:

Place the i18n messages JSON inside this property having the field processDefinitionName:

Whenever the workflow is loaded or shown in the UI using the command workflow.process.find or workflow.definition.details.find with parameter locale, the translated name will be picked-up and returned with the response.

In case no translation message or translation field exists for a given language, the common workflow name will be returned instead.

Common i18n messages (Portal)

There are global (common) i18n messages which are used inside the portal across all apps. These i18n resources are located inside global/app/io.pipeforce.common/i18n.

In case an i18n key doesn’t contain an app name like this example, the translation will be searched inside the common path mentioned above:

In this example an i18n message resource like this is expected to exist (if locale=en or as fallback):

… with an key-value entry like this:

The translations for the portal UI are located at:

  • global/

    • app/

      • io.pipeforce.common/

        • i18n/

          • portal-de.json

          • portal-en.json