docs/source/extension/internationalization.md
% Copyright (c) Jupyter Development Team.
% Distributed under the terms of the Modified BSD License.
To internationalize your extension, the following tasks are required:
:::{note}
Please read carefully the {ref}internationalization-rules as they are strong constraints for internationalization to work.
:::
translation.ITranslator from @jupyterlab/translation package to your plugin dependencies.const extension: JupyterFrontEndPlugin<void> = {
id: 'jupyterlab-extension',
autoStart: true,
requires: [ITranslator],
activate: (app: JupyterFrontEnd, translator: ITranslator) => {}
};
const trans = translator.load('my_domain');
:::{note}
A good practice is to use your extension named using only letters, numbers and _
characters.
Domain are normalized by replacing - with _ characters.
:::
Examples:
this._trans.__('String to be translated');
this._trans.__('%1 is argument of a translated string', adjective);
this._trans._n('Singular string for %1', 'Plural string for %1', n);
You could also look at the following pull requests on the spellchecker extension.
There are two options: you can either add your extension to the JupyterLab language packs or you can create a python package to distribute your extension translation (see below).
JupyterLab follows Gettext's approach for translation. Gettext extracts strings from source code, and compiles them with provided translation (find more about it in the Python documentation).
By using jupyterlab-translate, you can extract, update, and compile your translation.
After that, you must include your compiled translation (.json, .mo) to your python package. This can be done by editing these two files.
setup.py:
from setuptools import setup
setup(
# ...
entry_points={"jupyterlab.locale": ["jupyterlab_some_package = jupyterlab_some_package"]},
)
MANIFEST.in:
recursive-include jupyterlab_some_package *.json
recursive-include jupyterlab_some_package *.mo
:::{note} An example is available in the server test :::
Settings schema can also be translated. The translatable strings are extracted using regex selectors on JSON path. By default, the following selectors are used:
title: Settings titledescription: Settings descriptionproperties/.*/title: Property titlesproperties/.*/description: Property descriptionsdefinitions/.*/properties/.*/title: Property titles in definitionsdefinitions/.*/properties/.*/description: Property descriptions in definitionsjupyter\.lab\.setting-icon-label: Settings icon label in JupyterLabjupyter\.lab\.menus/.*/label: Menu label in JupyterLabjupyter\.lab\.toolbars/.*/label: Toolbar item label in JupyterLabThose selectors can be configured using the jupyter.lab.internationalization key in
the schema. The following example will pick the default value for myprop property:
"jupyter.lab.internationalization": {
"selectors": [
"properties/myprop/default",
],
"domain": "my_jlab_extension"
}
In the example above, a specific domain in which the translations are defined is also
specified (here my_jlab_extension). If no domain is specified, it defaults to
jupyterlab.
(internationalization-rules)=
In order for the strings to be extracted from the code, the following rules must be followed.
Domain name are normalized by replacing - to _
Translation bundle variable must be one of:
transthis.transthis._transthis.props.transprops.transExamples that work:
trans.__('This translatable string will be found');
this.trans.__('This translatable string will be found');
this._trans.__('This translatable string will be found');
this.props.trans.__('This translatable string will be found');
props.trans.__('This translatable string will be found');
Examples that will not work:
translator.__('This translatable string WONT be found');
__('This translatable string WONT be found');
this.__('This translatable string WONT be found');
To fix this issue, alter your variable to use an accepted name:
const trans = translator;
trans.__('This translatable string will be found');
Example that will not work:
const errorMessage = 'This translatable string WONT be found';
trans.__(errorMessage);
To fix this issue, pass the string directly:
trans.__('This translatable string will be found');