Skip to content

Commit

Permalink
docs(i18n): make translation guide more explicit (apache#18254)
Browse files Browse the repository at this point in the history
  • Loading branch information
villebro authored and bwang221 committed Feb 10, 2022
1 parent 4314129 commit 9ad6bb9
Showing 1 changed file with 67 additions and 22 deletions.
89 changes: 67 additions & 22 deletions docs/docs/Contributing/translations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ version: 1

## Translating

We use [Babel](http://babel.pocoo.org/en/latest/) to translate Superset.
In Python files, we import the magic `_` function using:
We use [Flask-Babel](https://flask-babel.tkte.ch/) to translate Superset.
In Python files, we use the following
[translation functions](https://flask-babel.tkte.ch/#using-translations) from
`Flask-Babel`:
- `gettext` and `lazy_gettext` (usually aliased to `_`): for translating singular
strings.
- `ngettext`: for translating strings that might become plural.

```python
from flask_babel import lazy_gettext as _
```

then wrap our translatable strings with it, e.g. `_('Translate me')`.
then wrap the 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.

Expand Down Expand Up @@ -43,29 +48,80 @@ LANGUAGES = {
}
```

### Creating a new language dictionary

First check if the language code for your target language already exists. Check if the
[two letter ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
for your target language already exists in the `superset/translations` directory:

```bash
ls superset/translations | grep -E "^[a-z]{2}\/"
```

If your language already has a pre-existing translation, skip to the next section

The following languages are already supported by Flask AppBuilder, and will make it
easier to translate the application to your target language:
[Flask AppBuilder i18n documentation](https://flask-appbuilder.readthedocs.io/en/latest/i18n.html)

To create a dictionary for a new language, first make sure the necessary dependencies are installed:
```bash
pip install -r superset/translations/requirements.txt
```

Then run the following, where `LANGUAGE_CODE` is replaced with the language code for your target
language:

```bash
pybabel init -i superset/translations/messages.pot -d superset/translations -l LANGUAGE_CODE
```

For instance, to add a translation for Finnish (language code `fi`), run the following:

```bash
pybabel init -i superset/translations/messages.pot -d superset/translations -l fi
```

### Extracting new strings for translation

This step needs to be done every time application strings change. This happens fairly
frequently, so if you want to ensure that your translation has good coverage, this
step needs to be run fairly frequently and the updated strings merged to the upstream
codebase via PRs. To update the template file `superset/translations/messages.pot`
with current application strings, run the following command:

```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.
Do not forget to update this file with the appropriate license information.

### Updating language files

Run the following command to update the language files with the new extracted strings.

```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)
`superset/translation`, where there's one folder 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.
To perform the translation on MacOS, you can install `poedit` via Homebrew:

```bash
brew install poedit
```

After this, just start the `poedit` application and open the `messages.po` file. In the
case of the Finnish translation, this would be `superset/translations/fi/LC_MESSAGES/messages.po`.

### Applying translations

To make the translations available on the frontend, we need to convert the PO file into
a JSON file. To do this, we need to globally install the npm package `po2json`.

```bash
npm install -g po2json
Expand All @@ -84,20 +140,9 @@ 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.
Finally, 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).

0 comments on commit 9ad6bb9

Please sign in to comment.