Переклад#

Для того, щоб Ваш бот володів декількома мовами, необхідно додати мінімальну кількість хуків до вашого Python коду

Ці хуки звуться рядками передкладу

Утиліти перекладу побудовані на основі модулю GNU gettext Python і Babel library.

Встановлення#

Babel потрібний для забезпечення простоти експорту рядків перекладу з Вашого коду.

Можна встановити безпосередньо з pip:

pip install Babel

чи як додаткову залежність aiogram:

pip install aiogram[i18n]

Як зробити повідомлення перекладаваними?#

Для того, щоб gettext знав які рядки слід перекласти, Вам необхідно відмітити рядки перекладу.

Наприклад:

from aiogram import html
from aiogram.utils.i18n import gettext as _

async def my_handler(message: Message) -> None:
    await message.answer(
        _("Hello, {name}!").format(
            name=html.quote(message.from_user.full_name)
        )
    )

Небезпека

f-рядки не можна використовувати як рядки перекладу, оскільки будь-які динамічні змінні слід додати до повідомлення після отримання перекладеного повідомлення

Крім того, якщо Ви бажаєте використати перекладений рядок у фільтрах, Вам треба використати відкладений переклад (lazy gettext):

from aiogram import F
from aiogram.utils.i18n import lazy_gettext as __

@router.message(F.text == __("My menu entry"))
...

Небезпека

Відкладені виклики gettext слід завжди використовувати, коли поточна мова на даний момент невідома.

Небезпека

Відкладені виклики gettext не можна використовувати як значення для методів API або будь-якого об’єкта Telegram (наприклад, aiogram.types.inline_keyboard_button.InlineKeyboardButton тощо)

Working with plural forms

The gettext from aiogram.utils.i18n is the one alias for two functions _gettext_ and _ngettext_ of GNU gettext Python module. Therefore, the wrapper for message strings is the same _(). You need to pass three parameters to the function: a singular string, a plural string, and a value.

Налаштування рушія#

Коли ваші повідомлення вже готові використовувати gettext, Ваш бот повинен знати, як визначити мову користувача.

Поруч з місцем ініціалізації диспетчера має бути створений екземпляр перекладача:class:aiogram.utils.i18n.I18n.

i18n = I18n(path="locales", default_locale="en", domain="messages")

Після цього Вам потрібно буде вибрати одну з вбудованих проміжних програм (middleware) I18n або написати власну.

Вбудовані проміжні програми:

SimpleI18nMiddleware#

class aiogram.utils.i18n.middleware.SimpleI18nMiddleware(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[source]#

Проста I18n проміжна програма.

Вибирає код мови з об’єкта User, отриманого в події.

__init__(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[source]#

Створення екземпляру проміжної програми.

Параметри:
  • i18n – екземпляр I18n

  • i18n_key – ключ (назва ключа) екземпляру I18n в контексті

  • middleware_key – контекстний ключ для цієї проміжної програми

ConstI18nMiddleware#

class aiogram.utils.i18n.middleware.ConstI18nMiddleware(locale: str, i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[source]#

Проміжна програма Const вибирає статично визначену локаль.

__init__(locale: str, i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[source]#

Створення екземпляру проміжної програми.

Параметри:
  • i18n – екземпляр I18n

  • i18n_key – ключ (назва ключа) екземпляру I18n в контексті

  • middleware_key – контекстний ключ для цієї проміжної програми

FSMI18nMiddleware#

class aiogram.utils.i18n.middleware.FSMI18nMiddleware(i18n: I18n, key: str = 'locale', i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[source]#

Ця проміжна програма зберігає локаль у сховищі FSM.

__init__(i18n: I18n, key: str = 'locale', i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[source]#

Створення екземпляру проміжної програми.

Параметри:
  • i18n – екземпляр I18n

  • i18n_key – ключ (назва ключа) екземпляру I18n в контексті

  • middleware_key – контекстний ключ для цієї проміжної програми

async set_locale(state: FSMContext, locale: str) None[source]#

Запис нової локалі у сховище

Параметри:
  • state – екземпляр FSMContext

  • locale – нова локаль

I18nMiddleware#

або визначте вашу власну проміжну програму, основану на абстракції I18nMiddleware:

class aiogram.utils.i18n.middleware.I18nMiddleware(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[source]#

Абстракція проміжної програми I18n

__init__(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[source]#

Створення екземпляру проміжної програми.

Параметри:
  • i18n – екземпляр I18n

  • i18n_key – ключ (назва ключа) екземпляру I18n в контексті

  • middleware_key – контекстний ключ для цієї проміжної програми

abstract async get_locale(event: TelegramObject, data: Dict[str, Any]) str[source]#

Визначення поточної мови користувача на основі події та контексту.

Цей метод повинен бути перевизначеним у дочірніх класах

Параметри:
  • event

  • data

Повертає:

setup(router: Router, exclude: Set[str] | None = None) BaseMiddleware[source]#

Реєстрація проміжної програми для всіх подій у Роутері

Параметри:
  • router

  • exclude

Повертає:

Працюємо з Babel#

Крок 1: Видобування текстів#

pybabel extract --input-dirs=. -o locales/messages.pot

Де --input-dirs=.- шлях до коду, locales/messages.pot — це шаблон, куди витягуватимуться повідомлення, а messages — домен перекладу.

Working with plural forms

Extracting with Pybabel all strings options:

  • -k _:1,1t -k _:1,2 - for both singular and plural

  • -k __ - for lazy strings

pybabel extract -k _:1,1t -k _:1,2 -k __ --input-dirs=. -o locales/messages.pot

Примітка

Деякі корисні опції:

  • Для додавання коментарів для перекладачів, ви можете використовувати інший тег, якщо хочете (TR) --add-comments=NOTE

  • Contact email for bugreport --msgid-bugs-address=EMAIL

  • Вимкнути коментарі з розташуванням рядків у коді --no-location

  • Copyrights --copyright-holder=AUTHOR

  • Встановлення назви проекту --project=MySuperBot

  • Встановлення версії --version=2.2

Крок 2: Ініціалізація перекладу#

pybabel init -i locales/messages.pot -d locales -D messages -l en
  • -i locales/messages.pot - попередньо створений шаблон

  • -d locales- тека перекладів

  • -D messages - домен перекладів

  • -l en - мова. Може бути змінений на будь-який інший дійсний код мови (Наприклад -l uk для української мови)

Крок 3: Переклад текстів#

Щоб відкрити файл .po, ви можете використовувати базовий текстовий редактор або будь-який редактор .po файлів, напр. Poedit

Просто відкрийте файл із назвою locales/{language}/LC_MESSAGES/messages.po і впишіть переклади

Крок 4: Компіляція перекладів#

pybabel compile -d locales -D messages

Крок 5: Оновлення текстів#

Коли ви змінюєте код свого бота, вам потрібно оновити файли .po і .mo

  • Крок 5.1: відновлення файлу .pot: команда з кроку 1

  • Крок 5.2: оновлення .po файлів
    pybabel update -d locales -D messages -i locales/messages.pot
    
  • Крок 5.3: оновлення Ваших перекладів: розміщення та інструменти Ви знаєте з кроку 3.

  • Крок 5.4: компіляція .mo файлів : команда з кроку 4