Skip to content

Commit 839c3bf

Browse files
DOCS: Add internationalization instructions (#1178)
Co-authored-by: James McKinney <[email protected]>
1 parent 41fde5f commit 839c3bf

File tree

4 files changed

+186
-0
lines changed

4 files changed

+186
-0
lines changed

docs/community/i18n.rst

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Internationalization
2+
====================
3+
4+
.. warning::
5+
6+
This theme is still in the process of setting up internationalization.
7+
Some of the text below may not yet be correct (for example, we do not yet have a ``locales/`` directory).
8+
Follow these issues to track progress:
9+
10+
- https://github.com/pydata/pydata-sphinx-theme/issues/1162
11+
- https://github.com/pydata/pydata-sphinx-theme/issues/257
12+
13+
Internationalization (I18N) and localization (L10N) is performed using `Gettext <https://docs.python.org/3/library/gettext.html>`__.
14+
15+
Types of files
16+
--------------
17+
18+
Gettext reads a program's source and extracts text that has been marked as translatable, known as "source strings.
19+
Gettext uses three types of files:
20+
21+
PO file (``.po``)
22+
A `Portable Object (PO) file <https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`__ is made up of many entries.
23+
Each entry holds the relation between a source string and its translation.
24+
``msgid`` contains the **source string**, and ``msgstr`` contains the **translation**.
25+
In a given PO file, all translations are expressed in a single target language.
26+
PO files are also known as "message catalogs".
27+
28+
Entries begin with comments, on lines starting with the character ``#``.
29+
Comments are created and maintained by Gettext.
30+
Comment lines starting with ``#:`` contain references to the program's source.
31+
These references allow a human translator to find the source strings in their original context.
32+
Comment lines starting with ``#,`` contain flags like ``python-format``, which indicates that the source string contains placeholders like ``%(copyright)s``.
33+
POT file (``.pot``)
34+
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.
35+
MO file (``.mo``)
36+
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.
37+
38+
.. _adding-natural-language-text:
39+
40+
Mark natural language text as translateable
41+
-------------------------------------------
42+
43+
All natural language text must be marked as translatable, so that it can be extracted by Gettext and translated by humans.
44+
45+
Jinja2 provides a ``trans`` block and a ``_()`` function to mark text as translatable.
46+
`Please refer to the Jinja2 documentation <https://jinja.palletsprojects.com/en/2.11.x/templates/#i18n>`__.
47+
Remember to `manually escape <https://jinja.palletsprojects.com/en/2.11.x/templates/#working-with-manual-escaping>`__ variables if needed.
48+
49+
Any text that is marked in this way will be discoverable by ``gettext`` and used to generate ``.po`` files (see below for information).
50+
Once you've marked text as translateable, complete the steps for :ref:`changing-natural-language-text`.
51+
52+
.. _changing-natural-language-text:
53+
54+
Add or change natural language text
55+
-----------------------------------
56+
57+
These steps cover how to add or change text that has been marked as translateable.
58+
59+
#. Edit the natural language text as desired.
60+
Ensure that it is {ref}`marked as translateable <adding-natural-language-text>`.
61+
62+
#. Generate/update the message catalog template (``POT`` file) with `the PyBabel extract command <https://babel.pocoo.org/en/latest/cmdline.html#extract>`__:
63+
64+
.. code-block:: bash
65+
66+
pybabel extract . -F babel.cfg -o src/pydata_sphinx_theme/locale/sphinx.pot -k '_ __ l_ lazy_gettext'
67+
68+
#. Update the message catalogs (``PO`` files) with `the PyBabel update command <https://babel.pocoo.org/en/latest/cmdline.html#update>`__:
69+
70+
.. code-block:: bash
71+
72+
pybabel update -i src/pydata_sphinx_theme/locale/sphinx.pot -d src/pydata_sphinx_theme/locale -D sphinx
73+
74+
This will update these files with new information about the position and text of the language you have modified.
75+
76+
.. _translating-the-theme:
77+
78+
Add translations to translateable text
79+
--------------------------------------
80+
81+
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.
82+
This section covers how to do so.
83+
84+
.. note::
85+
86+
These steps use the Spanish language as an example.
87+
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>`__.
88+
89+
#. 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>`__:
90+
91+
.. code-block:: bash
92+
93+
pybabel init -i src/pydata_sphinx_theme/locale/sphinx.pot -d src/pydata_sphinx_theme/locale -D sphinx -l es
94+
95+
#. 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.
96+
97+
#. 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>`__:
98+
99+
.. code-block:: bash
100+
101+
pybabel compile -d src/pydata_sphinx_theme/locale -D sphinx
102+
103+
104+
References
105+
----------
106+
107+
I18N and L10N are deep topics. Here, we only cover the bare minimum needed to fulfill basics technical tasks. You might like:
108+
109+
- `Internationalis(z)ing Code <https://www.youtube.com/watch?v=0j74jcxSunY>`__ by Computerphile on YouTube
110+
- `Falsehoods Programmers Believe About Language <http://garbled.benhamill.com/2017/04/18/falsehoods-programmers-believe-about-language>`__ by Ben Hamill

docs/community/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ setup
1616
structure
1717
topics
1818
manual
19+
i18n
1920
bootstrap
2021
```
2122

docs/user_guide/i18n.rst

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
Internationalization
2+
====================
3+
4+
This theme contains translatable strings.
5+
There are two kinds of strings in this theme, with different steps to translate each.
6+
7+
**Built-in strings** are hard-coded in the theme's templates.
8+
They will automatically be translated if the language is `supported <https://github.com/pydata/pydata-sphinx-theme/tree/master/pydata_sphinx_theme/locale>`__.
9+
To add another language, see :ref:`translating-the-theme`.
10+
11+
**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).
12+
To translate these strings, see the section below.
13+
14+
Translating configurable strings
15+
--------------------------------
16+
17+
These instructions are for translating configurable strings (those that are customizable in ``html_theme_options``).
18+
19+
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.
20+
21+
#. In your ``conf.py`` file:
22+
23+
.. code-block:: python
24+
25+
import os.path
26+
from sphinx.locale import get_translation
27+
28+
catalog = "theme"
29+
_ = get_translation(catalog)
30+
31+
html_theme_options = {
32+
"search_bar_text": _("Search the docs..."),
33+
34+
# You only need to translate the following if you use these features.
35+
"icon_links_label": _("Quick Links"),
36+
"icon_links": [
37+
{
38+
"name": _("GitHub"),
39+
"url": "https://github.com/<your-org>/<your-repo>",
40+
"icon": "fab fa-github-square",
41+
},
42+
],
43+
"external_links": [
44+
{
45+
"name": _("link-one-name"),
46+
"url": "https://<link-one>",
47+
},
48+
],
49+
}
50+
51+
def setup(app):
52+
locale_dir = os.path.join(os.path.abspath(os.path.dirname(__file__), "locale")
53+
54+
app.add_message_catalog(catalog, locale_dir)
55+
56+
#. Extract the strings to translate:
57+
58+
.. code-block:: bash
59+
60+
pybabel extract . -o locale/theme.pot
61+
62+
#. Create a message catalog (changing the ``--locale`` option as desired):
63+
64+
.. code-block:: bash
65+
66+
pybabel init --input-file=locale/theme.pot --domain=theme --output-dir=locale --locale=fr
67+
68+
#. Translate the message catalog by editing the file.
69+
70+
#. Compile the message catalog:
71+
72+
.. code-block:: bash
73+
74+
pybabel compile --directory=locale --domain=theme

docs/user_guide/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ announcements
4747
version-dropdown
4848
search
4949
keyboard-shortcuts
50+
i18n
5051
```
5152

5253
```{toctree}

0 commit comments

Comments
 (0)