Простая подстановка значений

В основе интернационализации интерфейсов часто лежит необходимость формировать строки на основе шаблонов, где часть текста динамически заменяется значениями из данных приложения. В библиотеке Globalize этот механизм реализован через систему сообщений, построенную поверх CLDR-данных и формата ICU MessageFormat.

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

Базовая структура сообщений

Сообщения описываются как строковые шаблоны, где параметры заключаются в фигурные скобки:

"Привет, {name}"

При обработке шаблона библиотека заменяет {name} на соответствующее значение, переданное в момент форматирования. Такой механизм обеспечивает:

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

Инициализация Globalize и подготовка данных

Перед использованием механизма подстановки требуется загрузка CLDR-данных и инициализация локали. Globalize не содержит локализационных данных по умолчанию, что делает его полностью модульным.

Пример типичной подготовки:

import Globalize from "globalize";
import likelySubtags from "cldr-data/supplemental/likelySubtags.json";
import numberingSystems from "cldr-data/supplemental/numberingSystems.json";
import caGregorian from "cldr-data/main/ru/ca-gregorian.json";
import numbers from "cldr-data/main/ru/numbers.json";
import timeZoneNames from "cldr-data/main/ru/timeZoneNames.json";
import currencies from "cldr-data/main/ru/currencies.json";
import messages from "cldr-data/main/ru/messages.json";

Globalize.load(
  likelySubtags,
  numberingSystems,
  caGregorian,
  numbers,
  timeZoneNames,
  currencies,
  messages
);

const globalize = new Globalize("ru");

После этого становится доступна работа с сообщениями, числами и датами в рамках выбранной локали.

Простая подстановка значений через messages

Основной API для работы с подстановкой строк — messageFormatter. Он компилирует шаблон в функцию, которая затем многократно используется для генерации строк.

const greet = globalize.messageFormatter("greeting");

greet({ name: "Алексей" });

При наличии сообщения:

{
  "greeting": "Привет, {name}"
}

результат будет:

Привет, Алексей

Важно, что форматтер создаётся один раз и затем используется повторно, что снижает накладные расходы при частых вызовах.

Именованные параметры и их поведение

Подстановка в Globalize основана на именованных параметрах. Это означает, что порядок значений не имеет значения — важны только ключи.

Шаблон:

"Пользователь {name} вошёл в систему {system}"

Вызов:

formatter({ system: "CRM", name: "Ирина" });

Результат:

Пользователь Ирина вошёл в систему CRM

Если параметр отсутствует, поведение зависит от реализации шаблона: обычно подстановка остаётся пустой строкой или ключ сохраняется в исходном виде, что позволяет обнаруживать ошибки локализации на этапе тестирования.

Вложенные значения и экранирование

Шаблоны поддерживают использование фигурных скобок только как синтаксиса параметров. Для отображения символов { и } в тексте требуется экранирование через двойные фигурные скобки или использование ICU-совместимого синтаксиса.

Пример:

"Результат: {{value}}"

После обработки:

Результат: {value}

Такой механизм предотвращает конфликт между текстом и синтаксисом интерполяции.

Использование числовых значений в подстановке

Подстановка не ограничивается строками. Числовые значения автоматически приводятся к строковому виду с учётом локали, если применяется дополнительное форматирование.

Пример:

const formatter = globalize.messageFormatter("items");

formatter({ count: 5 });

Шаблон:

"У вас {count} сообщений"

Результат:

У вас 5 сообщений

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

Интеграция с форматированием чисел

Globalize позволяет комбинировать подстановку с форматированием чисел через отдельные API. Это особенно важно, когда значение должно быть представлено в локализованном виде.

const numberFormatter = globalize.numberFormatter();
const formatted = numberFormatter(12345.67);

Результат для русской локали:

12 345,67

Далее это значение может быть передано в сообщение:

greet({ amount: formatted });

Шаблон:

"Сумма операции: {amount}"

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

Повторное использование форматтеров

Одним из ключевых аспектов производительности является кэширование форматтеров. Каждый вызов messageFormatter создаёт функцию, которая может использоваться многократно.

const errorFormatter = globalize.messageFormatter("error");

function showError(code) {
  return errorFormatter({ code });
}

При большом количестве операций это снижает нагрузку на парсер шаблонов и ускоряет генерацию интерфейсных сообщений.

Подстановка в составе сложных сообщений

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

Пример с условной частью:

"{name} {gender, select, male {создал} female {создала} other {создал(а)}} запись"

Вызов:

formatter({ name: "Олег", gender: "male" });

Результат:

Олег создал запись

Хотя данный пример выходит за рамки простой подстановки, он демонстрирует совместимость базового механизма с расширенными правилами.

Особенности обработки отсутствующих значений

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

Это поведение используется для выявления проблем локализации:

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

Организация сообщений в приложении

Шаблоны сообщений обычно группируются по доменам приложения:

{
  "auth": {
    "loginSuccess": "Добро пожаловать, {name}",
    "loginError": "Ошибка входа для пользователя {name}"
  }
}

Доступ к ним осуществляется через ключи:

globalize.messageFormatter("auth/loginSuccess");

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

Производственные аспекты использования

При интенсивной эксплуатации механизм подстановки значений становится частью критического пути рендеринга интерфейса. Поэтому важны следующие характеристики:

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

Эти принципы позволяют использовать Globalize в приложениях с высокой нагрузкой без деградации производительности при генерации текстовых сообщений.