В системах локализации выбор текстовых форм в зависимости от
грамматического рода является частью более общей задачи управления
контекстной зависимостью сообщений. В JavaScript-библиотеках
интернационализации, включая Globalize, этот механизм реализуется через
ICU MessageFormat и данные CLDR, где поддерживаются конструкции
select, позволяющие выбирать вариант строки в зависимости
от значения параметра.
Гендерная вариативность сообщений возникает не только в языках с развитой системой рода, но и в языках, где семантический род выражается через местоимения, формы глаголов или лексические замены. В интернационализационных системах это решается через унифицированный механизм выбора вариантов, где пол выступает как один из возможных ключей селектора.
Globalize опирается на данные Unicode CLDR (Common Locale Data
Repository), где хранятся правила форматирования сообщений и языковые
особенности. ICU MessageFormat предоставляет синтаксис, в котором
гендерная логика выражается через select.
Базовая структура ICU-сообщения с выбором по полу:
{gender, select,
male {...}
female {...}
other {...}
}
Каждый ключ (male, female,
other) соответствует значению параметра, передаваемого в
форматтер. При отсутствии совпадения используется ветка
other.
В Globalize работа с гендерными формами осуществляется через
messageFormatter, который компилирует ICU-шаблоны в функции
форматирования.
Подготовка окружения включает загрузку CLDR-данных:
Globalize.load(
require("cldr-data").entireSupplemental(),
require("cldr-data").entireMainFor("ru")
);
Globalize.locale("ru");
Далее создаётся форматтер сообщений:
const message = Globalize.messageFormatter(
"{gender, select, male {Он вошёл} female {Она вошла} other {Они вошли}}"
);
Использование:
message({ gender: "male" }); // Он вошёл
message({ gender: "female" }); // Она вошла
message({ gender: "other" }); // Они вошли
Ключи male и female не являются строго
биологическими категориями. Они отражают лингвистическую классификацию,
которая зависит от языка локали. В некоторых языках различие может
отсутствовать или расширяться.
other выполняет роль универсального fallback-значения. В
системах с агглютинативной или гендерно-нейтральной морфологией именно
эта ветка используется наиболее часто.
ICU MessageFormat позволяет вкладывать конструкции, что особенно важно для сложных фраз, где гендер взаимодействует с числом, падежом или контекстом.
Пример комбинированного шаблона:
{gender, select,
male {{
count, plural,
one {Он отправил # сообщение}
other {Он отправил # сообщений}
}}
female {{
count, plural,
one {Она отправила # сообщение}
other {Она отправила # сообщений}
}}
other {{
count, plural,
one {Отправлено # сообщение}
other {Отправлено # сообщений}
}}
}
В Jav * aScript:
const msg = Globalize.messageFormatter(template);
msg({ gender: "female", count: 3 });
// Она отправила 3 сообщений
Русский язык требует строгого согласования рода, числа и падежа. В контексте Globalize это означает, что гендерный выбор часто комбинируется с plural rules.
При этом важно учитывать:
Пример:
{gender, select,
male {Новый пользователь зарегистрировался}
female {Новая пользовательница зарегистрировалась}
other {Новый пользователь зарегистрировался}
}
В архитектуре приложений гендер не должен быть частью бизнес-логики. Вместо этого он передаётся как параметр форматирования, что позволяет отделить данные от представления.
Пример структуры данных:
const user = {
name: "Alex",
gender: "other"
};
Форматирование:
const greet = Globalize.messageFormatter(
"{gender, select, male {Пользователь вошёл} female {Пользовательница вошла} other {Пользователь вошёл}}"
);
greet(user);
Такой подход обеспечивает масштабируемость при добавлении новых локалей без изменения логики приложения.
Разные языки по-разному обрабатывают гендер:
ICU MessageFormat абстрагирует эти различия, позволяя использовать
единый синтаксис select.
При усложнении сообщений возникает проблема читаемости вложенных конструкций. Globalize не ограничивает глубину вложенности, однако рекомендуется структурировать шаблоны так, чтобы логика оставалась предсказуемой.
Пример многоуровневого шаблона:
{gender, select,
male {{
status, select,
active {Активный пользователь вошёл}
inactive {Неактивный пользователь был обнаружен}
}}
female {{
status, select,
active {Активная пользовательница вошла}
inactive {Неактивная пользовательница была обнаружена}
}}
other {{
status, select,
active {Активный пользователь вошёл}
inactive {Неактивный пользователь был обнаружен}
}}
}
Такие конструкции требуют строгого контроля за структурой данных, передаваемых в форматтер.
Globalize компилирует ICU-шаблоны в функции, что снижает накладные расходы при повторном использовании.
Форматтер создаётся один раз:
const formatter = Globalize.messageFormatter(template);
Дальнейшие вызовы:
formatter(data);
При этом ветвление select выполняется на уровне
скомпилированной функции, без повторного парсинга строки.
Если значение gender не соответствует ни одному ключу,
используется ветка other. При отсутствии other
результат становится неопределённым или приводит к возврату пустой
строки.
Типичные ошибки:
Пример корректной защиты:
{gender, select,
male {...}
female {...}
other {...}
}
Механизм select универсален и применяется не только к
полу, но и к статусам, категориям, ролям и любым дискретным
состояниям.
Пример:
{role, select,
admin {Администратор выполнил действие}
user {Пользователь выполнил действие}
guest {Гость выполнил действие}
}
Таким образом, гендерный select является частным случаем более общей модели контекстного выбора сообщений, реализованной в ICU и используемой в Globalize как базовый инструмент интернационализации.