Global properties in Express & Handlebars

express, handlebars.js, javascript, node.js

Solution

I haven't personally used Passport before, but based on the Passport README and what I've done with other authentication schemes, this should work.

Express 3

app.configure(function() {
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(function(req, res, next) {
        res.locals.user = req.user; // This is the important line

        next();
    });
    app.use(app.router);
});

Express 4

app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
    res.locals.user = req.user; // This is the important line

    next();
});

Basically, right before rendering, your `app.locals`, `res.locals`, and the locals you pass into the render function (the second argument) all get combined and passed along to your view engine.

Problem

I'm using Handlebars (using express3-handlebars) for templates and Passport for authentication in a NodeJS app. All is working great but I wondered if there is a way to pass the req.user object created by Passport to Handlebars globally. So my header partial might look something like this: ``` <header> <h1>My Title</h1> {{#if user}} <p>Hello {{user.name}}</p> {{else}} <p>Please <a href='/login'>Log In</a></p> {{/if}} </header> ``` As it stands I have to pass the user object explicitly with every page render: ``` app.get('/', function(req, res){ res.render('home', { page_title: 'welcome', user: req.user }); }); ``` This seems like the wrong way to go about it as I require it on every page, can I not just set it once and have all pages have access to it? I can't do this when I instantiate Handlebars as it's dependent on the user being logged in with Passport, which won't always be the case. Would creating a global 'page_options' object, appending and passing it to every render be the right solution or does Handlebars/Express have a way to handle this?

Original source