这个问题是关于模板化和本地化的,通过backbone.js使用require.js和下划线模板。应用程序需要动态本地化。
在走上一条后来证明有问题的路径之前,是否有比我正在考虑的更好的解决方案 - 我关注速度和内存,反复合并和处理语言数组。假设这是2-3万种语言字符串。
当前的方法(有效,但看起来处理器很重):
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请求的转换,但这仍然需要合并对象,这正是我想要避免的。
答案 0 :(得分:13)
这是我目前正在做的事情(只是开源的,因为它似乎对其他人有用)
underi18n是一个非常小的lib,用于在模板和代码上进行i18n。
它提供:
gettext
目录简单转换为json格式。不处理复数化。
来自自述文件:
under18n
使用简单的JSON格式进行目录,遵循标准gettext
格式。在以下示例中,
{
'Developer': 'Προγραμματιστής',
'Role ${role} does not exist in ${context}': 'Ο ρόλος ${role} δεν υπάρχει στο ${context}'
}
我们有两个翻译字符串,第二个翻译字符串包含两个变量role
和context
。
提供了一个简单的python脚本来帮助您将标准.mo
文件转换为此JSON格式。
从json i18n目录创建 MessageFactory :
var t = underi18n.MessageFactory(catalog);
您现在可以翻译内联:
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>
under18n将注册为匿名模块。
我希望这能解决你的问题,如果没有,请告诉我,我打算在某个阶段发布它,但现在比现在更好;)
答案 1 :(得分:9)
为了完整起见,我们提出的最优化的解决方案是:
当从服务器请求模板时,cookie确定了语言并传送了正确的模板。
使用PHP后端预先解析模板;然后将它们以正确的语言存储在memcached中
语言模板一旦被请求,就会被浏览器缓存,并在内部的骨干模型中进行缓存,以便JavaScript可以快速重复使用。
原因: