Skip to content

Commit

Permalink
DOCS: Add internationalization instructions (#1178)
Browse files Browse the repository at this point in the history
Co-authored-by: James McKinney <[email protected]>
  • Loading branch information
choldgraf and jpmckinney authored Feb 17, 2023
1 parent 41fde5f commit 839c3bf
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 0 deletions.
110 changes: 110 additions & 0 deletions docs/community/i18n.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
Internationalization
====================

.. warning::

This theme is still in the process of setting up internationalization.
Some of the text below may not yet be correct (for example, we do not yet have a ``locales/`` directory).
Follow these issues to track progress:

- https://github.com/pydata/pydata-sphinx-theme/issues/1162
- https://github.com/pydata/pydata-sphinx-theme/issues/257

Internationalization (I18N) and localization (L10N) is performed using `Gettext <https://docs.python.org/3/library/gettext.html>`__.

Types of files
--------------

Gettext reads a program's source and extracts text that has been marked as translatable, known as "source strings.
Gettext uses three types of files:

PO file (``.po``)
A `Portable Object (PO) file <https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`__ is made up of many entries.
Each entry holds the relation between a source string and its translation.
``msgid`` contains the **source string**, and ``msgstr`` contains the **translation**.
In a given PO file, all translations are expressed in a single target language.
PO files are also known as "message catalogs".

Entries begin with comments, on lines starting with the character ``#``.
Comments are created and maintained by Gettext.
Comment lines starting with ``#:`` contain references to the program's source.
These references allow a human translator to find the source strings in their original context.
Comment lines starting with ``#,`` contain flags like ``python-format``, which indicates that the source string contains placeholders like ``%(copyright)s``.
POT file (``.pot``)
A Portable Object Template (POT) file is the same as a PO file, except the translations are empty, so that it can be used as a template for new languages.
MO file (``.mo``)
A Machine Object (MO) file is a binary version of a PO file. PO files are compiled to MO files, which are required by Gettext.

.. _adding-natural-language-text:

Mark natural language text as translateable
-------------------------------------------

All natural language text must be marked as translatable, so that it can be extracted by Gettext and translated by humans.

Jinja2 provides a ``trans`` block and a ``_()`` function to mark text as translatable.
`Please refer to the Jinja2 documentation <https://jinja.palletsprojects.com/en/2.11.x/templates/#i18n>`__.
Remember to `manually escape <https://jinja.palletsprojects.com/en/2.11.x/templates/#working-with-manual-escaping>`__ variables if needed.

Any text that is marked in this way will be discoverable by ``gettext`` and used to generate ``.po`` files (see below for information).
Once you've marked text as translateable, complete the steps for :ref:`changing-natural-language-text`.

.. _changing-natural-language-text:

Add or change natural language text
-----------------------------------

These steps cover how to add or change text that has been marked as translateable.

#. Edit the natural language text as desired.
Ensure that it is {ref}`marked as translateable <adding-natural-language-text>`.

#. Generate/update the message catalog template (``POT`` file) with `the PyBabel extract command <https://babel.pocoo.org/en/latest/cmdline.html#extract>`__:

.. code-block:: bash
pybabel extract . -F babel.cfg -o src/pydata_sphinx_theme/locale/sphinx.pot -k '_ __ l_ lazy_gettext'
#. Update the message catalogs (``PO`` files) with `the PyBabel update command <https://babel.pocoo.org/en/latest/cmdline.html#update>`__:

.. code-block:: bash
pybabel update -i src/pydata_sphinx_theme/locale/sphinx.pot -d src/pydata_sphinx_theme/locale -D sphinx
This will update these files with new information about the position and text of the language you have modified.

.. _translating-the-theme:

Add translations to translateable text
--------------------------------------

Once text has been marked as translateable, and ``PO`` files have been generated for it, we may add translations for new languages for the phrase.
This section covers how to do so.

.. note::

These steps use the Spanish language as an example.
To translate the theme to another language, replace ``es`` with the language's two-letter lowercase `ISO 639-1 code <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>`__.

#. If the language's code matches no sub-directory of the `pydata_sphinx_theme/locale <https://github.com/pydata/pydata-sphinx-theme/tree/main/pydata_sphinx_theme/locale>`__ directory, initialize the language's message catalog (PO file) with `PyBabel init <https://babel.pocoo.org/en/latest/cmdline.html#init>`__:

.. code-block:: bash
pybabel init -i src/pydata_sphinx_theme/locale/sphinx.pot -d src/pydata_sphinx_theme/locale -D sphinx -l es
#. Edit the language's message catalog at ``pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po``. For each source string introduced by the ``msgid`` keyword, add its translation after the ``msgstr`` keyword.

#. Compile the message catalogs of every language. This creates or updates the MO files with `PyBabel compile <https://babel.pocoo.org/en/latest/cmdline.html#compile>`__:

.. code-block:: bash
pybabel compile -d src/pydata_sphinx_theme/locale -D sphinx
References
----------

I18N and L10N are deep topics. Here, we only cover the bare minimum needed to fulfill basics technical tasks. You might like:

- `Internationalis(z)ing Code <https://www.youtube.com/watch?v=0j74jcxSunY>`__ by Computerphile on YouTube
- `Falsehoods Programmers Believe About Language <http://garbled.benhamill.com/2017/04/18/falsehoods-programmers-believe-about-language>`__ by Ben Hamill
1 change: 1 addition & 0 deletions docs/community/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ setup
structure
topics
manual
i18n
bootstrap
```

Expand Down
74 changes: 74 additions & 0 deletions docs/user_guide/i18n.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Internationalization
====================

This theme contains translatable strings.
There are two kinds of strings in this theme, with different steps to translate each.

**Built-in strings** are hard-coded in the theme's templates.
They will automatically be translated if the language is `supported <https://github.com/pydata/pydata-sphinx-theme/tree/master/pydata_sphinx_theme/locale>`__.
To add another language, see :ref:`translating-the-theme`.

**Configurable strings** are user-defined with the ``html_theme_options`` variable in your ``conf.py`` file (see other sections in :doc:`the user guide<index>` for examples).
To translate these strings, see the section below.

Translating configurable strings
--------------------------------

These instructions are for translating configurable strings (those that are customizable in ``html_theme_options``).

These instructions assume that you store your translations in a ``locale`` directory under your documentation directory, and that you want to use ``theme`` as the name of the message catalog for these strings.

#. In your ``conf.py`` file:

.. code-block:: python
import os.path
from sphinx.locale import get_translation
catalog = "theme"
_ = get_translation(catalog)
html_theme_options = {
"search_bar_text": _("Search the docs..."),
# You only need to translate the following if you use these features.
"icon_links_label": _("Quick Links"),
"icon_links": [
{
"name": _("GitHub"),
"url": "https://github.com/<your-org>/<your-repo>",
"icon": "fab fa-github-square",
},
],
"external_links": [
{
"name": _("link-one-name"),
"url": "https://<link-one>",
},
],
}
def setup(app):
locale_dir = os.path.join(os.path.abspath(os.path.dirname(__file__), "locale")
app.add_message_catalog(catalog, locale_dir)
#. Extract the strings to translate:
.. code-block:: bash
pybabel extract . -o locale/theme.pot
#. Create a message catalog (changing the ``--locale`` option as desired):
.. code-block:: bash
pybabel init --input-file=locale/theme.pot --domain=theme --output-dir=locale --locale=fr
#. Translate the message catalog by editing the file.
#. Compile the message catalog:
.. code-block:: bash
pybabel compile --directory=locale --domain=theme
1 change: 1 addition & 0 deletions docs/user_guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ announcements
version-dropdown
search
keyboard-shortcuts
i18n
```

```{toctree}
Expand Down

0 comments on commit 839c3bf

Please sign in to comment.