Вложенные конструкции

В библиотеке 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

Одним из ключевых механизмов является комбинирование 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}
    }
  }}
}"

В этом случае вложенность достигает третьего уровня:

  1. выбор роли;
  2. выбор формы множественного числа;
  3. финальная текстовая подстановка.

Вложенные параметры и переиспользование переменных

Одним из важных аспектов является повторное использование одной переменной в разных частях сообщения без дублирования логики.

"{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}"

Такой подход позволяет строить многоуровневую систему локализации, где каждый слой отвечает за свою часть логики.


Вложенные селекторы с fallback-логикой

Конструкция 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-строк.

Типичные проблемы:

  • потеря структуры при глубине более 3–4 уровней;
  • сложность локализации для переводчиков;
  • трудность отладки при динамических данных.

Пример чрезмерной вложенности:

"{a, select,
  x {{
    {b, select,
      y {{
        {c, plural,
          one {{d}}
          other {{e}}
        }
      }}
    }
  }}
}"

Такие конструкции формально допустимы, но становятся трудно поддерживаемыми.


Вложенные форматы как часть единой ICU-модели

ICU MessageFormat, используемый в Globalize, рассматривает вложенность как естественное состояние выражения. Любая конструкция может содержать другую конструкцию того же типа или иного типа.

Комбинации:

  • plural внутри select
  • select внутри plural
  • number внутри plural
  • date внутри 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}
  }}
}"

Здесь направление отображения результата зависит от контекста команды, а числа остаются вложенными форматируемыми элементами.


Роль вложенности в архитектуре сообщений Globalize

Вложенные конструкции являются ключевым механизмом для:

  • устранения дублирования строк;
  • описания грамматических правил разных языков;
  • построения условной логики в текстах;
  • объединения форматирования и интерполяции в единый слой.

Структура сообщений становится декларативной, где логика представлена не кодом, а синтаксисом ICU, интерпретируемым Globalize.