Translating XM Solutions
Once you’ve created a solution in your primary language, you may want to get it translated into other languages.
If you would like to join the early access program for XM Solution Plugins, then please let us know by taking this survey.
This feature is in Early Access and is not yet generally available. Functionality, APIs, and documentation may change before general availability.
This page includes step-by-step instructions for translating a XM Solution and some advanced details in case you need something more specific than the standard translation process provides.
Translating an XM Solution is different from translating your plugin. This will help you translate the contents of your XM Solution, but you need to translate your extension and plugin separately. Look at this page for assistance.
Step-by-Step Instructions
Step 1: Add languages
The first step to adding translations is to decide what languages you would like to add translations for and add their language codes to your config.json file.
To get a valid language code, first use the solution add-lang --list to get a list of languages. It will give you a table that looks something like this:
+--------------------------------------------+
| Code | Language |
+--------------------------------------------+
| ar | Arabic |
| as | Assamese |
| az | Azeri/Azerbaijani (Latin script) |
| be | Belarusian |
| bg | Bulgarian |
| bn | Bengali |
| bs | Bosnian |
| ca | Catalan |
| ceb | Cebuano |
| ckb | Kurdish (Sorani) |
| cnr | Montenegrin |
| cs | Czech |
| cy | Welsh |
| da | Danish |
| de | German |
| el | Greek |
| en | English |
...
Notice the language code is on the left and the name of the Language is on the right. Now that you have this information, the easiest way to add a language is to use the command solution add-lang language_1 language_2 where language_1 and language_2 are space separated language names or language codes. For example, the following commands are equivalent:
solution add-lang Bengali Bosnian
solution add-lang bn bs
The add-lang command is a shortcut that will modify the list of available languages in the config.json file for you. If you prefer, you can modify that file directly instead. You'll see a list of languages that looks something like this:
"languages": [
"en",
"es"
],
You can add any valid language code to that languages array directly.
Never remove your baseLanguage from the Languages array. By default, the baseLanguage is always "en". More information on base languages in the advanced guide below.
Step 2: Generate Translation Files
Run solution translation-extract to generate the translation files you'll be working with. After running the command, you should see files like this in your plugin:
├── translations
│ ├── en.json
│ └── es.json
Step 3: Add translations
Translating strings
First, take a look at the files in the "translations" folder. If you just ran the translation-extract command for the first time, then all these files will be identical and they will look something like this:
{
"strings": {
"Resources/trigger.json": {
"$.payload.Name": {
"context": "Name of the trigger resource",
"text": "New Workflow"
}
},
"catalogConfig.json": {
"$.description": {
"context": "description",
"text": "Catalog configuration figure for solution plugin"
},
...
This is just a json representation of all the strings that need to be translated. Notice that the strings are grouped by file, and that the key for each translation string is the path of how to get to that string in the file it came from.
To translate strings in these files, all you need to do is edit the "text" field for each of them. The "context" string is there to help you know where the string is from, so you can translate it more easily. When you're done, the "text" fields in each file will all be in the language corresponding to the language code of the file name.
The keys are used to replace text later, so changing them will cause some translations to be missed when the build command tries to put the translated values into your XM Solution later.
This feature is in Early Access and is not yet generally available. Functionality, APIs, and documentation may change before general availability.
Translating Assets
Translating markdown files and images for your catalogConfig.json file follows a different process from normal translations, because you'll be swapping entire files instead of strings within the file. You'll notice in your translations files (e.g. translations/en.json) that you'll have entries like this:
"catalogConfig.json": {
"$.assetMap.catalogIcons[0]": {
"context": "File path to an icon to be shown in the Catalog.",
"text": "Assets/Survey_response.svg"
},
"$.assetMap.catalogIcons[1]": {
"context": "File path to an icon to be shown in the Catalog.",
"text": "Assets/Ticket.svg"
},
"$.assetMap.summaryMarkdown": {
"context": "File path to a markdown file to be shown in the Catalog sidebar.",
"text": "Assets/summary.md"
},
The "text" value of these entries is a file path instead of a string. If you want to have different asset files appear for different languages, then you need to add a new file somewhere in the src folder of your plugin and change the "text" field in the translation to point to it. You will probably always do that for all of your markdown files, but it may not be necessary for images.
File paths in your translation files are always relative paths from the src folder in your plugin.
This feature is in Early Access and is not yet generally available. Functionality, APIs, and documentation may change before general availability.
Step 4: Build your XM Solution
Once you're done with all of your translations, just run solution build again. This will automatically build your solution into all the languages you're supporting. You don't need to do anything else.
Advanced topics
Translations in JavaScript files
It is not currently possible to access translation strings in your JavaScript transformation files. For that reason, it is very strongly recommended to only use JavaScript to remove or modify things in the original resource. You should not use it to add new things into the resources, because there's no way for you to translate those additions.
Out of date translations
As you work on translating your XM Solution, you may get warnings like this from time to time:
[WARN] There is a chance your translations are out of date
[WARN] These files in src have been modified after running extract strings:[Assets/summary.md]
[WARN] Please make sure to rerun "solution translation-extract" if any src file changes were made
You see this warning message, because a resource file has changed, but you haven't extracted translations from it again. This may lead to confusing behavior if you've changed a string in the resource file, because you won't see the new string. Instead, you'll see the old string that's still in the translation file. Translation file strings always take priority over the strings in the resource.
Override Duplicates
To make translating a solution easier, duplicate strings are identified automatically and handled for you. It's only considered a duplicate if there is an exact text and context match for two strings. It's unlikely but possible that you have duplicate strings that you would rather not translate as duplicates. If that's the case, then you need to understand how duplicates are managed in the translations/.duplicateTranslations.json file in your plugin.
It will look something like this:
{
"strings": {
"file2.json": {
"itemName2": {
"context": "itemName",
"text": "$ref:#/strings/file1.json/itemName1"
},
},
}
It's a list of all the duplicate strings that have been removed, and it describes where the duplicate was found. In the example above you can see that an item with the key "itemName2" was found in "file2.json". That string is being replaced by the duplicate string found by the path in the "text" field.
Do not edit the .duplicateTranslations.json file. It's not necessary, and will just cause confusion.
If you need to override a string being treated as a duplicate, add the string back into the main translation file. For example, let's say that you have a duplicate string that works just fine in English, but you need it to appear differently in Japanese for some reason. Go to the translations/ja.json file and add the string into the file.
If you wanted the example above not to be treated as a duplicate, then you would add an entry that looks like this to the languages you need to override it in.
"file2.json": {
"itemName2": {
"context": "itemName",
"text": "Don't overwrite me with what seemed like a duplicate!"
},
},
In general, you can follow these steps to fix a string being incorrectly treated as a duplicate:
- Identify the bad string in your testing.
- Find the string in your resource file.
- Look for the matching entry for that string in the
.duplicateTRanslations.jsonfile. - Copy the entry and paste it into the language file you would like to override it for. Remember you can use the command
solution add-lang --listto get a list of supported languages and their language codes. - Build your Solution.
solution build
Changing your base language
Right now, the xmt-cli is only supported in English and is expecting that all extensions/plugins are written in English as their main language. However, Solutions are capable of having a different base language if you're fine with some possible inconsistencies at the extension and plugin level.
To change your base language, you just need to switch out a couple of language fields in your config.json file. You will have something like this in that file to start:
"baseLanguage": "en",
"languages": [
"en"
],
If you're switching your base language away from English (en), replace "en" in the baseLanguage and languages fields with the language code you'd like to use instead.