Локализация шаблонов с использованием require.js, магистрали и подчеркивания

Этот вопрос касается шаблонов и локализации, используя шаблоны require.js и underscore через backbone.js. Приложение должно быть локализовано "на лету".

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

Текущий подход (который работает, но выглядит тяжело процессорным):

  • Используя подход к связыванию I18N, создайте язык "включает", который по существу будет содержать переведенные элементы для всех шаблонов
  • Объединить этот объект/массив элементов с атрибутами модели (из магистрали) и передать объединенную партию в шаблон подчеркивания

.

define(['backbone', 'models/model', 'text!template.html', 'i18n!my/nls/translatedbits'],
  function(Backbone, MyModel, TemplateText, TranslationObject) {
  var View = Backbone.View.extend({
    model: {},

    initialize : function(params) {
      this.model = new MyModel();
    },

    render : function(callBack) {
      // Get the model attributes
      var templateParams = _.clone(this.model.attributes);
      // Bolt on the tranlsated elements (established from require.js I18N plugin)
      templateParams.t = TranslationObject;
      // Pass the lot ot the template
      var template = _.template(TemplateText, this.model.attributes);
      $(this.el).html( template );
      return this;
    }

  });
  return View;
  }
);

Затем шаблон будет читать

<%= modelAttribute1 %> <%= t.translationString1 %>

Есть ли лучшее решение или лучший шаблонный движок? [Лучше для этой цели - усы могут иметь другие преимущества, но могут ли они локализоваться более легко или могут кэшировать локализованные результаты, позволяющие передавать атрибуты модели позже?]

Обратите внимание, что языки могут нуждаться в изменении "на лету" - и это еще одна проблема, которую я имею с плагином I18N. Я могу закончить получение транзакций по запросу JSON через шаблонную модель, но для этого все еще требуется слияние объектов, чего я пытаюсь избежать.

Ответы

Ответ 1

Для полноты решение, которое мы придумали, было наиболее оптимизировано:

  • Когда шаблон запрашивался с сервера, cookie определил язык и был доставлен правильный шаблон.

  • Используется обратный конец PHP для предварительного анализа шаблонов; они были затем сохранены в memcached на правильном языке

  • Шаблон языка после запроса затем был кэширован браузером и внутренне в базовой модели, чтобы он мог быстро использоваться JavaScript.

Причины:

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

Ответ 2

Вот то, что я делаю сейчас (просто открытое, поскольку оно кажется полезным для других)

underi18n - очень минимальная lib для выполнения i18n на шаблонах и коде.

Он обеспечивает:

  • Простое преобразование каталогов gettext в формат json.
  • Поддержка замены переменных в строках перевода.

Он делает не дело с плюрализацией.

Из README:

Каталоги

under18n использует простой формат JSON для каталогов, следуя стандарту gettext. В следующем примере

{
    'Developer': 'Προγραμματιστής',
    'Role ${role} does not exist in ${context}': 'Ο ρόλος ${role} δεν υπάρχει στο ${context}'
}

мы имеем две строки перевода, вторую с двумя переменными, role и context. Простой python script предоставляется, чтобы помочь вам преобразовать стандартные файлы .mo в этот формат JSON.

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

Создайте MessageFactory из каталога json i18n:

var t = underi18n.MessageFactory(catalog);

Теперь вы можете перевести inline:

t('Developer') // returns "Προγραμματιστής"

t('Role ${role} does not exist in ${context}', {role: 'διαχειριστής', context: 'πρόγραμμα'})
// Returns "Ο ρόλος διαχειριστής δεν υπάρχει στο πρόγραμμα"

Шаблоны

Обычно переменные в шаблонах обозначаются некоторым разделителем. В усах, например, {{ var }} используется, тогда как <%= var %> по умолчанию используется для подчеркивания. Мы используем один и тот же подход, чтобы указать переводимые строки. Вы можете указать разделители для переводимых строк как RegExp, а также разделители влево/вправо, используемые выбранным вами языком шаблонов в under18n.templateSettings. По умолчанию это следующие соглашения подчеркивания:

templateSettings: {
    translate: /<%_([\s\S]+?)%>/g,
    i18nVarLeftDel: '<%=',
    i18nVarRightDel: '%>'
}

поэтому, <%_ i18n %> установлены для обозначения переводимых строк, а <%= var %> используется для обозначения переменных внутри шаблона.

Вы можете перевести шаблон, вызвав under18n.template, например, используя знак подчеркивания, вы можете сделать

var templ = _.template(under18n.template(myTemplate, t));

Пример

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

var test_en = {
        'files_label': 'Files',
        'num_files': 'There are ${num} files in this folder'
    },

    templ = '<h1><%= title %></h1>' +
            '<label><%_ files_label %></label>' +
            '<span><%_ num_files %></span>',

    t_en = underi18n.MessageFactory(test_en);
    t_el = underi18n.MessageFactory(test_el);

шаблон может быть построен по формуле

var toRender = _.template(underi18n.template(templ, t_en));
toRender({title: 'Summary', num: 3});

даст

<h1>Summary</h1>
<label>Files</label>
<span>There are 3 files in this folder</span>

Загрузка AMD

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

Надеюсь, это решает вашу проблему, дайте мне знать, если нет, я планировал выпустить ее на определенном этапе, но лучше теперь, чем никогда;)