Internationalization и локализация

Backbone.js предоставляет архитектуру для построения одностраничных приложений, однако сам по себе фреймворк не включает встроенных средств для интернационализации (i18n) и локализации (l10n). Для поддержки многоязычных интерфейсов и региональных настроек необходимо интегрировать сторонние решения и грамотно организовать структуру приложений.

Интернационализация и локализация: различия

Интернационализация (i18n) — подготовка приложения к поддержке нескольких языков и региональных форматов без привязки к конкретной локали. Локализация (l10n) — конкретная реализация перевода и форматирования для выбранной локали, включая строки, даты, числа и валюту.

Организация текстовых ресурсов

Для Backbone-приложений оптимально хранить текстовые ресурсы в виде JSON-объектов, структурированных по локалям. Пример структуры:

{
  "en": {
    "greeting": "Hello",
    "date_format": "MM/DD/YYYY"
  },
  "ru": {
    "greeting": "Привет",
    "date_format": "DD.MM.YYYY"
  }
}

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

Подключение ресурсов и хранение локали

Чаще всего локаль хранится в модели или глобальном объекте приложения:

var AppSettings = Backbone.Model.extend({
  defaults: {
    locale: 'en',
    translations: {}
  },
  
  setLocale: function(locale) {
    this.set('locale', locale);
    this.trigger('locale:changed', locale);
  },

  t: function(key) {
    var locale = this.get('locale');
    return this.get('translations')[locale][key] || key;
  }
});

var settings = new AppSettings({
  translations: {
    en: { greeting: "Hello" },
    ru: { greeting: "Привет" }
  }
});

console.log(settings.t('greeting')); // "Hello"
settings.setLocale('ru');
console.log(settings.t('greeting')); // "Привет"

Метод t позволяет централизованно получать строки для текущей локали, что упрощает поддержку и масштабирование интерфейса.

Использование локали в Backbone Views

Вьюхи Backbone.js должны реагировать на изменение локали и обновлять отображение. Для этого можно подписываться на событие locale:changed:

var GreetingView = Backbone.View.extend({
  initialize: function(options) {
    this.settings = options.settings;
    this.listenTo(this.settings, 'locale:changed', this.render);
  },

  render: function() {
    this.$el.text(this.settings.t('greeting'));
    return this;
  }
});

var view = new GreetingView({ settings: settings });
$('body').append(view.render().el);
settings.setLocale('ru'); // Автоматически обновит текст на "Привет"

Такой подход обеспечивает динамическое обновление интерфейса при смене локали.

Форматирование дат, чисел и валют

Для корректного отображения региональных форматов лучше использовать сторонние библиотеки, например Moment.js для дат и Numeral.js для чисел. Пример:

// Использование Moment.js для локализованных дат
moment.locale(settings.get('locale'));
var formattedDate = moment().format('L'); // форматируется в соответствии с локалью

// Использование Numeral.js для чисел
numeral.locale(settings.get('locale'));
var formattedNumber = numeral(1234567.89).format('0,0.00');

Подключение таких библиотек позволяет адаптировать интерфейс под региональные стандарты без дополнительной логики в Backbone.

Асинхронная загрузка переводов

Для больших приложений перевод может храниться в отдельных JSON-файлах и загружаться динамически:

$.getJSON('/i18n/' + locale + '.json', function(translations) {
  settings.set('translations', translations);
  settings.setLocale(locale);
});

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

Поддержка многоязычного роутинга

Backbone.Router может использовать локаль в URL для поддержки многоязычных приложений:

var AppRouter = Backbone.Router.extend({
  routes: {
    ':locale/home': 'home'
  },

  home: function(locale) {
    settings.setLocale(locale);
    console.log('Переход на домашнюю страницу с локалью:', locale);
  }
});

var router = new AppRouter();
Backbone.history.start();

Это обеспечивает синхронизацию URL с выбранной локалью, упрощая навигацию и SEO.

Кэширование и производительность

Для повышения производительности перевод можно кэшировать в localStorage или session-памяти. При первой загрузке локали она сохраняется, а при повторных визитах загружается локально, снижая количество сетевых запросов.

if (localStorage.getItem('translations')) {
  settings.set('translations', JSON.parse(localStorage.getItem('translations')));
} else {
  $.getJSON('/i18n/' + locale + '.json', function(translations) {
    localStorage.setItem('translations', JSON.stringify(translations));
    settings.set('translations', translations);
  });
}

Итоговые рекомендации

  • Центральная модель настроек локали облегчает поддержку интерфейса.
  • Использование событий Backbone обеспечивает динамическое обновление UI.
  • Для форматирования дат и чисел подключаются специализированные библиотеки.
  • Переводы рекомендуется хранить в отдельных JSON-файлах и подгружать по необходимости.
  • Для SEO и пользовательского опыта локаль можно включать в маршрутизацию URL.

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