Express.js で多言語ルートを実装する方法に関するベスト プラクティスの例があるかどうか疑問に思っています。ヘッダーを使用しaccept-language
てブラウザの言語を取得し、対応する言語ルートに自動的にリダイレクトしたい
www.foo.bar/de/startseite
また
www.foo.bar/en/home
これに関するアドバイスはありますか?
Express.js で多言語ルートを実装する方法に関するベスト プラクティスの例があるかどうか疑問に思っています。ヘッダーを使用しaccept-language
てブラウザの言語を取得し、対応する言語ルートに自動的にリダイレクトしたい
www.foo.bar/de/startseite
また
www.foo.bar/en/home
これに関するアドバイスはありますか?
i18n-node モジュールをインストールし、express 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
});
この後、すべてのリクエストを取得するために次を設定します
// 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);
多分このヘルプ。
検出された言語でコンテンツを直接提供するだけです。
たとえば、example.com/home
利用可能な最適な方法でホームページを提供しますAccept-Language
(サイト自体で言語選択オプションを提供している場合は、Cookie によってオーバーライドされる可能性があります)。
応答のVary:
ヘッダーにAccept-Language
.
URIに言語コードを含めるIMOは醜いハックです。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;
}
};
githubのサンプル プロジェクトにもあります。
ミドルウェアには 3 つの機能があります。i18n-node
1 つ目は、設定を構成して保存する小さなヘルパーですapp.locals
(それ自体から設定にアクセスする方法がわかりませんi18n-node
)。
主なものは 2 番目のもので、URL からロケールを取得し、それを要求オブジェクトに設定します。
最後の 1 つは、特定の 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);
i18n-node
ロケールは、たとえば . を持つ任意のコントローラからアクセスできますreq.getLocale()
。
@josh3736 が推奨するものは、確実に RFC などに準拠しています。それにもかかわらず、これは多くの i18n Web サイトやアプリにとって非常に一般的な要件であり、Google でさえローカライズされ、異なる URL で提供される同じリソースを尊重します (これは Webmaster ツールで確認できます)。私がお勧めするのは、lang コードの後に同じエイリアスを付けることです (例:など/en/home
) 。/de/home
コンテンツの整理や共有をどのように計画しているかはわかりませんが、エクスプレス ルートで正規表現を使用してから、さまざまなテンプレートをサーバーにアップロードできます。このようなもの:
app.get(/^\/(startseite|home)$/, function(req, res){
});
私が行ったことの 1 つは、コンテンツをサブドメインで整理し、ミドルウェアを使用して URL の分割に基づいてデータベースからコンテンツを取得することでしたが、それらはすべて同じルートとテンプレートを共有していました。
「Accept-Language」ヘッダーを解析し、要求レベルのローカル変数を適切なコード (2 文字の言語コードなど) にデフォルト値 (「en」など) で設定するミドルウェア関数を作成します (そのようなヘッダーがない場合)または、リストされている言語をサポートしていません。ルートでは、ローカルを取得してテンプレート ファイル名に追加し、テンプレートの選択以外に言語に依存する処理がある場合は分岐します。