Локализация с помощью gettext (PO-файлы)

In addition to importing translations in CSV format, Godot also supports loading translation files written in the GNU gettext format (text-based .po and compiled .mo).

Примечание

Для ознакомления с gettext посмотрите A Quick Gettext Tutorial. Он написан для проектов на C, но большая часть советов применима и к Godot (за исключением xgettext).

Полную документацию см. в GNU Gettext.

Преимущества

  • gettext is a standard format, which can be edited using any text editor or GUI editors such as Poedit. This can be significant as it provides a lot of tools for translators, such as marking outdated strings, finding strings that haven't been translated, etc.

  • gettext поддерживается такими платформами перевода, как Transifex и Weblate, что облегчает совместную работу людей над локализацией.

  • По сравнению с CSV, файлы gettext лучше работают с системами контроля версий, такими как Git, поскольку каждая локаль имеет свой собственный файл сообщений.

  • Многострочные строки удобнее редактировать в PO-файлах gettext, чем в CSV-файлах.

Недостатки

  • Файлы PO gettext имеют более сложный формат, чем CSV, и их может быть сложнее понять новичкам в локализации программного обеспечения.

  • Тем, кто поддерживает файлы локализации, потребуется установить инструменты GetText в своей системе. Однако, поскольку Godot поддерживает использование текстовых файлов сообщений (.po), переводчики могут тестировать свою работу без установки инструментов GetText.

  • В PO-файлах gettext обычно используется английский язык в качестве базового. Переводчики используют этот язык для перевода на другие языки. Вы также можете использовать другие языки в качестве базового, но это встречается нечасто.

Установка инструментов gettext

Инструменты командной строки gettext необходимы для выполнения операций обслуживания, таких как обновление файлов сообщений. Поэтому настоятельно рекомендуется их установить.

  • Windows: Загрузите программу установки с этой страницы. Работает любая архитектура и бинарный тип (разделяемый или статический); если есть сомнения, выбирайте 64-битный статический инсталлятор.

  • macOS: Установите gettext либо с помощью Homebrew с командой brew install gettext, либо с помощью MacPorts <https://www.macports.org/>`_ с командой ``sudo port install gettext.

  • Linux: В большинстве дистрибутивов установите пакет gettext из менеджера пакетов вашего дистрибутива.

Для графического интерфейса (GUI) Poedit можно загрузить с Официального сайта. Базовая версия имеет открытый исходный код и доступна по лицензии MIT.

Создание шаблона PO

Автоматическая генерация с помощью редактора

The editor can generate a PO template automatically from specified scene and GDScript files. This POT generation also supports translation contexts and pluralization if used in a script, with the optional second argument of tr() and the tr_n() method.

Open Project > Project Settings > Localization > Template Generation, then use the Add… button to specify the path to your project's scenes and scripts that contain localizable strings:

Creating a PO template in the Localization > Template Generation tab of the Project Settings

Creating a PO template in the Localization > Template Generation tab of the Project Settings

After adding at least one scene or script, click Generate in the top-right corner, then specify the path to the output file with a pot file extension. This file can be placed anywhere in the project directory, but it's recommended to keep it in a subdirectory such as locale, as each locale will be defined in its own file.

См. below информацию о том, как добавлять комментарии для переводчиков или исключать некоторые строки из добавления в шаблон PO для файлов GDScript.

Затем вы можете перейти к creating a messages file from a PO template.

Примечание

Не забудьте перегенерировать шаблон PO после внесения любых изменений в локализуемые строки или добавления новых сцен или сценариев. В противном случае вновь добавленные строки не будут локализованы, и переводчики не смогут обновить переводы устаревших строк.

Manual creation

Если автоматическая генерация вам не подходит, вы можете создать шаблон PO вручную в текстовом редакторе. Этот файл можно разместить в любом месте каталога проекта, но рекомендуется хранить его в подкаталоге, так как каждая локаль будет определена в отдельном файле.

Create a directory named locale in the project directory. In this directory, save a file named messages.pot with the following content:

# Don't remove the two lines below, they're required for gettext to work correctly.
msgid ""
msgstr ""

# Example of a regular string.
msgid "Hello world!"
msgstr ""

# Example of a string with pluralization.
msgid "There is %d apple."
msgid_plural "There are %d apples."
msgstr[0] ""
msgstr[1] ""

# Example of a string with a translation context.
msgctxt "Actions"
msgid "Close"
msgstr ""

Сообщения в gettext состоят из пар msgid и msgstr. msgid - это исходная строка (обычно на английском языке), msgstr - это переведенная строка.

Предупреждение

Значение msgstr в файлах шаблонов PO (.pot) должно всегда быть пустым. Локализация будет выполнена в сгенерированных файлах .po вместо этого.

Создание файла сообщений из шаблона PO

Команда msginit используется для превращения шаблона PO в файл сообщений. Например, чтобы создать файл французской локализации, используйте следующую команду, находясь в каталоге locale:

msginit --no-translator --input=messages.pot --locale=fr

Приведенная выше команда создаст файл с именем fr.po в том же каталоге, что и шаблон PO.

Кроме того, это можно сделать графически с помощью Poedit или загрузив файл POT на выбранную вами веб-платформу.

Загрузка файла сообщений в Godot

To register a messages file as a translation in a project, open the Project Settings, then go to Localization > Translations, click Add… then choose the .po or .mo file in the file dialog. The locale will be inferred from the "Language: <code>\n" property in the messages file.

Примечание

Смотрите Локализация игр для получения дополнительной информации об импорте и тестировании переводов в Godot.

Обновление файлов сообщений в соответствии с шаблоном PO

После обновления шаблона PO вам нужно будет обновить файлы сообщений, чтобы они содержали новые строки, удалив при этом строки, которые больше не присутствуют в шаблоне PO. Это можно сделать автоматически с помощью инструмента msgmerge:

# The order matters: specify the message file *then* the PO template!
msgmerge --update --backup=none fr.po messages.pot

Если вы хотите сохранить резервную копию исходного файла сообщения (который в данном примере будет сохранен как fr.po~), удалите аргумент --backup=none.

Примечание

После запуска msgmerge строки, изменённые на исходном языке, будут иметь в файле .po "нечёткий" комментарий. Этот комментарий означает, что перевод следует обновить в соответствии с новой исходной строкой, поскольку до обновления перевод, скорее всего, будет неточным.

Строки с "нечеткими" комментариями не будут прочитаны Godot, пока перевод не будет обновлен и "нечеткий" комментарий не будет удален.

Проверка достоверности файла или шаблона PO

Можно проверить правильность синтаксиса файла gettext.

Если открыть файл в Poeditor, он выведет соответствующие предупреждения, если есть синтаксические ошибки. Вы также можете проверить это, выполнив команду gettext ниже:

msgfmt fr.po --check

Если есть синтаксические ошибки или предупреждения, они будут выведены в консоль. В противном случае msgfmt ничего не выведет.

Использование двоичных MO-файлов (полезно только для больших проектов)

Для крупных проектов, требующих перевода нескольких тысяч строк и более, может быть целесообразно использовать двоичные (скомпилированные) файлы сообщений MO вместо текстовых PO-файлов. Двоичные MO-файлы меньше по размеру и читаются быстрее, чем аналогичные PO-файлы.

Вы можете создать MO-файл с помощью следующей команды:

msgfmt fr.po --no-hash -o fr.mo

Если PO-файл корректен, эта команда создаст файл fr.mo помимо PO-файла. Этот MO-файл затем можно загрузить в Godot, как описано выше.

Исходный PO-файл следует хранить в системе контроля версий, чтобы иметь возможность обновить перевод в будущем. Если вы потеряете исходный PO-файл и захотите декомпилировать MO-файл в текстовый PO-файл, это можно сделать следующим образом:

msgunfmt fr.mo > fr.po

Декомпилированный файл не будет содержать комментариев или нечетких строк, поскольку они изначально не компилируются в файле MO.

Извлечение локализуемых строк из файлов GDScript

Встроенный плагин редактора распознает различные шаблоны в исходном коде для извлечения локализуемых строк из файлов GDScript, включая, помимо прочего, следующие:

  • tr(), tr_n(), atr(), и atr_n() звонки;

  • назначение свойств text, placeholder_text, и tooltip_text;

  • add_tab(), add_item(), set_tab_title(), и другие звонки;

  • FileDialog фильтры типа "*.png ; PNG Images".

Примечание

Аргумент или правый операнд должен быть константной строкой, в противном случае плагин не сможет оценить выражение и проигнорирует его.

Если плагин извлекает ненужные строки, вы можете игнорировать их с помощью комментария NO_TRANSLATE. Вы также можете предоставить дополнительную информацию для переводчиков с помощью комментария TRANSLATORS:. Эти комментарии должны располагаться либо на той же строке, что и распознанный шаблон, либо перед ним.

$CharacterName.text = "???" # NO_TRANSLATE

# NO_TRANSLATE: Language name.
$TabContainer.set_tab_title(0, "Python")

item.text = "Tool" # TRANSLATORS: Up to 10 characters.

# TRANSLATORS: This is a reference to Lewis Carroll's poem "Jabberwocky",
# make sure to keep this as it is important to the plot.
say(tr("He took his vorpal sword in hand. The end?"))

Использование контекста

Параметр context можно использовать для различения ситуации, в которой используется перевод, или для различения полисемичных слов (слов с несколькими значениями).

Например:

tr("Start", "Main Menu")
tr("End", "Main Menu")
tr("Shop", "Main Menu")
tr("Shop", "In Game")

In a gettext PO file, a string with a context can be defined as follows:

# Example of a string with a translation context.
msgctxt "Main Menu"
msgid "Shop"
msgstr ""

# A different source string that is identical, but with a different context.
msgctxt "In Game"
msgid "Shop"
msgstr ""

Обновление файлов PO

Рано или поздно вы добавите в нашу игру новый контент, и появятся новые строки, которые необходимо будет перевести. В этом случае вам потребуется обновить существующие PO-файлы, включив в них новые строки.

Сначала создайте новый POT-файл, содержащий все существующие строки и вновь добавленные строки. После этого объедините существующие PO-файлы с новым POT-файлом. Это можно сделать двумя способами:

  • Используйте редактор GetText, в нем должна быть возможность обновления файла PO из файла POT.

  • Используйте инструмент gettext msgmerge:

# The order matters: specify the message file *then* the PO template!
msgmerge --update --backup=none fr.po messages.pot

Если вы хотите сохранить резервную копию исходного файла сообщения (который в данном примере будет сохранен как fr.po~), удалите аргумент --backup=none.

Пользовательский плагин для генерации POT

Если вам нужно работать с файлами других форматов, вы можете написать плагин для анализа и извлечения строк из файла. Этот плагин извлечет строки и запишет их в POT-файл после нажатия кнопки Generate POT. Подробнее о создании плагина для анализа перевода см. в разделе EditorTranslationParserPlugin.