Як працювати з перекладами
У прикладі використовуються файли каталогів GNU gettext:
locale/messages.pot— шаблон із текстами, зібраними з вихідного коду.locale/<мова>/LC_MESSAGES/messages.po— переклади для певної мови.messages.mo— скомпільований каталог, який використовує застосунок.
Формат gettext підтримують багато онлайн-сервісів перекладу, зокрема Crowdin і Transifex. Для роботи з файлами .po також є спеціальні редактори, наприклад Poedit.
Докладний посібник із перекладу застосунків за допомогою gettext є у статті Lokalise.
Для повторюваних дій у прикладі налаштовані завдання Poe the Poet. Запускайте їх із каталогу example/. Ці завдання особливо зручні, коли застосунок має кілька мов: вони оновлюють або компілюють каталоги всіх мов за один запуск, тож не потрібно повторювати команди для кожної мови окремо.
Перед запуском встановіть GNU gettext і Poe the Poet. Якщо Poe ще не встановлено, це можна зробити командою:
uv tool install poethepoet
Саме такі визначення завдань використовуються в example/pyproject.toml:
[tool.poe.tasks]
run = "streamlit run app.py"
xgettext.shell = "xgettext -d messages -o ./locale/messages.pot *.py --from-code=UTF-8 --no-location"
msgfmt = "find ./locale -name \\*.po -execdir msgfmt messages.po -o messages.mo \\;"
msgmerge.shell = "find locale -name '*.po' -exec msgmerge -U {} locale/messages.pot \\; && find locale -name '*.po~' -delete"
xgettext збирає рядки з Python-файлів у спільний шаблон. msgmerge оновлює за ним усі наявні каталоги .po та видаляє резервні файли, а msgfmt компілює всі каталоги .po у файли .mo. Усі ці команди входять до GNU gettext, а Poe лише запускає налаштовані завдання.
1. Позначте текст для перекладу
Обгортайте рядки, які побачить користувач, у gettext (зазвичай імпортовану як _). Для форм однини й множини використовуйте ngettext. Наприклад:
st.write(_("Squirrel application"))
ngettext("One squirrel", "%(num)d squirrels", count)
2. Зберіть рядки з коду
Після додавання або зміни рядків, які потрібно перекласти, сформуйте шаблон повідомлень:
poe xgettext
Завдання запускає xgettext для Python-файлів у каталозі example/ та оновлює locale/messages.pot.
3. Оновіть каталоги й додайте переклади
Об’єднайте актуальний шаблон з усіма наявними каталогами .po:
poe msgmerge
Відкрийте файли locale/<мова>/LC_MESSAGES/messages.po та перекладіть значення msgstr. Не змінюйте підстановки на кшталт %(num)d. Для множинних форм перекладіть усі варіанти msgstr[n], потрібні для цієї мови.
Під час оновлення каталогу msgmerge може позначити запис прапорцем fuzzy, якщо вихідний текст змінився, але схожий на попередній. Старий переклад переноситься як підказка, проте він може вже не підходити. Перевірте його й видаліть прапорець fuzzy: msgfmt пропускає такі записи, тому застосунок не зможе їх використовувати.
Завдання оновлює вже створені каталоги. Щоб додати нову мову, спочатку створіть для неї файл .po.
4. Скомпілюйте переклади й перевірте результат
Скомпілюйте каталоги перекладів у файли .mo:
poe msgfmt
Запустіть приклад і перевірте переклади в застосунку:
poe run
Коли вихідні рядки зміняться, знову виконайте poe xgettext і poe msgmerge, перекладіть нові або змінені записи та повторно скомпілюйте каталоги.