Keystone.js + i18n。在渲染视图之前获取当前区域设置

时间:2015-01-27 07:05:23

标签: node.js internationalization keystonejs

我正在尝试将i18n包含在keystone.js应用中。我在这个示例中https://gist.github.com/JedWatson/9191081就是这样做的,但它确实有效,但我的问题是在视图中获取当前的区域设置。我正在使用中间件通过url param设置语言环境:

// middleware.js
exports.setLocale = function (req, res, next) {
    if (req.params.lang) {
        req.setLocale(req.params.lang);
    }
    else
        res.redirect('/ru/');
    next();
};

// index.js
keystone.pre('render', middleware.setLocale);

和路由

app.get('/:lang/', routes.views.index);
app.get('/:lang/blog/:category?', routes.views.blog);
app.get('/:lang/blog/post/:post', routes.views.post);
...

默认语言环境为“ru”。但在我看来

view.on('render', function (next) {
    console.log('on render', req.getLocale());
    next();
});

console.log('before render', req.getLocale());
view.render('blog');

在路线/en/blog上输出

------------------------------------------------
KeystoneJS Started:
qalqan is ready on default port 3000
------------------------------------------------

before render ru
on render en
GET /en/blog 304 373ms

因此,据我所知,在将varibales发送到视图后,语言环境会发生变化。在呈现之前是否有任何设置方法?我知道,我可以在每个视图中通过url param lang的req.params获取它,但我希望通过中间件为所有视图执行此操作。

1 个答案:

答案 0 :(得分:1)

更新:从i18n版本0.7.0开始,您的代码应该可以运行。

这似乎有点反直觉,但我认为你不应该触摸路由以避免重复lang参数。

你正走在正确的道路上,这就是我所做的:

// routes/middleware.js

exports.detectLang = function(req, res, next) {
    var match = req.url.match(/^\/(de|en)([\/\?].*)?$/i);

    if (match) {
        req.setLocale(match[1]);
        // Make locale available in template
        // (necessary until i18n 0.6.x)
        res.locals.locale = req.getLocale();
        // reset the URL for routing
        req.url = match[2] || '/';
    } (else) {
        // Here you can redirect to default locale if you want
    }

    next();
}

现在只需在定义所有其他res.locals之前使用中间件:

// routes/index.js

keystone.pre('routes', i18n.init);
keystone.pre('routes', middleware.detectLang);

现在,您可以使用'/' + res.locals.locale添加所有网址,并且用户将在您的应用周围的任何位置保留其区域设置。