车把国际化

时间:2014-07-14 16:12:49

标签: express localization internationalization handlebars.js

我正在尝试将使用Express和Handlebars的应用程序国际化。是否可以获取Handlebars partials(片段)来加载和呈现本地化资源文件?

注意到我已经阅读了这个问题:express3-handlebars and 18next-node - internationalisation based on page?

这是我的目录结构:

views/
   index.html
   login.html
   fragments/
       frag1.html
       frag2.html
       frag3.html
locales/
   index.json
   login.json
   fragments/
       frag1.json
       frag2.json
       frag3.json

如果有必要,我可以将locales/目录中的JSON文件分开,如下所示:

locales/
   en-CA/
       index.json
       ...other files
   fr-CA/
       index.json
       ...other files

以下是我的server.js文件中的相关代码:

// ...
hbs = exphbs.create({
    extname: '.html',
    layoutsDir: [
        __dirname + '/views'
    ],
    partialsDir: [
        __dirname + '/views/fragments'
    ],
    helpers: {
        'json': function(context) {
            return JSON.stringify(context);
        },
        't': function(k) {
            // ?
        }
    }
});
app.engine('.html', hbs.engine);
app.set('view engine', 'html');

t帮助器是我需要帮助的。在我的模板/模板片段中,我有以下内容:

<h1>{{ t 'pageTitle' }}</h1>
<p>{{ t 'foo' }}</p>
<p>{{ t 'moreThings' }}</p>

我的JSON文件可能如下所示:

{
    "pageTitle": "Hello world",
    "foo": "Paragraph contents here",
    "moreThings": "There are %d things"
}

另外,我如何处理printf参数?

1 个答案:

答案 0 :(得分:0)

在您的应用程序中进行国际化意味着做两件事:

1)确定应使用的语言环境

根据您确定使用的语言环境的方式,在帮助程序中执行此操作可能很困难。例如,助手无权访问请求对象。说实话,我无法想到在帮助者中做到这一点的好方法。

我个人使用i18n-abide中间件进行国际化。他们有几个选项来确定给定请求的区域设置。确定区域设置后,它将作为属性添加到请求对象中。因此,您只需为每个请求确定一次区域设置。另一个优点是您还可以访问车把助手外部的区域设置。

2)访问资源文件

从帮助程序中访问资源文件意味着您应该读取并解析帮助程序之外的资源文件。每次需要翻译字符串时解析资源文件确实会损害性能。

在这里你也应该使用中间件。您可以执行以下伪代码。

function setup() {
  // Load resource files from disk and parse them.
  var resources = { /* parsed resources*/ }

  return function(req, res, next) {
    var locale = determineLocalFunction(req);
    req.getText = function(label) {
      return resources[local][label];
    }
  }
}

现在,您可以在代码中的每个位置使用req.getText函数。我个人从不在部分内部使用语言标签。相反,我使用数据对象传递部分所需的所有语言字符串。这背后的原因是我认为部分应该尽可能地重复使用。在其中使用硬编码语言标签会降低它们的可重用性。

如果您想在部分中使用getText函数,可以将getText函数传递给partial。

这样的事情:

var objectPassedToPartial = {
  getText: req.getText
}

使用它像:

{{getText 'label'}}

了解有关Mozilla i18n-abide解决方案的更多信息,我非常喜欢它。