Tro*_*nic 15 localization node.js express
我想知道是否有关于如何在express.js中实现多语言路由的最佳实践示例.我想使用accept-language标题来获取浏览器语言,然后自动重定向到相应的语言路由
www.foo.bar/de/startseite 要么
www.foo.bar/en/home
有什么建议吗?
我已经完成了以下操作:安装i18n-node模块并在快速js中注册.这是代码.
var express = require('express')
, routes = require('./routes')
, http = require('http')
, i18n = require("i18n");
var app = express();
i18n.configure({
// setup some locales - other locales default to en silently
locales:['de', 'en'],
// disable locale file updates
updateFiles: false
});
app.configure(function(){
...
app.use(i18n.init);
...
});
// register helpers for use in templates
app.locals({
__i: i18n.__,
__n: i18n.__n
});
Run Code Online (Sandbox Code Playgroud)
在此之后设置以下内容以获取所有请求
// invoked before each action
app.all('*', function(req, res, next) {
// set locale
var rxLocal = /^\/(de|en)/i;
if(rxLocal.test(req.url)){
var arr = rxLocal.exec(req.url);
var local=arr[1];
i18n.setLocale(local);
} else {
i18n.setLocale('de');
}
// add extra logic
next();
});
app.get(/\/(de|en)\/login/i, routes.login);
Run Code Online (Sandbox Code Playgroud)
也许这个帮助.
我只是直接用检测到的语言提供内容.
例如,example.com/home以最佳可用状态提供主页Accept-Language(如果您在网站上提供语言选择选项,可能会被cookie覆盖).
您需要确保您的回复Vary:标题包含Accept-Language.
IMO,包括URI中的语言代码是一个丑陋的黑客.RFC的意图是单个资源(您的主页)通常由单个URI表示.为URI返回的实体可能会根据其他信息(例如语言首选项)而有所不同.
考虑当讲德语的用户复制URL并将其发送给讲英语的用户时会发生什么.该收件人更愿意用英语看到您的网站,但由于他收到了指向的链接example.com/de/startseite,他直接使用德语版本.
显然,这对于用户在地址栏中看到的全部国际化并不理想(因为家庭是英语),但它更符合RFC的意图,我认为它对用户更有效,特别是链接传播到电子邮件/社交/任何.
@miro的答案非常好,但可以在单独的文件中改进,如下面的中间件(如@ebohlman建议的那样).
module.exports = {
configure: function(app, i18n, config) {
app.locals.i18n = config;
i18n.configure(config);
},
init: function(req, res, next) {
var rxLocale = /^\/(\w\w)/i;
if (rxLocale.test(req.url)){
var locale = rxLocale.exec(req.url)[1];
if (req.app.locals.i18n.locales.indexOf(locale) >= 0)
req.setLocale(locale);
}
//else // no need to set the already default
next();
},
url: function(app, url) {
var locales = app.locals.i18n.locales;
var urls = [];
for (var i = 0; i < locales.length; i++)
urls[i] = '/' + locales[i] + url;
urls[i] = url;
return urls;
}
};
Run Code Online (Sandbox Code Playgroud)
也在github中的示例项目中.
中间件有三个功能.第一个是一个小帮手,它配置i18n-node并保存设置app.locals(还没弄清楚如何从i18n-node自身访问设置).
主要的是第二个,它从URL中获取区域设置并将其设置在请求对象中.
最后一个是帮助程序,对于给定的URL,它返回一个包含所有可能语言环境的数组.如果'/about'我们打电话,我们会得到['/en/about', ..., '/about'].
在app.js:
// include
var i18n = require('i18n');
var services = require('./services');
// configure
services.i18nUrls.configure(app, i18n, {
locales: ['el', 'en'],
defaultLocale: 'el'
});
// add middleware after static
app.use(services.i18nUrls.init);
// router
app.use(services.i18nUrls.url(app, '/'), routes);
Run Code Online (Sandbox Code Playgroud)
可以从例如具有i18n-nodes的任何控制器访问区域设置req.getLocale().
@ josh3736推荐的内容肯定符合RFC等.然而,这是许多i18n网站和应用程序的一个相当普遍的要求,甚至Google尊重相同的资源本地化和在不同网址下提供(可以在网站管理员工具中验证这一点).我会建议虽然是有相同的别名郎代码之后,例如/en/home,/de/home等等.
不确定您计划如何组织或共享内容,但您可以使用正则表达式和快速路由,然后提供不同的模板。像这样的东西:
app.get(/^\/(startseite|home)$/, function(req, res){
});
Run Code Online (Sandbox Code Playgroud)
我做的一件事是用子域组织我的内容,然后使用中间件根据分割 URL 从数据库中获取内容,但它们都共享相同的路由和模板。
| 归档时间: |
|
| 查看次数: |
11414 次 |
| 最近记录: |