mashpie / i18n-node

Lightweight simple translation module for node.js / express.js with dynamic json storage. Uses common __('...') syntax in app and templates.
MIT License
3.08k stars 421 forks source link

Making global scope aware of locale #212

Open adamreisnz opened 8 years ago

adamreisnz commented 8 years ago

Just wondering if I'm missing something, but when using i18n in an express app with middleware, the locale is set by the middleware and passed onto the req/res objects. However, does the locale also get passed on to the global i18n object so that I can have services that provide for example email contents without needing to pass them the req object for reference?

Currently I've "hacked" it like so:

//Use i18n and propagate locale to global scope
  app.use(i18n.init);
  app.use((req, res, next) => {
    i18n.setLocale(req.getLocale());
    next();
  });

But not sure if that's redundant or if there's a better way of doing it. I just want to make sure that for the duration of the request the global locale equals the locale of the request.

mashpie commented 8 years ago

you should not use any global singleton assignments on webservers, right? When a language depends on a request, it should always get read from that request - not from the next one ;) nor from an older one with long running processes.

you could anyhow pass the locale to a new instance of your email service to let it handle locales itself. There are many ways to do so, just thinking of:

i18n.configure({...});
app.use(i18n.init);
app.use(function(req, res, next) {

  new EmailService(req.getLocale());

  new AnotherService().locale = req.getLocale();

  next();
});

var EmailService = function(locale){

    // some thing to do in here
    var t = i18n.__;
    var locale = locale;
    this.t('Hello') // --> Salut (taken from this.locale)
}

var AnotherService = function(){

    var t = i18n.__;
    this.t('Hello') // --> Salut (taken from this.locale)

    return this;
};

Another interesting use case... time to write a book ;) Maybe you get inspiration in tests https://github.com/mashpie/i18n-node/blob/master/test/i18n.init.js#L60

adamreisnz commented 8 years ago

Yeah, I realised that as soon as I had written this post ;)

I wasn't aware of the functionality to bind the translate function to any other object, and that it will look for a this.locale there. That could work I guess, I will play around with it. Thanks!

PS: in your sample code above, you meant to do this.t = ... and this.locale = ... instead of var declarations, correct?