Skip to main content

Translation

Translation files

Translation files are located in the ./translation directory of the app configuration.

By default, the app will use the default.json file located in this directory but additional files can be created for each language, e.g. a file named de.json for a German translation file.

Each translation file must have the following data structure, where name should always be the same value as the file name of your translation, while content is an object of simple key-value pairs for each translatable string in your app.

Example of a default.json file

{
"name": "default",
"content": {
"title": "My App",
"mainLabel": "Welcome to My App."
}
}
tip

It is highly recommended that you sort your translation file alphanumerically and optionally prefix your translation keys depending on where you intend to use them in the app.

In the following example, all translations for the home screen have been prefixed with home while those for the settings screen have been prefixed with settings. Additionally, all translations are sorted alphanumerically. Depending on your code editor or IDE, this feature might already be built-in or available from extensions (i.e. for VS Code, the Sort JSON objects extension allows the sorting of several selected lines by opening the command palette (CTRL+P or ⌘+P) and executing Sort JSON (by alphanum)).

Example of a sorted translation file

{
"name": "default",
"content": {
"homeHeader": "My App",
"homeSubtitle": "Welcome to My App",
"settingsHeader": "Settings",
"settingsSubstitle": "This is an example description."
}
}
Directory and translation file structure

Screenshot of the final directory and translation file structure.

Using translations

Translations can be applied throughout your app by using the $lang()$ keyword. By copying and pasting your JSON key between the brackets, the entire resulting keyword will automatically be translated to the respective JSON value, i.e. $lang(homeSubtitle)$ will be translated to Welcome to My App.

Example 1, in a layout

In this example, the translations are used directly in a layout. Since translations are static anyway, there is no need to put them in a client template:

{
"name": "c_myLayout",
"layers": [
{
"type": "text",
"value": "$lang(mainLabel)$",
"constraints": [...]
}
]
}

Example 2, in a database query and client template

Sometimes it may be more useful to directly evaluate your translation strings in an SQLite query, i.e. when fetching the current day of the week, as demonstrated in the following example:

{
"table": {
"name": "myTable",
"fields": [...],
"primaryKey": [...],
"queries": {
"myQuery": {
"custom": "SELECT iif(strftime('%w') IN ('0', '6'), '$lang(weekend)$', '$lang(weekday)$') AS typeOfDay FROM myTable"
}
}
}
...
}

The selected field may then be used in a client template as follows:

{
"name": "myClientTemplate",
"content": {
"content": {
"mainLabelText": {
"value": "{{typeOfDay}}"
}
}
}
}

Setting the current app language

Switching the app to a different language can be achieved by setting the AF_SETTING_LANGUAGE userSetting. By default, this setting may be unset but can be set to any value just like any other userSetting. For example, setting it to en if you wish to change the app's language to English will cause the app to look for an en.json file in the translations directory and apply the respective translation strings from that file.

note

Setting the AF_SETTING_LANGUAGE userSetting to an unsupported language (i.e. to fr when no fr.json file exists) will cause the app to automatically revert to the default language (default.json).

Example:

{
"type": "setValueToUserSetting",
"params": {
"key": "AF_SETTING_LANGUAGE",
"value": "en"
}
}

Getting the current app language

In some cases, you may want to read the currently used language in order to display it in your app or submit it to an API, as illustrated by the following examples.

Example 1, as a dynamic value

Here, the current app language is directly fetched and used as a value for a text layer, so it can be displayed in the app:

{
"type": "text",
"value": {
"context": "userSetting",
"field": "AF_SETTING_LANGUAGE"
},
"constraints": [...]
}

Example 2, as a dynamic parameter

In this example, the current app language is fetched from the userSettings as a dynamic param, stored in a field named language and then submitted in the body of a POST-request:

{
"type": "request",
"leadingDelimiter": "{$",
"trailingDelimiter": "$}",
"dynamicParams": {
"language": {
"context": "userSetting",
"field": "AF_SETTING_LANGUAGE"
}
},
"params": {
"method": "POST",
"url": "https://example.com",
"post": {
"language": "{$language$}"
}
}
},

Toggling/switching between two or more languages

If you wish to toggle your app's language between multiple languages or just want to execute different actions based on different languages, you may do so by using a switch action, if action or directly wrapping the actions in an event and evaluating the AF_SETTING_LANGUAGE userSetting from there:

Example 1, using a switch action

This is ideal if you want to support more than two languages, since the cases field can be easily extended:

{
"type": "switch",
"params": {
"value": {
"context": "userSetting",
"field": "AF_SETTING_LANGUAGE"
},
"cases": {
"de": [
{
"type": "setValueToUserSetting",
"params": {
"key": "AF_SETTING_LANGUAGE",
"value": "en"
}
}
],
"_default": [
{
"type": "setValueToUserSetting",
"params": {
"key": "AF_SETTING_LANGUAGE",
"value": "de"
}
}
]
}
}
}

Example 2, using an if action and by evaluating a condition

{
"type": "if",
"params": {
"condition": {
"left": {
"context": "userSetting",
"field": "AF_SETTING_LANGUAGE"
},
"mode": "equal",
"right": {
"value": "de"
}
},
"then": [
{
"type": "setValueToUserSetting",
"params": {
"key": "AF_SETTING_LANGUAGE",
"value": "en"
}
}
],
"else": [
{
"type": "setValueToUserSetting",
"params": {
"key": "AF_SETTING_LANGUAGE",
"value": "de"
}
}
]
}
}

Example 3, directly inside an event and by evaluating a condition

{
"name": "myEvent",
"content": {
"type": "myEvent",
"condition": {
"left": {
"context": "userSetting",
"field": "AF_SETTING_LANGUAGE"
},
"mode": "equal",
"right": {
"value": "de"
}
},
"actions": [
{
"type": "setValueToUserSetting",
"params": {
"key": "AF_SETTING_LANGUAGE",
"value": "en"
}
}
],
"elseActions": [
{
"type": "setValueToUserSetting",
"params": {
"key": "AF_SETTING_LANGUAGE",
"value": "de"
}
}
]
}
}