Tornado and pgettext

Недавно (26 мая 2015 года) вышел релиз tornado 4.2. В него вошли разные дополнения, пожалуй основные из них - модули tornado.locks и tornado.queues. Они перекочевали из пакета Toro, подробное описание процесса от Jesse Jiryu Davis в его блоге.

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

Она может быть полезна, когда вы создаете перевод для неоднозначных строк. Допустим есть слово “bat”, которое нужно вывести либо на английском, либо на русском, в зависимости от языка пользователя. Для этого можно воспользоваться соответствующими функциями перевода.

Например так (html шаблон):

<div>{{_("Bat")}}</div>

Далее мы с помощью утилиты xgettext создадим файл перевода, в котором будет что-то такое (подробно про процесс i18n можно почитать тут)

msgid "Bat"
msgstr ""

Теперь на месте пустой строки нам нужно вставить перевод. Но что означает слово “Bat”? В английском языке это слово может означать “летучая мышь”, а может “дубина”, в зависимости от контекста. Переводчику будет очень трудно понять, что же имелось в виду.

Вот где пригодится функция pgettext, ей в качестве первого аргумента передается контекст фразы:

<div>{{ pgettext("mammal", "Bat") }}</div>

При генерации перевода нужно дополнительно указать такие опции для утилиты xgettext:

--keyword=pgettext:1c,2 --keyword=pgettext:1c,2,3

После этого файл перевода будет выглядеть так:

msgctxt "mammal"
msgid "Bat"
msgstr ""

Переводчик поймет, что в данном случае имелась в виду именно летучая мышь, поэтому перевод однозначен:

msgctxt "mammal"
msgid "Bat"
msgstr "Летучая мышь"

Множественные формы так же поддерживаются:

<div>{{ pgettext("mammal", "Bat", "Bats", 2) }}</div>

В python коде (не в шаблоне) это будет выглядеть так:

class HomeHandler(tornado.web.RequestHandler):

    def get(self):
        self.render("home.html", text=self.locale.pgettext("mammal", "Bat", "Bats", 2))

Сам перевод множественных значений:

msgctxt "mammal"
msgid "Bat"
msgid_plural "Bats"
msgstr[0] "Летучая мышь"
msgstr[1] "Летучие мыши"
msgstr[2] "Летучих мышей"