ericf / express-handlebars

A Handlebars view engine for Express which doesn't suck.
BSD 3-Clause "New" or "Revised" License
2.31k stars 384 forks source link

Extend for multilingual layouts and templates #14

Closed rottmann closed 11 years ago

rottmann commented 11 years ago

My view/layout structure is:

views
|- de
   |- layouts
      |- main_layout.html
      |- main_layout.txt
   |- user
      |- register.html
      |- register.txt
|- en
   |- layouts
      |- main_layout.html
      |- main_layout.txt
   |- user
      |- register.html
      |- register.txt

Depending on the users language different layouts and templates will be rendered.

At the moment i extend / overwrite your function

ExpressHandlebars.prototype._resolveLayoutPathOld = express3Handlebars.ExpressHandlebars.prototype._resolveLayoutPath;
ExpressHandlebars.prototype._resolveLayoutPath = function(layoutPath) {
  layoutPath = this._resolveLayoutPathOld(layoutPath);
  return layoutPath.replace(/%language%/, this.language);
};

var templateHtml = express3Handlebars.create({
  helpers: templateHelpers,
  defaultLayout: "main_mail.html",
  layoutsDir: "views/%language%/layouts/"
});

var templateText = express3Handlebars.create({
  helpers: templateHelpers,
  defaultLayout: "main_mail.txt",
  layoutsDir: "views/%language%/layouts/"
});

Before render i set de ExpressHandlebars.language variable.

Call render with language Param for the template

app.render(language + template + ".html", fields, ....

Nice will be a param in the fields-param, when the template got rendered and this param will be uses for layouts too.

ericf commented 11 years ago

This sounds like an important feature to add, and if I can make a simple change to easily support what you're doing, I'm all for that!

To clarify, are you asking that I should pass the entire app/response locals object (fields in your example) to the _resolveLayoutPath() method?

Which would allow the following:

var app = require('express')(), 
    hbs = require('express3-handlebars').create({ /* ... */ });

app.engine('handlebars', hbs.engine);

hbs._resolveLayoutPath = function (locals) {
    var layoutPath = this.constructor.prototype._resolveLayoutPath.apply(this, arguments);
    return layoutPath.replace(/%language%/, locals.language);
};

// ...

app.render('foo.handlebars', {language: 'de'});
rottmann commented 11 years ago

Yes that will be a great solution. :+1:

ericf commented 11 years ago

@rottmann Okay, this change has been published to npm. Let me know if you run into anything else so we can keep thinking about adding first class multilingual support if the need arises.