Translate my application#
Sepal tries to be as inclusive as possible. To do so the platform is translated in these languages:
English |
Français |
Español |
To reflect the diversity of language available, sepal_ui
embed an translator tool and help you manage your messages for different languages.
Update the main dictionary#
I assume that since you started using the lib you hard-coded in your files every single message displayed to the end user. The first thing you’ll need to do is to update the main dictionary as it will be your reference for the rest of the app.
If you removed every message relative to the default functions, your dictionary should look like the following :
# component/message/en/locale.json
{
"not_translated": "this message only exist in the en dict",
"app": {
"title": "My first module",
"footer": "The sky is the limit \u00a9 {}",
"drawer_item": {
"aoi": "AOI selection",
"about": "About"
}
}
}
Add new message#
Here you gather and add every message you display in your app.
For example if I want to display an error when no_aoi
is set i can add the following input in the dictionary:
# component/message/en/locale.json
{
"error": {
"no_aoi": "No AOI have been set, please provide one in step 1"
}
}
Danger
remember that JSON format does only accept “ (double quote)
and to call in any of your component you just need to import the ms Translator and use the names you gave as SimpleNameSpace
:
# component/tile.my_tile.py
from component.message import ms
print(ms.error.no_aoi)
Add message with parameter#
If you want to keep the possibility to use parameter in your message you can use the .format()
method of Python string.
Note
The format()
method formats the specified value(s) and insert them inside the string’s placeholder. The placeholder is defined using curly brackets: {}
.
Read more about the placeholders in the Placeholder official documentation. The format()
method returns the formatted string.
In our dictionary that could be use in the following way:
# component/message/en/locale.json
{
"error": {
"error_occurred": "The following error occurred: {}"
}
}
and call it in your components for example in a try/Except statement :
# component/tile/my_tile.py
try:
# do stuff
except Exception as e:
print(ms.error.error_occurred.format(e))
Update the translated dictionaries#
Note
If a key is missing in the target language dictionary, the Translator
object (ms
) will automatically fallback to the “en” key in order to avoid error or non displayed messages
Automatic#
If your application is part of the OpenForis initiative and hosted on SEPAL, you can request to add your project to the Pontoon application list. Pontoon is an open-source translation solution that will deal with the trouble of creating the files and keep the keys updated. To learn more, please see their documentation. From the developer’s side you’ll need to add the folder corresponding to the language you want to support and open a request for a new project in our issue tracker.
Note
The sepal-ui
keys for built-in components are managed on this application.
Important
Pontoon application doesn’t support nested list in the .json
file and only provides support for named keys. If you really need to have a nested list in your .json
file, then you need to change your message key. Let’s take the following file:
# component/message/en/locale.json
{
"paragraph": [
"I'm a multiline",
"paragraph."
]
}
Then you need to replace the list by a numbered dict using string integer as keys:
# component/message/en/locale.json
{
"paragraph": {
"0": "I'm a multiline",
"1": "paragraph."
}
}
This is compatible with pontoon and can be called in your file as follows:
# component/scripts/my_script.py
from component.message import cm
print(cm.paragraph[0])
print(cm.paragraph[1])
Manual update#
If this is the first time you translate your app, the easiest way is to simply copy/paste all the English dictionary (en/locale.json
) into the target one (fr/locale.json
or es/locale.json
) and replace all the message with their accurate translation.
If it’s not the first translation you make, you don’t want to erase all you’re already translated message. You only want to update the dictionary with the new key.
To pinpoint the missing keys you can use your memory or one of the Translator
methods.
Open the component/message/test_translation.ipynb
notebook. change the locale
variable into your target language. Then run all cells. The last one will display all the missing keys in the dictionary hierarchy.
# component/message/test_translation.ipynb
from pathlib import Path
from sepal_ui.translator import Translator
# select the language you want to test
locale = 'fr'
# normally there is only one key lissing ('not_tranlated') in the default module
# at the root of the file
print(ms.missing_keys())
>>>>> root['not_translated']
Once your output message is “All messages are translated” it means that all the dictionaries have the same keys and the same shape. if someone open your application in another language the translated message will be used instead of the English one.