localization_using_gettext.rst 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. .. _doc_localization_using_gettext:
  2. Localization using gettext
  3. ==========================
  4. In addition to :ref:`doc_importing_translations` in CSV format, Godot
  5. also supports loading translation files written in the GNU gettext
  6. format (text-based ``.po`` and compiled ``.mo`` since Godot 4.0).
  7. .. note:: For an introduction to gettext, check out
  8. `A Quick Gettext Tutorial <https://www.labri.fr/perso/fleury/posts/programming/a-quick-gettext-tutorial.html>`_.
  9. It's written with C projects in mind, but much of the advice
  10. also applies to Godot (with the exception of ``xgettext``).
  11. Advantages
  12. ----------
  13. - gettext is a standard format, which can be edited using any text editor
  14. or GUI editors such as `Poedit <https://poedit.net/>`_.
  15. - gettext is supported by translation platforms such as
  16. `Transifex <https://www.transifex.com/>`_ and `Weblate <https://weblate.org/>`_,
  17. which makes it easier for people to collaborate to localization.
  18. - Compared to CSV, gettext works better with version control systems like Git,
  19. as each locale has its own messages file.
  20. - Multiline strings are more convenient to edit in gettext files compared
  21. to CSV files.
  22. Disadvantages
  23. -------------
  24. - gettext is a more complex format than CSV and can be harder to grasp for
  25. people new to software localization.
  26. - People who maintain localization files will have to install gettext tools
  27. on their system. However, as Godot supports using text-based message files
  28. (``.po``), translators can test their work without having to install gettext tools.
  29. Installing gettext tools
  30. ------------------------
  31. The command line gettext tools are required to perform maintenance operations,
  32. such as updating message files. Therefore, it's strongly recommended to
  33. install them.
  34. - **Windows:** Download an installer from
  35. `this page <https://mlocati.github.io/articles/gettext-iconv-windows.html>`_.
  36. Any architecture and binary type (shared or static) works;
  37. if in doubt, choose the 64-bit static installer.
  38. - **macOS:** Install gettext either using `Homebrew <https://brew.sh/>`_
  39. with the ``brew install gettext`` command, or using
  40. `MacPorts <https://www.macports.org/>`_ with the
  41. ``sudo port install gettext`` command.
  42. - **Linux:** On most distributions, install the ``gettext`` package from
  43. your distribution's package manager.
  44. Creating the PO template
  45. ------------------------
  46. Automatic generation using the editor
  47. -------------------------------------
  48. Since Godot 4.0, the editor can generate a PO template automatically from
  49. specified scene and script files. This POT generation also supports translation
  50. contexts and pluralization if used in a script, with the optional second
  51. argument of ``tr()`` and the ``tr_n()`` method.
  52. Open the Project Settings' **Localization > POT Generation** tab, then use the
  53. **Add…** button to specify the path to your project's scenes and scripts that
  54. contain localizable strings:
  55. .. figure:: img/localization_using_gettext_pot_generation.webp
  56. :align: center
  57. :alt: Creating a PO template in the Localization > POT Generation tab of the Project Settings
  58. Creating a PO template in the **Localization > POT Generation** tab of the Project Settings
  59. After adding at least one scene or script, click **Generate POT** in the
  60. top-right corner, then specify the path to the output file. This file can be
  61. placed anywhere in the project directory, but it's recommended to keep it in a
  62. subdirectory such as ``locale``, as each locale will be defined in its own file.
  63. You can then move over to
  64. :ref:`creating a messages file from a PO template <doc_localization_using_gettext_messages_file>`.
  65. .. note::
  66. Remember to regenerate the PO template after making any changes to
  67. localizable strings, or after adding new scenes or scripts. Otherwise, newly
  68. added strings will not be localizable and translators won't be able to
  69. update translations for outdated strings.
  70. Manual creation
  71. ---------------
  72. If the automatic generation approach doesn't work out for your needs, you can
  73. create a PO template by hand in a text editor. This file can be placed anywhere
  74. in the project directory, but it's recommended to keep it in a subdirectory, as
  75. each locale will be defined in its own file.
  76. Create a directory named ``locale`` in the project directory. In this directory,
  77. save a file named ``messages.pot`` with the following contents:
  78. ::
  79. # Don't remove the two lines below, they're required for gettext to work correctly.
  80. msgid ""
  81. msgstr ""
  82. # Example of a regular string.
  83. msgid "Hello world!"
  84. msgstr ""
  85. # Example of a string with pluralization.
  86. msgid "There is %d apple."
  87. msgid_plural "There are %d apples."
  88. msgstr[0] ""
  89. msgstr[1] ""
  90. # Example of a string with a translation context.
  91. msgctxt "Actions"
  92. msgid "Close"
  93. msgstr ""
  94. Messages in gettext are made of ``msgid`` and ``msgstr`` pairs.
  95. ``msgid`` is the source string (usually in English), ``msgstr`` will be
  96. the translated string.
  97. .. warning::
  98. The ``msgstr`` value in PO template files (``.pot``) should **always** be
  99. empty. Localization will be done in the generated ``.po`` files instead.
  100. .. _doc_localization_using_gettext_messages_file:
  101. Creating a messages file from a PO template
  102. -------------------------------------------
  103. The ``msginit`` command is used to turn a PO template into a messages file.
  104. For instance, to create a French localization file, use the following command
  105. while in the ``locale`` directory:
  106. .. code-block:: shell
  107. msginit --no-translator --input=messages.pot --locale=fr
  108. The command above will create a file named ``fr.po`` in the same directory
  109. as the PO template.
  110. Alternatively, you can do that graphically using Poedit, or by uploading the
  111. POT file to your web platform of choice.
  112. Loading a messages file in Godot
  113. --------------------------------
  114. To register a messages file as a translation in a project, open the
  115. **Project Settings**, then go to the **Localization** tab.
  116. In **Translations**, click **Add…** then choose the ``.po`` or ``.mo`` file
  117. in the file dialog. The locale will be inferred from the
  118. ``"Language: <code>\n"`` property in the messages file.
  119. .. note:: See :ref:`doc_internationalizing_games` for more information on
  120. importing and testing translations in Godot.
  121. Updating message files to follow the PO template
  122. ------------------------------------------------
  123. After updating the PO template, you will have to update message files so
  124. that they contain new strings, while removing strings that are no longer
  125. present in the PO template. This can be done automatically using the
  126. ``msgmerge`` tool:
  127. .. code-block:: shell
  128. # The order matters: specify the message file *then* the PO template!
  129. msgmerge --update --backup=none fr.po messages.pot
  130. If you want to keep a backup of the original message file (which would be
  131. saved as ``fr.po~`` in this example), remove the ``--backup=none`` argument.
  132. .. note::
  133. After running ``msgmerge``, strings which were modified in the source language
  134. will have a "fuzzy" comment added before them in the ``.po`` file. This comment
  135. denotes that the translation should be updated to match the new source string,
  136. as the translation will most likely be inaccurate until it's updated.
  137. Strings with "fuzzy" comments will **not** be read by Godot until the
  138. translation is updated and the "fuzzy" comment is removed.
  139. Checking the validity of a PO file or template
  140. ----------------------------------------------
  141. It is possible to check whether a gettext file's syntax is valid by running
  142. the command below:
  143. .. code-block:: shell
  144. msgfmt fr.po --check
  145. If there are syntax errors or warnings, they will be displayed in the console.
  146. Otherwise, ``msgfmt`` won't output anything.
  147. Using binary MO files (useful for large projects only)
  148. ------------------------------------------------------
  149. For large projects with several thousands of strings to translate or more,
  150. it can be worth it to use binary (compiled) MO message files instead of text-based
  151. PO files. Binary MO files are smaller and faster to read than the equivalent
  152. PO files.
  153. You can generate a MO file with the command below:
  154. .. code-block:: shell
  155. msgfmt fr.po --no-hash -o fr.mo
  156. If the PO file is valid, this command will create a ``fr.mo`` file besides
  157. the PO file. This MO file can then be loaded in Godot as described below.
  158. The original PO file should be kept in version control so you can update
  159. your translation in the future. In case you lose the original PO file and
  160. wish to decompile a MO file into a text-based PO file, you can do so with:
  161. .. code-block:: shell
  162. msgunfmt fr.mo > fr.po
  163. The decompiled file will not include comments or fuzzy strings, as these are
  164. never compiled in the MO file in the first place.