Search code examples
node.jsexpresshandlebars.js

Dynamic partial in handlebars


The below code working fine but routes / and /signup will show same thing (except title) because the first argument in the res.render doesn't do anything and because in the layout I have {{< index}} which render the view with the name index. What I want is to dynamically pass the partial that I want to render (basically I want the first argument of res.render to have effect).

app.js

/* Variable declarations */
var express =   require('express'),
    hbs     =   require('hbs'),
    app     =   express();

/* Setttings */
app.set('views', __dirname + '/views');
app.set('view engine', 'hbs');
app.set('view options', { layout: 'layout' });

/* Register Partials */
hbs.registerPartials(__dirname + '/views');

/* Routes */
app.get('/signup', function (req, res) {
    res.render('index', {title: 'Welcome'});
});
app.get('/signup', function (req, res) {
    res.render('signup', {title: 'Sign Up'});
});

/* Listeners */
app.listen(80, function () {
  console.log('App started...');
});

Layout.hbs

<!DOCTYPE html>
<html>
    <head>
        <title>{{title}}</title>
    </head>
    <body>
        {{> index}}
    </body>
</html>

Solution

  • As part of Handlerbars 3.0 dynamic partials are included. You can find the reference here. With this new syntax the name of the partial is evaluated and dynamically replaced. I'm using "express-handlebars": "2.0.1",.

    Layout.hbs

    <!DOCTYPE html>
    <html>
      <head>
        <title>{{title}}</title>
      </head>
      <body>
        {{> (whichPartial) }}
      </body>
    </html>
    

    App.js

    /* Routes */
    app.get('/', function (req, res) {
       res.render('index', {title: 'Welcome'
            whichPartial: function() {
                 return "thePartialNameForIndex";
            }
       });
    });
    app.get('/signup', function (req, res) {
       res.render('signup', {title: 'Sign Up'
           whichPartial: function() {
                 return "thePartialNameForSignup";
           }
       });
    });
    

    Where thePartialNameForIndex and thePartialNameForSignup are the name of the partials allocated in /views.