15

这个问题是关于模板化和本地化,使用 require.js 和通过主干.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;
  }
);

然后模板将读取

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

是否有更好的解决方案或更好的模板引擎?[更适合这个目的 - mustache 可能还有其他优点,但它可以更容易地本地化,还是它可以缓存本地化结果以允许稍后传入模型属性?]

请注意,可能需要“即时”更改语言 - 这是我对 I18N 插件的另一个担忧。我最终可能会通过模板模型通过 JSON 请求获取转换,但这仍然需要对象的合并,这是我试图避免的。

4

2 回答 2

13

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

underi18n是一个非常小的库,用于在模板和代码上执行 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 "Ο ρόλος διαχειριστής δεν υπάρχει στο πρόγραμμα"

模板

通常,模板中的变量用一些分隔符表示。例如在 mustache 中{{ var }}使用,而<%= var %>下划线默认使用。我们使用相同的方法来表示可翻译的字符串。您可以将可翻译字符串的分隔符指定为正则表达式,以及您选择的模板语言使用的左/右分隔符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 加载

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

我希望这能解决你的问题,如果没有,请告诉我,我计划在某个阶段发布它,但是现在总比没有好;)

于 2012-10-12T08:40:13.763 回答
9

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

  1. 当从服务器请求模板时,cookie 会确定语言并传递正确的模板。

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

  3. 语言模板一旦被请求,就会被浏览器缓存并在内部存储在主干模型中,以便 JavaScript 可以快速重用它。

原因:

  • 更快的 JS(更少的正则表达式替换)。我们从未进行过基准测试,但只有在您完全删除这些功能时才合乎逻辑。
  • saved transferring a HUGE language file to the client
于 2012-11-26T05:48:17.127 回答