ICU MessageFormat представляет собой формальный синтаксис шаблонов сообщений, используемый в экосистеме FormatJS для интернационализации строк. Основная идея заключается в отделении текстовой части сообщения от динамических значений и правил локализации.
Базовая структура сообщения:
{variable}
Любое выражение в фигурных скобках трактуется как плейсхолдер, который подставляется в момент форматирования.
Простейшая форма включает только имя переменной:
Привет, {name}
При форматировании значение name подставляется без
преобразований.
Допускается использование нескольких аргументов:
{firstName} {lastName}
Аргументы могут повторяться внутри одного сообщения, что позволяет переиспользовать значения без дополнительных вычислений.
ICU поддерживает форматирование значений через модификаторы:
{value, type, format}
{price, number}
FormatJS применяет локаль-специфичное форматирование чисел: разделители тысяч, десятичные символы, округление.
Расширенные варианты:
{price, number, currency}
или с указанием валюты через параметры форматирования:
{price, number, ::currency/USD}
Также доступны процентные форматы:
{ratio, number, percent}
{createdAt, date}
{createdAt, time}
Поддерживаются стандартные шаблоны:
{createdAt, date, short}
{createdAt, date, medium}
{createdAt, date, long}
{createdAt, date, full}
ICU допускает кастомные форматы:
{createdAt, date, ::yyyyMMMd}
Для времени аналогично:
{createdAt, time, short}
Конструкция select используется для выбора варианта
строки на основе значения переменной.
Общий формат:
{gender, select,
male {Он пришёл}
female {Она пришла}
other {Они пришли}
}
Ключевым элементом является обязательная ветка other,
которая используется как fallback.
Один из наиболее сложных механизмов ICU — система множественных форм.
Базовый синтаксис:
{count, plural,
one {# элемент}
few {# элемента}
many {# элементов}
other {# элементов}
}
Символ # заменяется текущим значением
count.
Категории one, few, many,
other зависят от языка. Например, в русском языке
используется система с тремя формами:
ICU позволяет смещать значение:
{count, plural, offset:1
one {Ты и ещё # человек}
other {Ты и ещё # человек}
}
Offset уменьшает значение count перед вычислением категорий.
Отдельная форма для порядковых числительных:
{place, selectordinal,
one {#-й}
two {#-й}
few {#-й}
other {#-й}
}
Используется для выражений вроде “1-й”, “2-й”, “3-й”.
ICU допускает комбинирование select и
plural внутри одного выражения.
Пример:
{gender, select,
male {{
count, plural,
one {Он добавил # элемент}
other {Он добавил # элементов}
}}
female {{
count, plural,
one {Она добавила # элемент}
other {Она добавила # элементов}
}}
other {{
count, plural,
one {Добавлен # элемент}
other {Добавлено # элементов}
}}
}
Вложенность увеличивает выразительность, но усложняет читаемость.
Фигурные скобки имеют специальное значение, поэтому используются правила экранирования.
Апостроф (') используется для защиты текста:
'{name}' не будет заменено
Если требуется вывести сам апостроф:
'' → '
Текст внутри сообщения может содержать фигурные скобки только при экранировании:
'{' и '}' используются как литералы
FormatJS поддерживает расширенный синтаксис форматирования через двоеточие и опции ICU:
{value, number, ::compact-short}
Примеры:
{value, number, ::compact-short}
Результат: 1K, 1M
{value, number, ::percent scale/100}
{value, number, ::currency/EUR}
ICU строго определяет структуру:
Пример общей формы:
{var, type,
option1 {text}
option2 {text}
}
ICU не фиксирует набор категорий для plural. Он зависит от CLDR-правил локали.
Основные категории:
Некоторые языки используют только one и
other, другие — более сложные схемы.
В одном сообщении допускается комбинация нескольких типов форматирования:
У {name} {count, plural,
one {# новое уведомление}
few {# новых уведомления}
many {# новых уведомлений}
other {# новых уведомлений}
} от {date, date, short}
Такой подход позволяет объединять числа, даты и условную логику в одной строке.
Whitespace внутри ICU-выражений не влияет на семантику, однако внутри блоков select/plural отступы используются только для читаемости.
Следующий вариант эквивалентен:
{count,plural,one{1}other{many}}
и
{count, plural,
one {1}
other {many}
}
Все значения аргументов интерпретируются как типизированные данные:
При необходимости вывода текста, похожего на ICU-синтаксис, применяется удвоение апострофов:
It''s a value: {value}
Результат:
It's a value: 10
Во всех конструкциях select и plural ветка
other является обязательной логической основой. При
отсутствии совпадения с другими категориями используется именно она.
FormatJS допускает передачу форматтеров через параметры:
{value, number, ::currency/USD compact-short}
Параметры комбинируются в цепочки, формируя итоговое поведение форматирования.
Если значение переменной отсутствует или не соответствует ожидаемому типу:
otherotherICU допускает глубокую вложенность, но каждое вложение увеличивает сложность парсинга и поддержки:
{role, select,
admin {{
count, plural,
one {Администратор обработал # запрос}
other {Администратор обработал # запросов}
}}
user {{
count, plural,
one {Пользователь обработал # запрос}
other {Пользователь обработал # запросов}
}}
other {Операция завершена}
}