В библиотеке Globalize вложенные конструкции формируют основу сложных сообщений на базе ICU MessageFormat, позволяя объединять условия, множественные формы, переменные и форматирование в единую структуру без потери читаемости и локализационной корректности.
Вложенность в Globalize возникает тогда, когда одно сообщение
содержит внутри себя управляющие конструкции, которые, в свою очередь,
содержат другие конструкции. Это может быть комбинация
select, plural, number,
date и подстановок переменных.
Основная идея заключается в том, что сообщение рассматривается как дерево выражений, где каждый узел может содержать подузлы с собственной логикой.
Простейшая форма сообщения:
Globalize.formatMessage(
"en",
"{count} items"
);
При переходе к вложенности структура усложняется:
Globalize.formatMessage(
"en",
"{count, plural, one {# item} other {# items}}"
);
Здесь plural содержит вложенные подсообщения, зависящие
от значения переменной count.
Одним из ключевых механизмов является комбинирование
plural и select. Эти конструкции часто
используются совместно, формируя многоуровневую логику.
"{gender, select,
male {He has {count, plural, one {# message} other {# messages}}}
female {She has {count, plural, one {# message} other {# messages}}}
other {They have {count, plural, one {# message} other {# messages}}}
}"
В данном примере:
select по полу;plural по количеству сообщений;#, заменяющаяся
числом.Такая структура позволяет описывать сложные грамматические зависимости без дублирования строк.
Вложенные конструкции не ограничиваются только условиями. Переменные могут быть встроены в форматированные выражения.
"{user} has {balance, number, currency} in account"
Добавление вложенного условия:
"{user} has {balance, number, currency}, which is {balance, select,
positive {a positive balance}
zero {no balance}
other {a negative balance}
}"
Здесь одна и та же переменная используется в разных контекстах: как форматированное число и как основа для логического выбора.
Plural-конструкции поддерживают вложенность с другими plural-конструкциями, что особенно важно для языков с несколькими формами множественного числа.
"{apples, plural,
one {You have one apple}
other {
You have {apples} apples, which is {apples, plural,
few {a few}
many {many}
other {some}
}
}
}"
Здесь происходит двойная оценка количества:
Globalize позволяет использовать форматирование прямо внутри сообщений, включая вложенные контексты.
"{eventCount, plural,
one {Last event was on {lastDate, date}}
other {Last {eventCount} events were before {lastDate, date, long}}
}"
Здесь дата форматируется в зависимости от числа событий. Это позволяет связать семантику количества и времени.
Более сложный пример:
"{status, select,
delayed {Delivery delayed until {expectedDate, date, medium}}
onTime {Delivery expected on {expectedDate, date, short}}
cancelled {Delivery cancelled}
}"
При построении сложных интерфейсных сообщений часто требуется комбинировать несколько параметров одновременно.
"{role, select,
admin {{
{count, plural,
one {Admin has one notification}
other {Admin has {count} notifications}
}
}}
user {{
{count, plural,
one {User has one notification}
other {User has {count} notifications}
}
}}
}"
В этом случае вложенность достигает третьего уровня:
Одним из важных аспектов является повторное использование одной переменной в разных частях сообщения без дублирования логики.
"{name} updated {fieldCount, plural,
one {one field: {fields}}
other {{fieldCount} fields: {fields}}
}"
Здесь fields может быть заранее подготовленной строкой,
а fieldCount управляет структурой предложения.
В сложных приложениях часто требуется композиция сообщений, где одно сообщение включается в другое логически, но не напрямую текстово.
"{summary}"
где summary может быть результатом отдельного
вызова:
Globalize.formatMessage("en", "{count, plural, one {...} other {...}}");
И затем используется внутри другого сообщения:
"{user} report: {summary}"
Такой подход позволяет строить многоуровневую систему локализации, где каждый слой отвечает за свою часть логики.
Конструкция other в select и
plural часто используется как уровень вложенного резервного
поведения.
"{subscription, select,
premium {Premium plan active}
basic {Basic plan active}
other {
{trialDays, plural,
one {Trial: 1 day left}
other {Trial: {trialDays} days left}
}
}
}"
Здесь при отсутствии конкретного тарифа система переходит к альтернативной логике, основанной на количестве дней.
При чрезмерной вложенности возрастает сложность поддержки и риск ошибок интерпретации. Практически важные ограничения связаны не с самим Globalize, а с читаемостью ICU-строк.
Типичные проблемы:
Пример чрезмерной вложенности:
"{a, select,
x {{
{b, select,
y {{
{c, plural,
one {{d}}
other {{e}}
}
}}
}
}}
}"
Такие конструкции формально допустимы, но становятся трудно поддерживаемыми.
ICU MessageFormat, используемый в Globalize, рассматривает вложенность как естественное состояние выражения. Любая конструкция может содержать другую конструкцию того же типа или иного типа.
Комбинации:
plural внутри selectselect внутри pluralnumber внутри pluraldate внутри selectформируют единый синтаксический механизм описания языковых правил.
При работе с динамическими данными важно учитывать порядок вычисления вложенных выражений.
Globalize.formatMessage("en", "{x, plural, one {Result: {y}} other {Results: {y}}}");
Значение y может быть как строкой, так и результатом
отдельного форматирования:
{
x: 2,
y: Globalize.formatNumber(12345)
}
В этом случае вложенность выходит за пределы шаблона и включает предварительную обработку данных.
Сложные интерфейсные сценарии часто требуют комбинирования условий, чисел и временных данных.
"{status, select,
processing {{
{progress, number, percent} complete
}}
finished {{
Completed at {finishTime, date, long}
}}
failed {{
Failed after {duration, number} seconds
}}
}"
Каждый сценарий содержит собственную вложенную логику форматирования.
При работе с несколькими независимыми переменными структура становится многомерной.
"{team, select,
home {{
{scoreHome, number} - {scoreAway, number}
}}
away {{
{scoreAway, number} - {scoreHome, number}
}}
}"
Здесь направление отображения результата зависит от контекста команды, а числа остаются вложенными форматируемыми элементами.
Вложенные конструкции являются ключевым механизмом для:
Структура сообщений становится декларативной, где логика представлена не кодом, а синтаксисом ICU, интерпретируемым Globalize.