internationalization.rst 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. Internationalization and Localization
  2. =====================================
  3. To internationalize your extension, the following tasks are required:
  4. .. note::
  5. Please read carefully the :ref:`internationalization-rules` as they are strong constraints for internationalization to work.
  6. 1. Add the token ``ITranslator`` from ``@jupyterlab/translation`` package to your plugin dependencies.
  7. .. code:: typescript
  8. const extension: JupyterFrontEndPlugin<void> = {
  9. id: 'jupyterlab-extension',
  10. autoStart: true,
  11. requires: [ITranslator],
  12. activate: (app: JupyterFrontEnd, translator: ITranslator) => {}
  13. };
  14. 2. Get the translation bundle from the domain on which your extension is translated.
  15. .. code:: typescript
  16. const trans = translator.load('my_domain');
  17. .. note::
  18. A good practice is to use your extension named using only letters, numbers and ``_``
  19. characters.
  20. Domain are normalized by replacing ``-`` with ``_`` characters.
  21. 3. Wraps all translatable strings with one of the `gettext functions <https://jupyterlab.readthedocs.io/en/3.4.x/api/modules/translation.html#translationbundle>`_.
  22. Examples:
  23. .. code:: typescript
  24. this._trans.__('String to be translated');
  25. this._trans.__('%1 is argument of a translated string', adjective);
  26. this._trans._n('Singular string for %1', 'Plural string for %1', n);
  27. You could also look at the following pull requests on the
  28. `spellchecker extension <https://github.com/jupyterlab-contrib/spellchecker/pull/84/files>`_.
  29. 4. Create and publish the translation for your extension.
  30. There are two options: you can either add your extension to the JupyterLab `language packs <https://github.com/jupyterlab/language-packs/#adding-a-new-extension>`_
  31. or you can create a python package to distribute your extension translation (see `test example <https://github.com/jupyterlab/jupyterlab_server/tree/main/tests/translations/jupyterlab-some-package>`_).
  32. Settings translation
  33. --------------------
  34. Settings schema can also be translated. The translatable strings are extracted using regex selectors
  35. on JSON path. By default, the following selectors are used:
  36. - ``title``: Settings title
  37. - ``description``: Settings description
  38. - ``properties/.*/title``: Property titles
  39. - ``properties/.*/description``: Property descriptions
  40. - ``definitions/.*/properties/.*/title``: Property titles in definitions
  41. - ``definitions/.*/properties/.*/description``: Property descriptions in definitions
  42. - ``jupyter\.lab\.setting-icon-label``: Settings icon label in JupyterLab
  43. - ``jupyter\.lab\.menus/.*/label``: Menu label in JupyterLab
  44. - ``jupyter\.lab\.toolbars/.*/label``: Toolbar item label in JupyterLab
  45. Those selectors can be configured using the ``jupyter.lab.internationalization`` key in
  46. the schema. The following example will pick the default value for ``myprop`` property:
  47. .. code:: json
  48. "jupyter.lab.internationalization": {
  49. "selectors": [
  50. "properties/myprop/default",
  51. ],
  52. "domain": "my_jlab_extension"
  53. }
  54. In the example above, a specific domain in which the translations are defined is also
  55. specified (here ``my_jlab_extension``). If no domain is specified, it defaults to
  56. ``jupyterlab``.
  57. .. _internationalization-rules:
  58. Rules
  59. -----
  60. In order for the strings to be extracted from the code, the following rules must be followed.
  61. - Domain name are normalized by replacing ``-`` to ``_``
  62. - Translation bundle variable must be one of:
  63. - ``trans``
  64. - ``this.trans``
  65. - ``this._trans``
  66. - ``this.props.trans``
  67. - ``props.trans``
  68. Examples that work:
  69. .. code:: typescript
  70. trans.__('This translatable string will be found');
  71. this.trans.__('This translatable string will be found');
  72. this._trans.__('This translatable string will be found');
  73. this.props.trans.__('This translatable string will be found');
  74. props.trans.__('This translatable string will be found');
  75. Examples that will **not** work:
  76. .. code:: typescript
  77. translator.__('This translatable string WONT be found');
  78. __('This translatable string WONT be found');
  79. this.__('This translatable string WONT be found');
  80. To fix this issue, alter your variable to use an accepted name:
  81. .. code:: typescript
  82. const trans = translator;
  83. trans.__('This translatable string will be found');
  84. - String must be passed directly to the function; don't use variables or constants
  85. Example that will **not** work:
  86. .. code:: typescript
  87. const errorMessage = 'This translatable string WONT be found'
  88. trans.__(errorMessage);
  89. To fix this issue, pass the string directly:
  90. .. code:: typescript
  91. trans.__('This translatable string will be found');