Видобування¶
Видобування — це крок, що збирає кожне позначене повідомлення з вашого
вихідного коду в шаблон .pot для перекладачів — крок 3 циклу
підручника. Ця сторінка — довідник цього кроку: налаштування,
власні імена функцій, строгий режим для CI та перевірки, що охороняють ваші
каталоги опісля.
Видобуванню потрібен extra babel:
Процес¶
Створіть babel.cfg:
Потім використовуйте звичайні команди Babel:
pybabel extract -F babel.cfg -c "Translators:" -o locales/messages.pot .
pybabel init -i locales/messages.pot -d locales -l ja
pybabel compile -d locales
init запускається один раз на мову; далі pybabel update вливає кожен
свіжий шаблон у наявні каталоги. Цей повторюваний цикл — і що його записи
fuzzy означають для релізу — розібрано в
У продакшені.
Видобувач gettext_tstrings обробляє і звичайні виклики _(), gettext()
та ngettext(), тож одне зіставлення покриває мішану кодову базу. Він
розпізнає _(), чотири стандартні імена gettext, псевдоніми tr() / ntr()
і відкладені lazy_gettext() / lazy_pgettext().
Увімкніть коментарі для перекладачів через -c
pybabel extract збирає коментарі для перекладачів лише тоді, коли ви
передаєте -c "Translators:", — точно як для звичайних викликів gettext.
Пропустіть його — і видобування все одно спрацює: коментарі просто ніколи
не потраплять до каталогу, де вони є найдешевшим важелем якості
в усьому процесі.
Реєстрація власних імен функцій¶
Файл ini дає один рядок, TOML-зіставлення дає список, а всередині рядка імена розділяються пробілами або комами. Працюють усі чотири написання.
Доступні опції: tr_functions, ntr_functions, gettext_functions,
ngettext_functions, pgettext_functions і npgettext_functions.
-k не дістає до t-рядка
Власний помічник на кшталт mytr(t"…") мусить бути названий в одній з
опцій вище. Механізм --keyword у Babel не вміє читати літерал t-рядка,
тож pybabel extract -k mytr нічого не знаходить і нічого не каже —
повідомлення просто відсутні в POT. -k і далі працює для звичайних
викликів gettext, що видобуваються поруч.
Підтримується лише стандартний порядок аргументів: спершу повідомлення;
контекст, потім повідомлення для pgettext; контекст, однина, множина
для npgettext.
М'яко локально, строго в CI¶
За замовчуванням один поганий файл не завершує прогін:
- t-рядок, який видобувач відхиляє, — доступ до атрибута, вираз, хибний аргумент — повідомляється попередженням і пропускається.
- Файл, що не парситься, пропускається так само.
- Так само й файл, який відкидає лише
tokenize, тоді якastйого приймає, — на такому власний прохід Babel інакше б аварійно зупинився.
Це зручно, поки ви редагуєте, і небезпечно, коли ні: пропущене повідомлення
просто відсутнє в POT, тож його ніколи не перекладуть, і ніщо про це не
скаже. Установіть strict = true в опціях зіставлення всюди, де за
видобуванням не стежить людина:
Кожне попередження вище тоді стає жорсткою відмовою. Вважайте це продакшн-налаштуванням, а типову поведінку — локальним.
Ваш наявний інструментарій перевіряє ці каталоги¶
Babel позначає кожне видобуте повідомлення стандартним прапорцем, і саме цей один рядок вмикає перевірку заповнювачів в інструментах, які ви вже запускаєте:
Перекладіть його як こんにちは {nombre} — і помилку буде впіймано без
жодного налаштування:
$ msgfmt --check-format -o /dev/null locales/ja/LC_MESSAGES/messages.po
locales/ja/LC_MESSAGES/messages.po:25: a format specification for argument
'name' doesn't exist in 'msgstr'
msgfmt: found 1 fatal error
Weblate документує ту саму перевірку як Python brace format, а комерційні платформи мають власний контроль заповнювачів, зав'язаний на той самий прапорець. Поведінка кожної платформи — її власна; два інструменти нижче — ті, що перевірені тут.
Понад те, пакет реєструє чекер Babel, тож pybabel compile застосовує
правила специфікації до кожного повідомлення з маркерним коментарем
gettext-tstrings:
$ pybabel compile -d locales -l ja
error: locales/ja/LC_MESSAGES/messages.po:24: translation does not match the
source placeholders: {name} is missing; {nombre} is not in the source message
1 errors encountered.
Для повідомлення з множиною вказівник називає форму, бо номер рядка, який
повідомляє Babel, належить msgid, а російський блок має під ним три msgstr:
error: locales/ru/LC_MESSAGES/messages.po:31: msgstr[1]: translation does not
match the source placeholders: {n} is missing
pybabel compile все одно записує .mo
Помилку вище повідомлено, статус виходу — 1, і зламаний каталог усе
одно скомпільовано. Лише цей статус виходу може зупинити конвеєр від його
доставки; Що вартує CI показує крок збірки,
який це робить.
Дві перевірки не дублюють одна одну. Чекер пакета суворіший щонайменше у двох випадках:
- msgid, чиї єдині дужки екрановані (
Config {{raw}} only), ніколи не отримує прапорцяpython-brace-format, тож жоден зовнішній інструмент його взагалі не перевіряє. - Форми множини перевіряються поодинці.
msgfmt --check-formatчитає той самий файл вище і виходить із0; форма, що викидає заповнювач, який тримають її сусідки, там приймається, а тут відхиляється.
msgfmt перевіряє лише імена заповнювачів, які може розпарсити як Python
brace format, тож ASCII-імена зберігають здатність кожного інструмента в
ланцюжку перевіряти повідомлення. Сама бібліотека приймає будь-яке ім'я, для
якого str.isidentifier() істинне.
Шаблонізатори та інші інструменти¶
t-рядки — синтаксис Python, тож ця бібліотека покриває вихідний код Python.
Мови шаблонів і далі користуються власною i18n — {% trans %} у Jinja2,
шаблонні теги Django — та видобувачами Babel для них. Усе живить той самий
PO-каталог, тож один процес перекладу так само покриває мішану кодову базу.
pygettext сьогодні не вміє парсити t-рядки — тому видобування йде через
Babel. Угода записана у специфікації, щоб інший видобувач або
майбутній pygettext міг на неї орієнтуватися.