使用require.js,backbone和underscore本地化模板

Rob*_*bie 15 templates localization requirejs backbone.js underscore.js

这个问题是关于模板化和本地化的,通过backbone.js使用require.js和下划线模板.应用程序需要动态本地化.

在开始一条后来证明有问题的路径之前,有没有比我正在考虑的更好的解决方案 - 我关注速度和内存,反复合并和处理语言数组.假设是2-3万个语言字符串.

当前的方法(有效,但看起来处理器很重):

  1. 使用I18N捆绑方法,创建语言"包含",其基本上包含所有模板的已翻译元素
  2. 将此对象/数组元素与模型属性(来自主干)合并,并将合并的批次传递到下划线模板中

.

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;
  }
);
Run Code Online (Sandbox Code Playgroud)

然后模板将会读取

<%= modelAttribute1 %> <%= t.translationString1 %>
Run Code Online (Sandbox Code Playgroud)

有更好的解决方案还是更好的模板引擎?[更好的目的 - 胡子可能有其他优点,但它可以更容易本地化,还是可以缓存本地化结果,允许模型属性在以后传递?]

请注意,语言可能需要"动态"更改 - 这是我对I18N插件的另一个担忧.我可能最终通过模板模型获取JSON请求的转换,但这仍然需要合并对象,这正是我想要避免的.

ggo*_*zad 13

这是我目前正在做的事情(只是开源的,因为它似乎对其他人有用)

underi18n是一个非常小的lib,用于在模板和代码上进行i18n.

它提供:

  • gettext目录简单转换为json格式.
  • 支持翻译字符串中的变量替换.

它并没有解决多元化.

来自README:

产品目录

under18n对标准使用简单的JSON格式,遵循标准gettext格式.在以下示例中,

{
    'Developer': '???????????????',
    'Role ${role} does not exist in ${context}': '? ????? ${role} ??? ??????? ??? ${context}'
}
Run Code Online (Sandbox Code Playgroud)

我们有两个翻译字符串,第二个有两个变量,rolecontext.提供了一个简单的python脚本来帮助您将标准.mo文件转换为此JSON格式.

用法

从json i18n目录创建一个MessageFactory:

var t = underi18n.MessageFactory(catalog);
Run Code Online (Sandbox Code Playgroud)

您现在可以内联翻译:

t('Developer') // returns "???????????????"

t('Role ${role} does not exist in ${context}', {role: '????????????', context: '?????????'})
// Returns "? ????? ???????????? ??? ??????? ??? ?????????"
Run Code Online (Sandbox Code Playgroud)

模板

通常,模板中的变量用一些分隔符表示.例如{{ var }},使用小胡子,而<%= var %>下划线则默认使用.我们使用相同的方法来指示可翻译的字符串.您可以将可翻译字符串的分隔符指定为RegExp,以及您选择的模板语言使用的左/右分隔符under18n.templateSettings.默认情况下,这遵循下划线约定:

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

因此,<%_ i18n %>设置为表示可翻译字符串,<%= var %>用于表示模板内的变量.

您可以通过调用来翻译模板under18n.template,例如使用下划线,您可以这样做

var templ = _.template(under18n.template(myTemplate, t));
Run Code Online (Sandbox Code Playgroud)

给出以下目录,英语和希腊语的工厂和模板,并假设下划线模板,

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);
Run Code Online (Sandbox Code Playgroud)

模板可以由构造,

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

会屈服

<h1>Summary</h1>
<label>Files</label>
<span>There are 3 files in this folder</span>
Run Code Online (Sandbox Code Playgroud)

AMD加载

如果您使用requireJS, under18n将注册为匿名模块.

我希望这可以解决你的问题,如果没有,请告诉我,我打算在某个阶段发布它,但是现在比你从未好过;)


Rob*_*bie 9

为了完整起见,我们提出的最优化的解决方案是:

  1. 从服务器请求模板时,cookie确定了语言并传送了正确的模板.

  2. 使用PHP后端预先解析模板; 然后将它们以正确的语言存储在memcached中

  3. 语言模板一旦被请求,然后由浏览器缓存,并在内部以骨干模型进行缓存,以便JavaScript可以快速重复使用.

原因:

  • 更快的JS(更少的正则表达式替换).我们从未进行过基准测试,但只有在完全删除这些功能时才合乎逻辑.
  • 保存将巨大的语言文件传输到客户端