MrBojangles
MrBojangles

Reputation: 1443

Accessing Express.js req or session from Jade template

I am wondering if there is an easy way to access Express.js' req or session variables from within a Jade template without passing it in through the normal response.

Or is this the only way?

res.render('/', {
    session: req.session
});

Upvotes: 29

Views: 30885

Answers (8)

Sohan Arafat
Sohan Arafat

Reputation: 93

If your session object variable is declared globally then In global

var sess

In function

sess=req.session

req.render('index.pug',{sess})

Upvotes: 0

st0ne
st0ne

Reputation: 126

You could solve this with a render function in which you use to render every view that needs the session variable as a local variable accessible in the template(usually when a user is logged in for example).

Here is an example of a function but you can adjust as you like:

var renderView = function(res, template, context, session, cb) {
    context.session = session;

    if(cb){
        res.render(template, context, function(error, html){
            cb(error, html)
        }
    } else {
        res.render(template, context)
    }
}

Then it can be used like this:

app.get("/url", function(req, res){

    req.session.user_email = user_email;

    renderView(res, "template_name", { local_variables: local_variables }, req.session)
});

and in your jade template you can access the session variables like this:

div.user-email #{session.user_email}

Upvotes: 0

SulTan
SulTan

Reputation: 201

this worked for me

app.use(function(req,res,next){
   res.locals.user = req.user;
   next();
});

in pug or jade view user

#{user.email}

Upvotes: 3

Ajouve
Ajouve

Reputation: 10089

Just add

app.use(express.cookieParser());
app.use(express.session({secret: '1234567890QWERTY'}));
app.use(function(req,res,next){
    res.locals.session = req.session;
    next();
});

Before

app.use(app.router);

and get your session in jade

p #{session}

Upvotes: 58

Dominic Barnes
Dominic Barnes

Reputation: 28429

You'll need to create a dynamicHelper for Express to use.

app.dynamicHelpers({
    session: function (req, res) {
        return req.session;
    }
});

Then inside your template, you can use <%= session.logged_in %> or whatever.

Note: dynamicHelpers are deprecated in Express 3

Upvotes: 21

kaisa1028
kaisa1028

Reputation: 3796

just use a middleware.

app.use(function (req, res, next) {
            var origRender = res.render;
            res.render = function (view, locals, callback) {
                if ('function' == typeof locals) {
                    callback = locals;
                    locals = undefined;
                }
                if (!locals) {
                    locals = {};
                }
                locals.req = req;
                origRender.call(res, view, locals, callback);
            };
            next();
});

After which you can use "#{req}" to refer to it in a jade template.

Suppose you have a 'user' object in 'req', and 'user' has a method 'isAnonymous', if your user.isAnonymous() returns true,

p #{req.user.isAnonymous()}

will be rendered as :

<p>true</p>

Upvotes: 3

David Weldon
David Weldon

Reputation: 64312

In express 3.x, dynamicHelpers have been removed so you will need to use a combination of middleware and res.locals. Let's say we want to access req.query in a /signup/new view:

localQuery = function(req, res, next) {
  res.locals.query = req.query;
  next();
};

newSignup = function(req, res) {
  res.render('signup/new');
};

app.get('signup/new', localQuery, newSignup);

Now any route which uses the localQuery middleware, will have res.locals.query set. This can then be accessed in your view as query.

Upvotes: 46

jcolebrand
jcolebrand

Reputation: 16025

While there is always a way in javascript to escape the scope and crawl upwards, I really really really really really strongly encourage you to find another way.

Consider what you're asking: Can I have my view know about the guts of my controller?

Or what you're really asking: Can I have my view know about the guts of my runtime?

A view is supposed to take data and transform it into markup. That's IT. If you do anything else, you're doing it wrong. I don't care how "easy" it is. That's the point of an interface. To define exactly what is being passed, and to make it easy to replace one thing with another thing.

Upvotes: 0

Related Questions