Interval postprocessor в i18next используется для интервальной обработки числовых значений при формировании текста, когда стандартной плюрализации оказывается недостаточно. Основная задача механизма — выбор варианта строки не по языковым правилам множественного числа, а по заданным числовым диапазонам, что особенно важно для бизнес-логики, статистики, таймеров, прогрессов и любых случаев, где требуется явное управление интервалами.
Постпроцессоры в i18next представляют собой этап обработки результата
t() после подстановки интерполяций и выбора ключа перевода.
Они позволяют модифицировать итоговую строку без изменения исходных
ресурсов.
Регистрация постпроцессора выполняется через механизм расширения:
i18next.use(postProcessor);
После подключения становится доступен дополнительный этап обработки,
который можно активировать через параметр postProcess при
вызове перевода.
Interval postprocessor предназначен для интерпретации числовых
диапазонов и выбора соответствующего варианта строки на основе значения
count или другого числового параметра.
Ключевая особенность — замена стандартной plural-логики на декларативные диапазоны:
(a-b)(n-inf)Это позволяет описывать сложные языковые и бизнес-формы без привязки к CLDR plural rules.
Интервалы задаются внутри строки перевода в виде набора правил:
(0){...}
(1){...}
(2-4){...}
(5-20){...}
(21-inf){...}
Каждое правило состоит из двух частей:
Поддерживаемые формы диапазонов:
(n) — точное совпадение(a-b) — включительный диапазон(a-inf) — всё от a и выше(-inf-b) — всё до b включительноАлгоритм обработки выполняет последовательный разбор выражений слева направо. При первом совпадении диапазона с входным значением возвращается соответствующий блок текста.
Приоритет определяется порядком записи, а не специфичностью диапазона, что делает критически важным корректное расположение правил.
В экосистеме i18next интервал обычно подключается как отдельный модуль:
import i18next from 'i18next';
import IntervalPostProcessor from 'i18next-interval-postprocessor';
i18next.use(IntervalPostProcessor).init({
lng: 'ru',
resources: {
ru: {
translation: {
apples: '(0){нет яблок} (1){{{count}} яблоко} (2-4){{{count}} яблока} (5-inf){{{count}} яблок}'
}
}
}
});
После регистрации становится доступным использование постпроцессора
через параметр postProcess.
Вызов перевода с интервалами требует передачи числового значения и активации постпроцессора:
i18next.t('apples', {
count: 0,
postProcess: 'interval'
});
Изменение значения count приводит к выбору другого
интервала:
i18next.t('apples', {
count: 3,
postProcess: 'interval'
});
Значение 3 попадает в диапазон (2-4).
Интервальные блоки поддерживают стандартную интерполяцию i18next. Переменные подставляются после выбора соответствующего диапазона:
"messages": "(0){пусто} (1){{{count}} элемент} (2-inf){{{count}} элементов}"
Использование:
i18next.t('messages', {
count: 12,
postProcess: 'interval'
});
Стандартная система plural в i18next опирается на языковые правила CLDR, которые определяют формы множественного числа в зависимости от локали.
Interval postprocessor полностью игнорирует эти правила и заменяет их числовыми диапазонами.
Ключевые отличия:
"onlineUsers": "(0){нет пользователей} (1){1 пользователь} (2-4){{{count}} пользователя} (5-inf){{{count}} пользователей}"
"progress": "(0){не начато} (1-30){начальный этап} (31-70){в процессе} (71-99){почти готово} (100){завершено}"
"time": "(0){сейчас} (1-59){{{count}} минут назад} (60-119){час назад} (120-inf){{{count}} минут назад}"
Отрицательные числа могут быть обработаны через явное указание диапазонов:
(-inf- -1){ошибка} (0){ноль} (1-inf){{{count}}}
Поведение зависит от реализации постпроцессора и требует явного контроля.
При передаче float значения обычно приводятся к числовому сравнению без округления логики интервалов. Это может приводить к неожиданным результатам, поэтому чаще применяется предварительное округление:
i18next.t('key', {
count: Math.floor(value),
postProcess: 'interval'
});
i18next поддерживает цепочки постпроцессоров:
i18next.t('key', {
count: 3,
postProcess: ['interval', 'uppercase']
});
В этом случае результат интервалов сначала вычисляется, затем преобразуется вторым постпроцессором.
Порядок выполнения критически важен, так как каждый этап работает с результатом предыдущего.
Interval-строки обычно располагаются в стандартных переводах, без выделения отдельного namespace. Однако при сложных системах локализации часто выделяются отдельные группы:
resources: {
ru: {
stats: {
users: '(0){нет} (1){1} (2-inf){{{count}}}'
}
}
}
Вызов:
i18next.t('stats:users', {
count: 7,
postProcess: 'interval'
});
Interval postprocessor выполняет парсинг строки на каждом вызове
t(). При большом количестве переводов это создаёт нагрузку,
особенно при динамических интерфейсах.
Оптимизационные подходы включают:
Если ключ одновременно содержит plural-формы и interval-выражения, поведение определяется порядком постобработки. Interval полностью переопределяет выбор формы, игнорируя plural rules.
Пример конфликтной структуры:
"key_one": "one",
"key_other": "other",
"key": "(0){none} (1){one} (2-inf){many}"
В режиме interval plural-формы не используются.
postProcess: 'interval'Пример проблемной конфигурации:
(1-5){A} (3-10){B}
Значение 3 попадёт в первое совпадение
(1-5), что может быть неочевидным.
Interval postprocessor часто используется как слой над доменной логикой:
В таких сценариях интервал выступает декларативной моделью состояний, заменяя условные конструкции в коде.