FormatJS опирается на ICU MessageFormat — формализованный язык описания строк интернационализации, в котором текст перестаёт быть простой строкой и становится структурированным выражением с параметрами, условиями и форматированием.
Ключевым элементом нотации выступают фигурные скобки:
{variable}
Фигурные скобки обозначают вставку значения из контекста выполнения. Внутри может находиться идентификатор параметра, путь к значению или выражение форматирования.
Простейшая форма:
Hello, {name}
Здесь name — именованный параметр, подставляемый в
строку во время рендеринга.
Имена внутри фигурных скобок подчиняются строгим правилам:
_Пример корректной нотации:
{userName}
{item_count}
{price1}
Некорректные формы:
{user-name}
{1price}
{user name}
Каждая переменная интерпретируется как ключ в объекте значений, передаваемом в форматтер.
Фигурные скобки являются служебными символами, поэтому для их отображения в тексте применяются экранирующие конструкции.
Обычный текст с фигурными скобками:
'{' and '}'
Также используется апостроф как управляющий символ экранирования:
It''s a test
Двойной апостроф интерпретируется как один символ '.
Если необходимо вывести текст, содержащий ICU-синтаксис буквально, используется экранирование:
'{'name'}'
FormatJS расширяет простую подстановку переменных через форматные функции.
Синтаксис:
{value, type, format}
Где:
value — переменнаяtype — тип форматированияformat — конкретный стиль или правилоЧисла форматируются через тип number.
Пример:
{price, number}
С указанием стиля:
{price, number, currency}
Возможные форматы:
integerpercentcurrencyПример с валютой:
{balance, number, currency}
Под капотом используется Intl.NumberFormat, а
ICU-нотация лишь задаёт декларативную оболочку.
Тип date и time задают правила отображения
временных значений.
{createdAt, date}
{createdAt, time}
Стили:
{createdAt, date, short}
{createdAt, date, medium}
{createdAt, date, long}
{createdAt, date, full}
Пример комбинированной логики:
{createdAt, date, long} {createdAt, time, short}
Каждый формат транслируется в Intl.DateTimeFormat.
Одним из наиболее сложных элементов нотации является обработка множественного числа.
Синтаксис:
{count, plural, one {1 item} other {# items}}
Структура:
count — переменнаяplural — тип конструкцииone, few, many,
other — категории языкаСимвол # внутри блока заменяется значением
переменной.
Пример:
{apples, plural, one {# apple} other {# apples}}
Для языков со сложной морфологией возможно расширение:
{count, plural,
=0 {no items}
one {1 item}
other {# items}
}
Категория =0 обозначает точное совпадение значения.
Конструкция select используется для выбора варианта на
основе строкового значения.
{gender, select,
male {He}
female {She}
other {They}
}
Значение gender сопоставляется с ключами внутри блока,
после чего выбирается соответствующий текст.
Особенность нотации заключается в строгом соответствии ключей строковым значениям без преобразования типов.
FormatJS допускает вложенные конструкции, что позволяет комбинировать plural и select.
Пример:
{gender, select,
male {{count, plural, one {He has # item} other {He has # items}}}
female {{count, plural, one {She has # item} other {She has # items}}}
other {{count, plural, one {They have # item} other {They have # items}}}
}
Здесь каждая ветка содержит собственную plural-логику, формируя многоуровневую грамматику.
FormatJS допускает использование именованных шаблонов через
MessageFormat API.
Структура сообщения обычно задаётся через объект:
{
id: "cart.items",
defaultMessage: "{count, plural, one {# item} other {# items}}"
}
Поле id выступает ключом локализации, а
defaultMessage содержит ICU-нотацию.
ICU-синтаксис позволяет комбинировать текстовые и форматные элементы в одной строке.
Пример:
Hello {name}, you have {count, plural, other {# messages}} since {date, date, short}
Здесь одновременно используются:
Порядок элементов не фиксирован и зависит от языка локализации.
Внутри ICU-выражений действуют следующие ограничения:
Пример некорректного выражения:
{count, plural, one {1 item,} other {# items}}
Запятая в конце блока может нарушить парсинг.
Помимо стандартных категорий возможно использование точных чисел:
{points, select,
0 {No points}
1 {One point}
other {Many points}
}
Или более формализованная версия plural:
{points, plural,
=0 {No points}
=1 {One point}
other {# points}
}
Символ = фиксирует точное совпадение значения.
ICU позволяет комбинировать форматирование внутри одного выражения:
{amount, number, currency} as of {date, date, medium}
Здесь одновременно применяются:
Такая нотация делает строку декларативной и независимой от логики приложения.
MessageFormat в FormatJS интерпретирует строку как дерево выражений:
Фактически строка превращается в AST-подобную структуру, где каждый элемент имеет тип и набор параметров.
Переносы строк внутри ICU-сообщений сохраняются как часть текста:
Hello {name}
Welcome back
При этом внутри фигурных скобок переносы недопустимы и нарушают синтаксис.
Некоторые символы имеют двойную роль:
{} — структура выражения# — подстановка числового значения в plural, — разделитель параметров' — управляющий символ экранированияКорректная интерпретация зависит от контекста, в котором символ встречается.
ICU MessageFormat обеспечивает единообразие синтаксиса независимо от языка. Одна и та же структура может быть адаптирована под разные грамматические правила без изменения логики выражения.
Пример универсальной формы:
{count, plural, one {# file} other {# files}}
В разных языках интерпретация категорий plural может отличаться, но структура сообщения остаётся неизменной.