--- title: Translating hide_title: true sidebar_position: 9 version: 1 --- ## Translating We use [Babel](http://babel.pocoo.org/en/latest/) to translate Superset. In Python files, we import the magic `_` function using: ```python from flask_babel import lazy_gettext as _ ``` then wrap our translatable strings with it, e.g. `_('Translate me')`. During extraction, string literals passed to `_` will be added to the generated `.po` file for each language for later translation. At runtime, the `_` function will return the translation of the given string for the current language, or the given string itself if no translation is available. In TypeScript/JavaScript, the technique is similar: we import `t` (simple translation), `tn` (translation containing a number). ```javascript import { t, tn } from "@superset-ui/translation"; ``` ### Enabling language selection Add the `LANGUAGES` variable to your `superset_config.py`. Having more than one option inside will add a language selection dropdown to the UI on the right side of the navigation bar. ```python LANGUAGES = { 'en': {'flag': 'us', 'name': 'English'}, 'fr': {'flag': 'fr', 'name': 'French'}, 'zh': {'flag': 'cn', 'name': 'Chinese'}, } ``` ### Extracting new strings for translation ```bash pybabel extract -F superset/translations/babel.cfg -o superset/translations/messages.pot -k _ -k __ -k t -k tn -k tct . ``` This will update the template file `superset/translations/messages.pot` with current application strings. Do not forget to update this file with the appropriate license information. ### Updating language files ```bash pybabel update -i superset/translations/messages.pot -d superset/translations --ignore-obsolete ``` This will update language files with the new extracted strings. You can then translate the strings gathered in files located under `superset/translation`, where there's one per language. You can use [Poedit](https://poedit.net/features) to translate the `po` file more conveniently. There are some [tutorials in the wiki](https://wiki.lxde.org/en/Translate_*.po_files_with_Poedit). In the case of JS translation, we need to convert the PO file into a JSON file, and we need the global download of the npm package po2json. ```bash npm install -g po2json ``` To convert all PO files to formatted JSON files you can use the `po2json.sh` script. ```bash ./scripts/po2json.sh ``` If you get errors running `po2json`, you might be running the Ubuntu package with the same name, rather than the Node.js package (they have a different format for the arguments). If there is a conflict, you may need to update your `PATH` environment variable or fully qualify the executable path (e.g. `/usr/local/bin/po2json` instead of `po2json`). If you get a lot of `[null,***]` in `messages.json`, just delete all the `null,`. For example, `"year":["年"]` is correct while `"year":[null,"年"]`is incorrect. For the translations to take effect we need to compile translation catalogs into binary MO files. ```bash pybabel compile -d superset/translations ``` ### Creating a new language dictionary To create a dictionary for a new language, run the following, where `LANGUAGE_CODE` is replaced with the language code for your target language, e.g. `es` (see [Flask AppBuilder i18n documentation](https://flask-appbuilder.readthedocs.io/en/latest/i18n.html) for more details): ```bash pip install -r superset/translations/requirements.txt pybabel init -i superset/translations/messages.pot -d superset/translations -l LANGUAGE_CODE ``` Then, [extract strings for the new language](#extracting-new-strings-for-translation).