-
-
Save jamuhl/f8020960024b4d09f721 to your computer and use it in GitHub Desktop.
var i18next = require('i18next'); | |
var middleware = require('i18next-express-middleware'); | |
var Backend = require('i18next-node-fs-backend'); | |
var express = require('express'); | |
i18next | |
.use(Backend) | |
.init({ | |
// use correct configuration options...look up docs! | |
backend: { | |
loadPath: __dirname + '/locales/{{lng}}/{{ns}}.json' | |
} | |
}); | |
// pseudo virtual hosts | |
var vhosts = [ | |
{ lng: 'de', port: 3000 }, | |
{ lng: 'en', port: 3001 } | |
]; | |
vhosts.forEach(function(host) { | |
var app = express(); | |
// set req.lng to defined lng in vhost | |
// see for details: | |
// https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L14 | |
app.use(function(req, res, next) { | |
req.lng = host.lng; | |
next(); | |
}); | |
// use the middleware to do the magic | |
// create a fixed t function for req.lng | |
// no clones needed as they just would do the same (sharing all but lng) | |
app.use(middleware.handle(i18next)); | |
// in your request handler | |
app.get('/', function(req, res) { | |
var lng = req.language; | |
var lngs = req.languages; | |
console.log('language is: ', lng, lngs); | |
res.send(req.t('key1')); | |
}); | |
app.listen(host.port); | |
}); | |
// go to localhost:3000 ---> de | |
// go to localhost:3001 ---> en | |
// unclear to me...why you need an array of express apps to archive this. | |
// one app with custom language detector function detection lng from domainName | |
// would be enought to detect lng and translate content appropriate |
your issue is related to handlebars being a singleton!
// change the order - first the middleware to get req.t
app.use(middleware.handle(i18next));
// set your lng
// add handlebars helper
app.use(function(req, res, next) {
req.lng = host.lng;
// not sure how you assert in handlebars request save functions...as i always used jade on server
// which does not suffering from the singleton problem
// t helper will be dangerous as race conditions on requests can overwrite it
// see http://stackoverflow.com/questions/17274142/setting-a-handlebars-helper-to-return-a-specific-value-per-request-in-express
var handlebars = new ???;
handlebars.registerHelper('t', function(key, options) {
var result = req.t(key, options.hash);
return new handlebars.SafeString(result);
});
next();
});
Thanks Jan.
The problem is that req.t is undefined:
app.use(function(req, res, next) {
req.lng = host.lng;
// not sure how you assert in handlebars request save functions...as i always used jade on server
// which does not suffering from the singleton problem
// t helper will be dangerous as race conditions on requests can overwrite it
// see http://stackoverflow.com/questions/17274142/setting-a-handlebars-helper-to-return-a-specific-value-per-request-in-express
var handlebars = new ???;
handlebars.registerHelper('t', function(key, options) {
var result = req.t(key, options.hash); // <========== req.t is undefined.
return new handlebars.SafeString(result);
});
next();
});
We still need a way to retrieve the i18next instance. Going back to the original question. req.t === undefined.
Thanks
req.t === undefined --> gets set by app.use(middleware.handle(i18next));
Hi Jan,
I get this error just by placing this line before as you mentioned:
// change the order - first the middleware to get req.t
app.use(middleware.handle(i18next));
If I do that before :
app.use(function(req, res, next) {
// ...
});
I get:
TypeError: Cannot read property 'indexOf' of undefined
at e.a.value (/Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/node_modules/i18next/bin/index.js:1:13811)
at t.u.value (/Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/node_modules/i18next/bin/index.js:2:8308)
at /Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/node_modules/i18next-express-middleware/lib/index.js:82:40
at Layer.handle as handle_request
at trim_prefix (/Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/node_modules/express/lib/router/index.js:312:13)
at /Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/node_modules/express/lib/router/index.js:330:12)
at next (/Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/node_modules/express/lib/router/index.js:271:10)
at /Users/uroblesmellin/projects/bolt20-frontend/bolt-2dot0-frontend/server/middlewares/write-header.js:9:9
at Layer.handle as handle_request
If I do it in the original way (without changing the order of
app.use(middleware.handle(i18next));
I don't get that error.
Thanks,
Ulises
Hi,
Yes, of course we want to translate all handlebar (we are using handlebars as our template library) references in a given page for a given host. We are defining a handlebars helper called "i18n" that actually calls your t method:
For instance, say in index.hbs we have
<h1>{{i18n "title"}}</h1>
{{i18n "title"}} should become the corresponding value given in the file en_US/translations.json or fr_FR/translations.json, etc.
My point was that we are not translating anything in the loop that is setting up the app for a given host (the code shown above). There we don't need to translate a key to get a value, just to set or initialize the i18next instance. We are using handlebars to then read the translated value when a page gets loaded. That's working fine with:
app.use(function(req, res, next) {
i18next.changeLanguage(host.lng);
next();
});
So {{i18n "title"}} will become something like "Hello World" or "Hallo Welt"
Originally, I tried with:
app.use(function(req, res, next) {
req.lng = host.lng;
next();
});
But that just rendered "title" in the html output, not the corresponding localized value.
I do see the point of your comment of not using i18next.changeLanguage(host.lng); because it could yield concurrency issues. The only reminding issue to solve is how to attach the host.lng (the language of the current host) to the "instance of i18next" for that host.
Thanks for your time!