Составные значения представляют собой результат объединения нескольких локализуемых элементов в одну связную строку с учётом правил конкретной локали. В отличие от простого форматирования чисел, дат или валют, здесь важна структура выражения: порядок элементов, разделители, грамматические согласования и контекстные формы.
В международной локализации составные значения возникают в типичных сценариях:
Globalize опирается на CLDR (Common Locale Data Repository), где описаны правила соединения элементов и языковые особенности для разных локалей, включая пунктуацию, пробелы, типографику и морфологические формы.
В основе работы с составными значениями лежит принцип шаблона: данные подставляются в заранее определённую структуру, адаптированную под локаль.
Простейший пример:
Globalize.locale("en");
Globalize.formatMessage(
"{count} items in {category}",
{ count: 5, category: "books" }
);
В разных локалях этот же шаблон может менять:
Один из наиболее частых типов составных значений — число с единицей измерения.
const globalize = Globalize("en");
globalize.formatUnit(5, "meter");
Результат зависит от локали:
5 meters5 метров5 メートルОсобенность составных значений в этом контексте заключается в том, что единица измерения не является статической строкой. Она участвует в морфологическом согласовании с числом.
Внутренне система использует правила CLDR Unit Patterns, которые определяют шаблоны вида:
{0} meter
{0} meters
Диапазоны представляют собой частный случай составного форматирования, где два значения соединяются в единое выражение.
globalize.formatNumberRange(10, 20);
В зависимости от локали формируется:
10–2010–2010–20Однако различия могут проявляться в:
Процент как составное значение часто зависит от контекста:
globalize.formatNumber(0.25, { style: "percent" });
Результат:
25%25 %В составных выражениях процент может комбинироваться с другими элементами:
globalize.formatMessage(
"{value} of {total} ({percent}%)",
{
value: 25,
total: 100,
percent: 25
}
);
Здесь формируется единая структура, где каждый элемент локализуется отдельно, но соединяется по правилам шаблона.
Форматирование валюты становится составным значением, когда оно включается в более сложные конструкции.
globalize.formatCurrency(1000, "USD");
Однако в составе сообщения:
globalize.formatMessage(
"Price: {price} per item",
{ price: globalize.formatCurrency(1000, "USD") }
);
Важный аспект заключается в том, что валюта уже содержит локализованный формат, включая:
При комбинировании с другими элементами необходимо учитывать, что результат не является «сырой строкой», а уже структурированным фрагментом.
Списки представляют собой особый класс составных значений, где важна грамматика соединения элементов.
globalize.formatList(["apples", "bananas", "oranges"]);
Результаты:
apples, bananas, and orangesяблоки, бананы и апельсиныCLDR определяет несколько типов списков:
Каждый тип влияет на:
Наиболее гибкий механизм — шаблонные сообщения, где несколько параметров взаимодействуют между собой.
const msg = "{user} has {count} new message(s) in {folder}";
globalize.formatMessage(msg, {
user: "Alex",
count: 3,
folder: "Inbox"
});
Однако реальная сложность появляется при добавлении правил множественного числа.
const msg =
"{count, plural, one {# message} other {# messages}} for {user}";
globalize.formatMessage(msg, {
count: 3,
user: "Alex"
});
Здесь составное значение включает:
В разных локалях правила plural categories отличаются, что делает структуру полностью зависимой от языка.
Составные значения могут быть вложенными, образуя иерархические структуры.
globalize.formatMessage(
"{user} spent {amount} on {items}",
{
user: "Maria",
amount: globalize.formatCurrency(250, "EUR"),
items: globalize.formatList(["books", "notebooks"])
}
);
В этом случае:
amount уже является составным значением (валюта);items является составным списком;Особенность вложенности заключается в том, что каждый уровень уже локализован до интеграции в общий шаблон.
В языках с развитой морфологией составные значения требуют согласования:
Пример:
globalize.formatMessage(
"{count} {unit} available",
{
count: 5,
unit: "файл"
}
);
В корректной локализации слово «файл» изменяется:
Globalize использует CLDR правила pluralization, которые позволяют динамически выбирать правильную форму внутри составного выражения.
Даты часто участвуют в сложных выражениях:
globalize.formatDate(new Date());
В составе сообщения:
globalize.formatMessage(
"Event starts at {time} on {date}",
{
time: globalize.formatTime(new Date()),
date: globalize.formatDate(new Date())
}
);
Локализация влияет на:
Реальные приложения часто комбинируют несколько типов форматирования:
globalize.formatMessage(
"{user} purchased {count} items for {total} on {date}",
{
user: "Ivan",
count: 4,
total: globalize.formatCurrency(1200, "USD"),
date: globalize.formatDate(new Date())
}
);
Такое сообщение включает:
Каждый элемент независимо локализуется, но итоговое сообщение зависит от синтаксиса конкретного языка.
При работе с составными значениями ключевыми становятся следующие принципы:
На практике часто возникают типичные проблемы:
Корректная модель предполагает, что каждое значение форматируется отдельно и только затем включается в итоговую структуру.
Составное сообщение можно представить как дерево:
корневой шаблон сообщения;
параметры:
правила локали:
Globalize обеспечивает согласованность этой структуры за счёт стандартизированных данных CLDR и единых механизмов форматирования.