Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRYing up layout locals in expressjs rendering

I am using express in nodejs, and am trying to keep my view rendering dry. Inside my layout, I have something like the following (I'm using jade)

body
  nav.login
    -if(currentUser)
      ="logged in information"
    -else
      ="logged out information"
  !=body

The problem is that every time I render, I'm now required to have

res.render('anything.jade',{
  locals: {
    currentUser: req.session.currentUser,
    /*all of my other locals*/
  }
});

It seems like a pain to have to go through all of my rendering calls and add that, and then do the same thing if I have to add any other locals to the layout. Is there some way to keep from having to retype 'currentUser' into the locals everywhere I render

like image 935
Ryan Avatar asked Jan 28 '11 07:01

Ryan


2 Answers

I know this answer is late, but for posterity: if you're using express, you should use the supplied dynamic helpers, which are view-accessible helper functions which take req,res as arguments. In your case:

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

Which means your view could now call #{user}

like image 130
jmreidy Avatar answered Sep 21 '22 20:09

jmreidy


I ended up doing the following:

first, I set up some local variables

app.use(function(req,res,next){
  req.localvars = new Object;
  next();
});

later, I set some local variables

app.use(function(req,res,next){
  req.localvars.currentUser = req.session.currentUser;
  next();
});

I set up a render function

function renderer(file){  
  return function(req,res,next){
    res.render(file,{locals:req.localvars});
  }
}

then for the routing function

app.get('/',blah,blah,whatever,setSomeMoreLocalsHere,renderer(index.jade));

There might be something better, but it's the best solution I've figured out so far

like image 37
Ryan Avatar answered Sep 22 '22 20:09

Ryan