Localizing Fietsboek
====================

Most of the localization in Fietsboek is done using the `gettext
<https://www.gnu.org/software/gettext/>`__ machinery to provide translated
messages. Additionally, `Babel <https://babel.pocoo.org/en/latest/>`__ is used
to provide localized number and date formatting.

In addition to ``gettext``-based messages, some longer texts are also provided
as stand-alone files in their respective language directories.

The ``gettext`` Machinery
-------------------------

The ``gettext`` machinery depends on three files:

The ``.pot`` files are the template files that contain all the messages that
need to be translated. They are generated by walking through the source code
and finding marked translation strings.

The ``.po`` files are translations, initialized from the ``.pot`` template. For
every language, a ``.po`` file contains the translated messages and can be
edited by the translator.

Finally, the ``.mo`` files are compiled versions of the ``.po`` files, intended
to be more efficient.

Extracting Messages
-------------------

.. note::

    This section can be skipped if you only intend on creating a new
    translation. It is only important if you introduce new features with new
    messages to the code.

If you introduce new messages in Fietsboek, it is important to regenerate the
``.pot`` template. Only then can translations for your messages be added.

In order to do so, use the :program:`pybabel` binary:

.. code:: bash

    .venv/bin/pybabel extract -F babel.cfg -o fietsboek/locale/fietslog.pot --input-dirs=fietsboek

The :file:`justfile` (requires just_) contains a shortcut for this command:

.. code:: bash

    just extract-messages

Creating a New Language
-----------------------

If you want to add a translation for a language that does not yet exist, first
generate the ``.po`` file containing the messages using :program:`pybabel`:

.. code:: bash

    # Replace LOCALE with the locale name, for example "nl" or "fr"
    .venv/bin/pybabel init -d fietsboek/locale -l LOCALE -i fietsboek/locale/fietslog.pot

This will create the directory :file:`fietsboek/locale/{language}`.

Finally, you need to copy the non-gettext messages. This is best done by
copying over the english original texts:

.. code:: bash

    # Replace nl with the locale that you just generated
    cp -r fietsboek/locale/en/html fietsboek/locale/nl/

Again, there is a shortcut in the :file:`justfile` that does both steps:

.. code:: bash

    just init-language nl

Updating a Language
-------------------

When features and messages get added to Fietsboek, it is important to keep the
message catalogues up to date:

.. code:: bash

    # Replace nl with the locale that you want to update
    .venv/bin/pybabel update -d fietsboek/locale -l nl -i fietsboek/locale/fietslog.pot

This ensures that every message from the template is also present in the
language's message catalogue, ready for translation.

Alternatively, you can also use the shortcut again:

.. code:: bash

    just update-language nl

Translating
-----------

Once you have the ``.po`` file generated (either by initializing a new language
or by updating an existing one), it is time to actually translate messages.
This is done by editing the
:file:`fietsboek/locale/{language}/LC_MESSAGES/messages.po` file. This can be
done either by using a standard text editor, or by using a specialized tool
like :program:`poedit`.

After translating the messages, the files in
:file:`fietsboek/locale/{language}/html` should also be translated. For this, a
text editor or a HTML editor can be used.

Compiling the Messages
----------------------

To generate the machine readable message format, the message catalogue has to
be compiled:

.. code:: bash

    # Replace nl with the locale that you want to compile
    .venv/bin/pybabel compile -d fietsboek/locale -l nl -i fietsboek/locale/nl/LC_MESSAGES/messages.po

Or using the shortcut:

.. code:: bash

    just compile-language nl

Further Reading
---------------

* The Pyramid documentation: `Internationalization and Localization
  <https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/i18n.html>`__

.. _just: https://github.com/casey/just