I18n strategies для SPA

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


Подходы к хранению и управлению переводами

1. JSON-файлы

Наиболее распространённый способ — хранение переводов в формате JSON. Каждая поддерживаемая локаль имеет отдельный файл:

// en.json
{
  "greeting": "Hello",
  "date_format": "MM/DD/YYYY"
}

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

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

2. Структурирование ключей

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

{
  "header": {
    "title": "Главная страница",
    "menu": {
      "home": "Главная",
      "about": "О нас"
    }
  },
  "footer": {
    "contact": "Контакты"
  }
}

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


Интеграция с Backbone.js

1. Расширение моделей и представлений

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

var AppModel = Backbone.Model.extend({
  defaults: {
    lang: 'en',
    translations: {}
  },

  setLanguage: function(lang) {
    this.set('lang', lang);
    this.trigger('language:changed');
  }
});

var appModel = new AppModel();

var HeaderView = Backbone.View.extend({
  initialize: function() {
    this.listenTo(appModel, 'language:changed', this.render);
  },

  render: function() {
    var lang = appModel.get('lang');
    var translations = appModel.get('translations')[lang];
    this.$el.html(translations.header.title);
    return this;
  }
});

Таким образом, любое изменение языка автоматически обновляет соответствующие элементы интерфейса.

2. Подключение JSON-переводов

Для динамической загрузки переводов можно использовать Backbone.ajax или сторонние библиотеки:

$.getJSON('/i18n/' + lang + '.json', function(data) {
  appModel.set('translations', data);
});

После загрузки данных вызывается событие language:changed для обновления всех представлений.


Динамическое обновление контента

SPA предполагает, что контент меняется без перезагрузки страницы. Backbone.View позволяет использовать шаблоны для рендеринга:

var template = _.template('<h1><%= header.title %></h1>');

var view = Backbone.View.extend({
  render: function() {
    var lang = appModel.get('lang');
    var translations = appModel.get('translations')[lang];
    this.$el.html(template({ header: translations.header }));
    return this;
  }
});

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


Управление локализацией чисел, дат и валют

i18n в SPA охватывает не только текст. Backbone.js не предоставляет встроенных средств форматирования, поэтому используют сторонние библиотеки, например moment.js или Intl API:

var date = new Date();
var lang = appModel.get('lang');

// Форматирование даты через Intl
var formattedDate = new Intl.DateTimeFormat(lang, { day: 'numeric', month: 'long', year: 'numeric' }).format(date);

// Форматирование чисел
var number = 123456.78;
var formattedNumber = new Intl.NumberFormat(lang).format(number);

Поддержка динамического изменения языка требует повторного вызова форматирования при событии смены языка.


Стратегии переключения языка

  1. На уровне модели приложения Установка текущего языка в глобальной модели и оповещение всех представлений. Эффективно для небольших SPA.

  2. Загрузка переводов по требованию Подходит для больших приложений, где полный набор переводов может быть слишком большим. Используются AJAX-запросы при смене языка.

  3. Комбинированный подход Основные переводы загружаются при старте, дополнительные — по мере необходимости. Это снижает нагрузку и ускоряет первоначальную загрузку.


Практические советы

  • Минимизировать дублирование ключей: использовать уникальные и осмысленные пути, например menu.home, form.submit.
  • Хранить форматирование отдельно: даты, числа, валюты должны быть отдельными ключами или использовать стандарты Intl.
  • Слушать события: Backbone позволяет подписываться на изменение языка и автоматически обновлять интерфейс.
  • Lazy-load переводов: оптимизация загрузки ресурсов особенно важна для мультиязычных SPA с большим объёмом текста.

Инструменты и библиотеки

  • i18next: популярная библиотека для интернационализации, легко интегрируется с Backbone.
  • Polyglot.js: лёгкая библиотека для работы с ключами и строками.
  • Backbone.localStorage: хранение выбранного языка в локальном хранилище для сохранения состояния между сессиями.

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