我正在使用expressjs和i18n节点(https://github.com/mashpie/i18n-node)。它正在工作,除了优雅的链接。我现在拥有的是:
app.all(/^/(w{2}/)+(w*)?/, function(req, res, next) {
var lang = req.params[0];
var type = req.params[1];
req.url = req.url.replace(lang, "");
if(type !== 'javascript' && type !== 'img' && type !== 'css') {
i18n.setLocale(lang.slice(0, 2));
}
next();
});
(我希望/foo和/en/foo都能工作)。如果url中未指定语言,则会检查标头,如果未指定,则默认为英语。顺便说一句,我的解决方案似乎不太理想(我必须手动检查它是否不是静态内容),所以如果你们中有人有更好的解决方案,我会洗耳恭听。
现在,我真正的问题是建立内部内容的链接。如果用户在这里:"/en/foo","/bar"链接实际上应该是"/en/bar"。我正在使用翡翠(除了它是默认的之外,没有其他特别的原因,再次接受建议。)
我试着给Jade添加一个助手功能:
app.helpers({
__i: i18n.__
,__n: i18n.__n
,link_to: function(link, text) {
//TODO: how to get request here?
// this should be defined to the absolute base path
var baseUrl = "/";
// only append locale if it is part of the existing url!
var locale = i18n.getLocale();
return '<a href="' + baseUrl + locale + '/' + link + '">' + text + '</a>';
}
});
但它有很多问题:
- 如何获取基本url?例如,如果网站位于http://www.example.com/foo/bar,并且我链接到"testLink",link_to将生成http://www.example.com/foo/bar/testLink",而不是"/testLink"或"http://www.example.com/testLink"等
- 如何确定url是否包含本地化参数?如果没有必要的话,我不想在链接中添加本地化参数
- 功能本身并不伟大;在Jade中,它被称为::=link_to("testUrl","一些链接描述")。我宁愿这样做:link_to(href="someUrl")div更多的翡翠代码
- (minor)HTML是直接在JS中编写的
做这件事的首选方式是什么?我一直在找,但找不到一个好的答案。。
这实际上也是一个普遍的问题;即如何链接到其他内部内容,如Rails中的link_to。仅仅做一个(href="someAction")是不够的,因为你希望它生成绝对的URL,这样漂亮的URL就不会破坏静态内容链接。
谢谢!
我用i18n粘贴自己项目的代码,我用一个类作为dicto,用另一个类通过IP:搜索语言
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
secret: "sessid",
key: 'uwsid',
store: sessionStore
}));
app.use(function (req,res,next) {
if (req.session.uid) {
req.lang = req.session.uid.lang;
next();
} else if (req.cookies.lang) {
req.lang = req.cookies.lang;
next();
} else {
var alang = typeof req.headers['accept-language'] != "undefined" ? req.headers['accept-language'].substr(0,2) : null;
var ipinfows = ipinfo.getInstance();
ipinfows.getInfo(req.connection.remoteAddress, function (err,data) {
if (err) {
req.lang = alang;
res.cookie('lang', alang);
} else if (data && data.error) {
req.lang = alang;
res.cookie('lang', alang);
} else {
console.log("seteando");
req.lang = data.lang.toLowerCase();
for (i in countryLangs) {
if (countryLangs[i].indexOf(data.lang) != -1) {
req.lang = i;
}
}
if (alang != req.lang) {
req.langdifference = alang;
}
res.cookie('lang', req.lang);
}
next();
});
}
});
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
在路由app.use(app.router)之前你可以定义回调,在这种情况下,我搜索lang并在cookie中定义它。在我添加dynamicHelper以将Dicto对象包含到模板中之后:
app.dynamicHelpers({
i18n: function (req,res) {
return new i18n({lang: req.lang});
}
});
在路由之前定义lang。(保存在req.lang中),我现在可以使用模板中的i18n哈尔珀(带翡翠):
form.uniForm(action="/account",method="post")
fieldset.inlineLabels
.ctrlHolder
label(for="nickname") #{**i18n.getText('user:nick')**}:
input(type="text",name="nickname",value=everyauth.user.nick)
p.formHint
i18n对象现在与动态助手上定义的对象相同。
据我所知,express只会调用一次helper函数(编译模板时…)
在快速指南中,http://expressjs.com/guide.html,查看dynamicHelpers,它应该对您的情况更有用(dynamicHelpers提供请求和响应对象)。