Переклад¶
Для того, чтобы Ваш бот володив декилькома мовами, необходимо добавить минимальну килькисть хукив к вашого Python коду
Ци хуки звуться рядками передкладу
Утилити перевода побудовани на основе модулю GNU gettext Python и Babel library.
Всиновлення¶
Babel потрибний для забезпечення простоти експорту рядкив перевода с Вашого коду.
Можна всиновити непосредственно с pip:
pip install Babel
или как кдаткову зависимость litegram:
pip install litegram[i18n]
Как зробити сообщение переводимыми?¶
Для того, чтобы gettext знав которые строки следует перекласти, Вам необходимо видмитити строки перевода.
Например:
from litegram import html
from litegram.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 litegram import F
from litegram.utils.i18n import lazy_gettext as __
@router.message(F.text == __("My menu entry"))
...
Опасно
Отложенные вызовы gettext следует всегда использовать, когда поточна мова на даний момент невидома.
Опасно
Отложенные вызовы gettext не можно использовать как значение для методив API или будь-которого объекта Telegram (например, litegram.types.inline_keyboard_button.InlineKeyboardButton и т.д.)
Working with plural forms
The gettext from litegram.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.
from litegram import html
from litegram.utils.i18n import gettext as _
async def my_handler(message: Message) -> None:
try:
n = int(message.text)
except ValueError:
n = 1
await message.answer(
_("You ordered {n} piece.", "You ordered {n} pieces.",n).format(n)
)
)
Налаштування рушия¶
Когда ваши сообщения уже готовые использовать gettext, Ваш бот должен знати, как определить мову пользователя.
Поруч с мисцем инициализации диспетчера имеет быть созданный экземпляр перекладача:class:litegram.utils.i18n.I18n.
i18n = I18n(path="locales", default_locale="en", domain="messages")
После этого Вам нужно будет вибрати одну с встроенных промижних програм (middleware) I18n или написать власну.
Вбуквани промеждуни программы:
SimpleI18nMiddleware¶
- class litegram.utils.i18n.middleware.SimpleI18nMiddleware(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[исходный код]¶
Проси I18n middleware.
Вибирае код языки с об’еки User, отриманого в события.
- __init__(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[исходный код]¶
Создания екземпляру промеждунои программы.
- Параметры:
i18n – экземпляр I18n
i18n_key – ключ (название ключа) екземпляру I18n в контексти
middleware_key – контекстный ключ для этой промеждунои программы
ConstI18nMiddleware¶
- class litegram.utils.i18n.middleware.ConstI18nMiddleware(locale: str, i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[исходный код]¶
Middleware Const вибирае ситично визначену локаль.
- __init__(locale: str, i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[исходный код]¶
Создания екземпляру промеждунои программы.
- Параметры:
i18n – экземпляр I18n
i18n_key – ключ (название ключа) екземпляру I18n в контексти
middleware_key – контекстный ключ для этой промеждунои программы
FSMI18nMiddleware¶
- class litegram.utils.i18n.middleware.FSMI18nMiddleware(i18n: I18n, key: str = 'locale', i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[исходный код]¶
Ця middleware зберигае локаль в сховищи FSM.
- __init__(i18n: I18n, key: str = 'locale', i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[исходный код]¶
Создания екземпляру промеждунои программы.
- Параметры:
i18n – экземпляр I18n
i18n_key – ключ (название ключа) екземпляру I18n в контексти
middleware_key – контекстный ключ для этой промеждунои программы
- async set_locale(state: FSMContext, locale: str) None[исходный код]¶
Запись новои локали в хранилище
- Параметры:
state – экземпляр FSMContext
locale – нова локаль
I18nMiddleware¶
или визначте вашу власну промижну програму, основану на абстракции I18nMiddleware:
- class litegram.utils.i18n.middleware.I18nMiddleware(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware')[исходный код]¶
Абстракция промеждунои программы I18n
- __init__(i18n: I18n, i18n_key: str | None = 'i18n', middleware_key: str = 'i18n_middleware') None[исходный код]¶
Создания екземпляру промеждунои программы.
- Параметры:
i18n – экземпляр I18n
i18n_key – ключ (название ключа) екземпляру I18n в контексти
middleware_key – контекстный ключ для этой промеждунои программы
- abstractmethod async get_locale(event: TelegramObject, data: dict[str, Any]) str[исходный код]¶
Визначення поточнои языки пользователя на основе события и контекста.
Этот метод должен быть перевизначеним в кчирних класах
- Параметры:
event
data
- Результат:
- setup(router: Router, exclude: set[str] | None = None) BaseMiddleware[исходный код]¶
Реестрация промеждунои программы для всех событий в Роутери
- Параметры:
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=NOTEContact email for bugreport
--msgid-bugs-address=EMAILВимкнути коменири с розишуванням рядкив в коди
--no-locationCopyrights
--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 ruдля русского языка)
Шаг 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