Skip to content

Instantly share code, notes, and snippets.

@mashpie
Last active June 18, 2021 02:46
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mashpie/5246334 to your computer and use it in GitHub Desktop.
Save mashpie/5246334 to your computer and use it in GitHub Desktop.
express + i18n-node + handlebars and avoid concurrency issues
// require modules
var express = require('express'),
i18n = require('i18n'),
hbs = require('hbs'),
app = module.exports = express();
i18n.configure({
locales: ['en', 'fr'],
cookie: 'locale',
directory: "" + __dirname + "/locales"
});
app.configure(function () {
// setup hbs
app.set('views', "" + __dirname + "/views");
app.set('view engine', 'hbs');
app.engine('hbs', hbs.__express);
// you'll need cookies
app.use(express.cookieParser());
// init i18n module for this loop
app.use(i18n.init);
});
// register hbs helpers in res.locals' context which provides this.locale
hbs.registerHelper('__', function () {
return i18n.__.apply(this, arguments);
});
hbs.registerHelper('__n', function () {
return i18n.__n.apply(this, arguments);
});
// serving homepage
app.get('/', function (req, res) {
res.render('index');
});
// startup
app.listen(3000);
<span id="text">{{{__ "text to test"}}}</span>
<br>
<span id="onecat">{{{__n "%d cat" "%d cats" 1}}}</span>
<br>
<span id="twocats">{{{__n "%d cat" "%d cats" 2}}}</span>
@eloquence
Copy link

eloquence commented Jun 16, 2016

I had to move the helpers into a middleware, or all messages resolved in the context of {{#each}} loops were output in the default locale, with the debug message, "WARN: No locale found - check the context of the call to __(). Using en as current locale" (the value of this being set to the message key inside the loop). Please let me know if there's a more elegant way to do this:

app.use(function(req, res, next) {
  hbs.registerHelper('__', function() {
    return i18n.__.apply(req, arguments);
  });
  hbs.registerHelper('__n', function() {
    return i18n.__n.apply(req, arguments);
  });
  next();
});

UPDATE: Don't do what I did -- re-registering with hbs on each request creates concurrency issues. Indeed, doing this inside of middleware is not necessary at all, as hbs has access to the current locale through the options parameter that gets passed to each helper. The solution I ultimately went with can be found here (see the __ and __n helpers in particular):
https://github.com/eloquence/lib.reviews/blob/master/util/handlebars-helpers.js

@ekkis
Copy link

ekkis commented Oct 14, 2016

I'm confused. the title of this document reads "express + i18n-node + handlebars", referring to i18n-node, as opposed to i18n which is what is shown as required. which module does this apply to? because both exist. at first I installed i18n-node and then thought that i18n was required so I uninstalled the former and installed the latter. in neither case can I make this work. which is the correct module?

@JailBreakC
Copy link

@eloquence thanks a lot! your method is fucking working! solved my problem.

@bajajDeeksha
Copy link

hello, How is it reading the json files, Mine is going to the views/**.hbs but it is not reading the json file properly. need help

@felquis
Copy link

felquis commented Jun 13, 2020

Thank you, this piece helped me 👍 💯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment