:orphan: .. _text_loc_example: Text Localization ================= Let's start by making a stripped down version of of :ref:`drawing_text`. We're going to be performing work on multiple files here, so I'm going to be putting all of them and doing all work in a folder called ``text_loc_example``. Create ``text_loc_example/text_loc_example.py`` with the following code: .. literalinclude:: ../../arcade/examples/text_loc_example_start.py :caption: text_loc_example_start.py :linenos: This code should run. .. image:: images/text_loc_example_untranslated.png :width: 600px :align: center :alt: Untranslated Game Screen We're going to translate that "Simple line of text in 12 point" line that shows on the screen into Spanish. I've adapted the instructions from `this blog post `__ to do this. We'll do this in the following steps: - Extract the lines we want to translate from the ``text_loc_example.py`` file into a ``text_loc_example.pot`` file. - Translate the lines manually. - Create a database usable by Python's ``gettext`` module from this translation. - Load this translation into the game. Extract the lines we want to translate from the ``text_loc_example.py`` file. ----------------------------------------------------------------------------- First, wrap all user-facing strings with ``_("my string")``. So in ``text_loc_example.py``, we'll just wrap the line facing the user: .. code:: python arcade.draw_text( "Simple line of text in 12 point", start_x, start_y, arcade.color.BLACK, 12 ) becomes .. code:: python arcade.draw_text( _("Simple line of text in 12 point"), start_x, start_y, arcade.color.BLACK, 12 ) At this point, your program will not run (because it's looking for a function ``_`` that's not defined). This is fine, and we'll fix it in a bit. Now we need to extract those strings into a ``.pot`` file. We need an external script for this- the ``pygettext.py`` script. Download the ``pygettext.py`` program from `the GitHub CPython repo `__ (Right click the page, then select the "Save Page as" option to save it. I recommend saving it to our working ``text_loc_example`` folder to keeps things simple). From this folder: .. code:: python python ./pygettext.py -d text_loc_example text_loc_example.py This creates ``text_loc_example/text_loc_example.pot``. This is a text file with a format we'll be able to use. It looks like this: :: # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2019-05-06 12:19-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" #: text_loc_example.py:46 msgid "Simple line of text in 12 point" msgstr "" Translate the "Simple line of text in 12 point" line by changing the ``msgstr`` value below it (I used `Google Translate `__ for this). :: msgid "Simple line of text in 12 point" msgstr "Línea simple de texto en 12 puntos." Save this file as ``text_loc_example/text_loc_example.po`` (we changed the ``.pot`` extension to ``.po``.). Let's move on to the next step: Create a database usable by Python's ``gettext`` module from this translation. ------------------------------------------------------------------------------ We need another Python script for this. Download the ``msgfmt.py`` script from `the GitHub CPython repo `__ (right click the page, then select the "Save Page as" option to save it). We need to put our translation into the right folder structure so our library will be able to find it. Create the ``my_app.mo`` folder heirarchy. Because we're translating it into Spanish (whose `country code `__ is ``es``), we have to make a ``locale/es/LC_MESSAGES`` directory for it. :: # If you're on Mac/Linux: mkdir -p ./text_loc_example_locale/es/LC_MESSAGES :: # If you're on Windows (TODO: test): mkdir .\text_loc_example_locale\es\LC_MESSAGES Create the ``text_loc_example.mo`` file: :: python msgfmt.py -o ./text_loc_example_locale/es/LC_MESSAGES/text_loc_example.mo text_loc_example.po Load this translation into the game. ------------------------------------ Add the following code to load your new translation database! I've inserted ``...`` around where I put it. .. code:: python ... import arcade import gettext es = gettext.translation('text_loc_example', localedir='text_loc_example_locale', languages=['es']) es.install() SCREEN_WIDTH = 500 ... Now you should be able to run the game with the ``es`` translation! .. image:: images/text_loc_example_translated.png :width: 600px :align: center :alt: Translated Game Screen Auto-translating to your user's language ---------------------------------------- Setting the language to ``es`` proves that our translation works, of course, but most of the time, we want our game to load the correct language for the user automatically. For this, replace the lines .. code:: python es = gettext.translation('text_loc_example', localedir='text_loc_example_locale', languages=['es']) es.install() with .. code:: python gettext.install('text_loc_example', localedir='text_loc_example_locale') As `the documentation `__ says, this code searches the user's computer for the language being used, then the ``locale`` folder for an appropriate translation to find the right language to show on the screen. We can test this by setting the ``LANG`` variable before running the program: :: # MacOS / Linux export LANG=es python text_loc_example.py :: # Windows set LANG=es python test_loc_example.py Final Code ---------- .. literalinclude:: ../../arcade/examples/text_loc_example_done.py :caption: text_loc_example_done.py :linenos: Final Directory structure ------------------------- :: text_loc_example/ ├── README.md ├── text_loc_example_locale │   └── es │   └── LC_MESSAGES │   └── text_loc_example.mo ├── msgfmt.py ├── pygettext.py ├── text_loc_example.po ├── text_loc_example.pot └── text_loc_example.py