Skip to content

🌎 Переводы

Введение

Для поддержки многоязычия в PBModular встроена система переводов. Модули могут предоставлять переводы для разных языков, и фреймворк автоматически загрузит и сделает их доступными, основываясь на глобальной языковой конфигурации бота.

Шаг 1: Создание файлов перевода

  1. Внутри каталога вашего модуля создайте папку с именем strings/.
  2. Внутри strings/ создайте YAML-файлы для каждого языка, который вы хотите поддерживать. В имени файла должен быть указан код языка ISO 639-1 (например, en.yaml, ru.yaml, es.yaml).
  3. Структурируйте переводы в файлах YAML, используя вложенные ключи для организации.

Пример strings/en.yaml:

yaml
# strings/en.yaml
greeting: "Hello, {user}!"
farewell: Goodbye, {user}!
errors:
  not_found: "Sorry, the item could not be found."
  permission_denied: |
  	You do not have permission to do that.
  	{user}

Шаг 2: Загрузка переводов

Во время инициализации модуля BaseModule автоматически:

  1. Сканирует каталог strings/.
  2. Загружает все найденные валидные файлы .yaml в словарь, доступный через self.rawS. Ключами являются коды языков (например, self.rawS['en'], self.rawS['ru']).
  3. Определяет язык для использования на основе глобальной конфигурации бота (config.language и config.fallback_language).
    • Сначала проверяется config.language.
    • Если он не найден в self.rawS, он пробует config.fallback_language.
    • Если запасной язык также не найден, выдается предупреждение и используется первый язык, загруженный в self.rawS.
  4. Загружает переводы выбранного языка (потенциально объединенные с языком резервного копирования для отсутствующих ключей) в self.S. Этот объект self.S является SafeDict, то есть обращение к несуществующему ключу возвращает сам ключ, а не вызывает ошибку KeyError.
  5. Хранит код активного в данный момент языка в self.cur_lang.

Слияние с резервным языком

Если в папке strings/ вашего модуля есть и основной язык (config.language), и запасной язык (config.fallback_language), фреймворк создает объединенный словарь для self.S. Он начинает с копии строк резервного языка, а затем объединяет строки основного языка. Это означает, что любая строка, присутствующая в первичном языке, отменяет значение резервного, но любая строка, отсутствующая в первичном, но присутствующая в резервном, все равно будет доступна.

Шаг 3: Использование переводов в коде

Доступ к переведенным строкам через словарь self.S. Используйте стандартное форматирование строк Python (.format() или f-strings) для вставки переменных.

python
# Внутри метода BaseModule или ModuleExtension

async def greet_user(self, message: Message):
    user_name = message.from_user.first_name
    # Доступ к простой строке
    await message.reply(self.S["greeting"].format(user=user_name))

async def show_help(self, message: Message):
    help_title = self.S["help"]["title"] # Доступ к вложенным ключам
    command_name = "mycommand"
    usage_text = self.S["help"]["usage"].format(command=command_name)
    await message.reply(f"**{help_title}**\n\n{usage_text}")

async def handle_error(self, message: Message, error_key: str):
    # Использование свойства SafeDict: если ключ отсутствует, возвращается сам ключ
    error_message = self.S["errors"][error_key]
    await message.reply(f"Error: {error_message}")

# Пример доступа к необработанным переводам или текущему языку
def log_languages(self):
    self.logger.info(f"Current language code: {self.cur_lang}")
    self.logger.info(f"Available language codes: {list(self.rawS.keys())}")
    # Прямой доступ к конкретному языку (встречается реже)
    # english_farewell = self.rawS.get("en", {}).get("farewell", "Fallback Farewell")

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