Translating software using GNU Gettext

GNU Gettext is one of the most widely used tool for internationalization of free software. It provides a simple yet flexible way to localize the software. It has great support for plurals, it can add further context to the translated string and there are quite a lot of tools built around it. Of course it has great support in Weblate (see GNU Gettext file format description).

Примітка

If you are about to use it in proprietary software, please consult licensing first, it might not be suitable for you.

GNU Gettext can be used from a variety of languages (C, Python, PHP, Ruby, JavaScript and many more) and usually the UI frameworks already come with some support for it. The standard usage is through the gettext() function call, which is often aliased to _() to make the code simpler and easier to read.

Additionally it provides pgettext() call to provide additional context to translators and ngettext() which can handle plural types as defined for target language.

As a widely spread tool, it has many wrappers which make its usage really simple, instead of manual invoking of Gettext described below, you might want to try one of them, for example intltool.

Зразок програми

Проста програма мовою C із використанням Gettext може виглядати так:

#include <libintl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int count = 1;
    setlocale(LC_ALL, "");
    bindtextdomain("hello", "/usr/share/locale");
    textdomain("hello");
    printf(
        ngettext(
            "Orangutan has %d banana.\n",
            "Orangutan has %d bananas.\n",
            count
        ),
        count
    );
    printf("%s\n", gettext("Thank you for using Weblate."));
    exit(0);
}

Видобування рядків для перекладу

Щойно у вас буде код, де використовуються виклики gettext, ви можете скористатися xgettext для видобування повідомлень з коду і зберігання їх до файла .pot:

$ xgettext main.c -o po/hello.pot

Примітка

Існують альтернативні програми для видобування рядків з коду, наприклад, pybabel.

Ця програма створює файл шаблона, яким ви можете скористатися для того, щоб розпочати новий переклад (за допомогою програми msginit) або оновити наявні переклади після змін у коді (вам варто скористатися для цього програмою msgmerge). Отриманий файл є просто структурований текстовий файл:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-23 11:02+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"

#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""

#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""

Кожен рядок msgid визначає рядок для перекладу. Спеціальний порожній рядок на початку файла є заголовком, який містить метадані щодо перекладу.

Започаткування нового перекладу

Коли у нас буде шаблон, ми можемо розпочати перший переклад:

$ msginit -i po/hello.pot -l cs --no-translator -o po/cs.po
Created cs.po.

Щойно створений файл cs.po вже містить деякі попередньо заповнені дані. Найважливіше те, що у файлі вже визначено належні форми множини для вибраної мови — кількість форм множини буде змінено відповідним чином:

# Czech translations for PACKAGE package.
# Copyright (C) 2015 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Automatically generated, 2015.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-23 11:02+0200\n"
"PO-Revision-Date: 2015-10-23 11:02+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"

#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""

#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""

Цей файл компілюється у оптимізовану двійкову форму — файл .mo, який використовується функціями GNU Gettext під час роботи програми.

Оновлення рядків

Після додавання рядків або зміни рядків у вашій програм, ви можете запустити xgettext знову і повторно створити файл шаблона:

$ xgettext main.c -o po/hello.pot

Далі, ви можете оновити окремі файли перекладів, щоб вони відповідали новоствореному шаблону (це стосується і перевпорядковування рядків відповідно до нового шаблона):

$ msgmerge --previous --update po/cs.po po/hello.pot

Імпортування до Weblate

Щоб імпортувати такий переклад до Weblate, вам достатньо визначити вказані нижче поля при створенні складника (див. Налаштовування складників для докладного опису полів):

Поле

Значення

Сховище з джерелами

Адреса сховища VCS із вашим проєктом

Маска файлів

po/*.po

Заготова для нових перекладів

po/hello.pot

Формат файлу

Виберіть файл PO Gettext

Нова мова

Виберіть Створити новий мовний файл

Ось і все — можна починати переклад вашого програмного забезпечення!

Дивись також

Ви можете знайти приклад Gettext із багатьма мовами у проєкті Weblate Hello на GitHub: <https://github.com/WeblateOrg/hello>.