Комбинирование контекста с плюрализацией

В i18next одновременно применяются два механизма трансформации ключа перевода: контекст (context) и плюрализация (pluralization). Оба механизма влияют на итоговый ключ, по которому выполняется поиск строки в ресурсах, но порядок их применения строго определён и критичен для корректной структуры словарей.

При вызове перевода вида:

t('message', { count: 3, context: 'male' })

формируется цепочка разрешения ключа, где сначала учитывается контекст, затем число.


Порядок разрешения ключа

i18next строит ключ в несколько этапов:

  1. Базовый ключ: message
  2. Добавление контекста: message_male
  3. Применение правила плюрализации: message_male_plural (или message_male_one, message_male_other в зависимости от языка)

Итоговая последовательность поиска:

  • message_male_few (для языков с несколькими формами)
  • message_male_plural
  • message_male_other
  • message_female_plural
  • message_plural
  • message

Фактический набор форм зависит от локали и настроек plural rules.


Структура ключей в ресурсах

Комбинация context + plural требует предсказуемой структуры словаря. Обычно применяется схема:

{
  "message": "сообщение",
  "message_male": "сообщение для мужчины",
  "message_female": "сообщение для женщины",

  "message_one": "одно сообщение",
  "message_other": "{{count}} сообщений",

  "message_male_one": "одно сообщение для мужчины",
  "message_male_other": "{{count}} сообщений для мужчины",

  "message_female_one": "одно сообщение для женщины",
  "message_female_other": "{{count}} сообщений для женщины"
}

Контекст добавляется первым суффиксом, plural — вторым.


Инициализация i18next

import i18n from 'i18next';

i18n.init({
  resources: {
    ru: {
      translation: {
        message: "сообщение",
        message_male_one: "одно сообщение для мужчины",
        message_male_other: "{{count}} сообщений для мужчины",
        message_female_one: "одно сообщение для женщины",
        message_female_other: "{{count}} сообщений для женщины"
      }
    }
  },
  lng: 'ru',
  fallbackLng: 'ru',
  interpolation: {
    escapeValue: false
  }
});

Базовый вызов с контекстом и count

i18n.t('message', { count: 1, context: 'male' });
// одно сообщение для мужчины

i18n.t('message', { count: 5, context: 'male' });
// 5 сообщений для мужчины

Если контекст отсутствует, используется базовая форма plural:

i18n.t('message', { count: 2 });
// 2 сообщений

Влияние порядка применения context и plural

Контекст всегда применяется до плюрализации. Это означает, что логически формируется «подключаемая подгруппа» переводов, внутри которой уже применяется языковая грамматика числа.

Схема поиска ключа:

baseKey
→ baseKey + '_' + context
→ baseKey + '_' + context + '_' + pluralForm

Такой порядок исключает пересечения между контекстами и формами множественного числа.


Поведение при отсутствии полного совпадения

Если отсутствует ключ, включающий и context, и plural, выполняется деградация поиска:

  1. message_male_other
  2. message_male
  3. message_other
  4. message

Пример:

i18n.t('message', { count: 3, context: 'female' });

Если отсутствует message_female_other, но существует message_other, будет использована fallback-форма без контекста.


Использование нестандартного разделителя контекста

По умолчанию i18next использует _ как разделитель. Поведение регулируется настройкой:

i18n.init({
  contextSeparator: '#'
});

Тогда структура ключей меняется:

{
  "message#male_one": "одно сообщение для мужчины",
  "message#male_other": "{{count}} сообщений для мужчины"
}

Это важно при интеграции с существующими системами локализации, где _ уже используется в ключах.


Комбинация с языковыми plural rules

Plural формы определяются языком и могут включать более двух категорий. Например:

  • one
  • few
  • many
  • other

В языках с расширенной системой множественного числа структура расширяется автоматически:

{
  "car_male_one": "1 машина для мужчины",
  "car_male_few": "{{count}} машины для мужчины",
  "car_male_many": "{{count}} машин для мужчины",
  "car_male_other": "{{count}} машин для мужчины"
}

Вызов:

i18n.t('car', { count: 7, context: 'male' });

Интерполяция внутри context + plural

Интерполяция применяется после выбора финального ключа.

{
  "item_female_other": "{{user}} имеет {{count}} элементов"
}
i18n.t('item', {
  context: 'female',
  count: 3,
  user: 'Анна'
});

Результат:

Анна имеет 3 элементов

Взаимодействие с отсутствующими значениями count

Если count не передан, plural механизм не активируется, даже при наличии plural-ключей.

i18n.t('message', { context: 'male' });

Поиск ограничивается:

  • message_male
  • message

Plural-формы игнорируются полностью.


Контекст как переключатель смысловых веток

Контекст не ограничивается гендером. Он используется как семантический переключатель:

{
  "notification_email_one": "1 письмо",
  "notification_email_other": "{{count}} писем",

  "notification_push_one": "1 уведомление",
  "notification_push_other": "{{count}} уведомлений"
}
i18n.t('notification', { context: 'email', count: 2 });

Контекст формирует отдельную ветку, внутри которой применяется plural.


Множественные контексты через расширение ключей

i18next поддерживает один context, но на практике реализуется расширение через составные ключи:

{
  "message_male_admin_one": "одно сообщение администратору",
  "message_male_admin_other": "{{count}} сообщений администратору"
}
i18n.t('message', {
  context: 'male_admin',
  count: 4
});

Фактически context становится строкой-композицией, увеличивая количество возможных ветвлений.


Приоритет ключей при сложных комбинациях

При одновременном наличии нескольких вариантов применяется следующий приоритет:

  1. key + context + plural
  2. key + context
  3. key + plural
  4. key

Это гарантирует предсказуемое поведение даже при неполной локализации.


Особенности организации ресурсов

При масштабировании словарей возникает необходимость строгого разделения:

  • базовые ключи без модификаторов
  • контекстные ветки
  • plural-варианты внутри контекста

Рекомендуемая структура:

{
  "order": {
    "male": {
      "one": "1 заказ",
      "other": "{{count}} заказов"
    },
    "female": {
      "one": "1 заказ",
      "other": "{{count}} заказов"
    }
  }
}

Однако при использовании flat-структуры i18next всё равно корректно разрешает ключи через суффиксы.


Влияние fallbackLng на context + plural

При отсутствии ключа в текущей локали выполняется переход в fallback-язык с сохранением всей цепочки:

message_male_one → fallback message_male_one → fallback message_one → message

Контекст и plural не теряются в процессе fallback-поиска, они сохраняются как часть ключа.


Конфликты между context и custom pluralSuffix

В редких случаях pluralSuffix может конфликтовать с contextSeparator. При нестандартных конфигурациях важно учитывать:

  • context добавляется до pluralSuffix
  • pluralSuffix зависит от языка
  • порядок не изменяется настройками

Формально:

key + contextSeparator + context + pluralSuffix

Поведение с опцией returnObjects

При включённом returnObjects возможно хранение вложенных структур, где context и plural формируют дерево:

{
  "message": {
    "male": {
      "one": "..."
    }
  }
}

В этом случае механизм ключей заменяется доступом к объекту, но логика context + plural сохраняется на уровне структуры.