Локализация шаблонов с использованием 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.
Надеюсь, это решает вашу проблему, дайте мне знать, если нет, я планировал выпустить ее на определенном этапе, но лучше теперь, чем никогда;)