Express Middleware为所有app.get()填充Jade变量

时间:2013-09-18 22:38:12

标签: javascript node.js express pug

我有一个Jade文件,我的所有模板都扩展名为layout.jade。在其中我希望能够在用户当前登录时有一个注销按钮(这在req.session中保持跟踪)。

所以layout.jade会有类似的东西,

-if (loggedin)
  a.navButton(href="/logout") Log Out

页面的路径看起来像是

app.get("/foo", function(req, res) {
    res.render("foo", {loggedin: req.session.isValidUser});
});

问题是,我不想在每个路由中手动填充登录变量。有没有办法可以使用Express中间件自动为发送到res.render的对象设置一些默认选项?或者有更好的方法来做到这一点吗?

基本上我问的是如何将一些变量总是发送到模板,以及通过在路径中手动设置某些模板中某些自定义变量的功能。

3 个答案:

答案 0 :(得分:7)

看起来这实际上是一个我记不清的功能,除非有人有更好的方法。来自最新的Express documentation

  

app.locals :应用程序本地变量提供给所有模板   在应用程序中呈现。这对提供帮助很有用   功能到模板,以及应用级数据。

所以在我的登录成功功能中,

req.session.username = profile.username;
app.locals.username = profile.username;

我的退出功能,

app.get('/logout', function (req, res) {
    delete app.locals.username;
    req.session.destroy();
    res.redirect('/login');
});

最后在layout.jade /我的所有模板中,

- if(username)
  a.navButton(href="/logout") Logout

答案 1 :(得分:4)

如果您在res.locals.loggedin路线中设置/login,正如六氰化物所示,此地方 将在/foo的路线中可用。每次请求都会清除res.locals

您可以尝试将其置于其他路线之上:

app.all('*', function(req, res, next){
  if(req.user){
    res.locals.loggedin = true;
    res.locals.currentuser = req.user;
  };
  next();
});

非常确定如果您在路线中修改req.user,之前设置的res.locals.currentuser将不会更新为新的req.user。但不确定。

我实际上为每个呈现模板的页面使用自定义render函数,它看起来像这样:

function myRender(templateName){
  return function(req, res){
    res.locals.currentuser = req.user || null;
    res.render(templateName);
  };
};

我这样用它:

app.get('/foo'
, function(req, res, next){
  res.locals.bar = req.query['bar'] || "";
  console.log('passing request to myRender middleware');
  next();
}
, myRender('foo-jade-template')
)

这样做的好处是,当我准备渲染某些东西时,而不是在执行我的路线之前,只设置res.locals.currentuser。因此,如果我更改req.user,则保证在渲染时具有最新版本。

答案 2 :(得分:1)

在Express源中有一行代码对您非常有用:

// merge res.locals
options._locals = self.locals;

因此,当您运行res.render()时,Express还会将res.locals中存储的所有本地文件传递给渲染器。因此,您只需将res.locals.loggedin设置为true,然后照常运行res.render()

app.get('/login', function(res, res) {
  res.locals.loggedin = true;
});
app.get('/foo', function(req, res) {
  res.render('foo', {});
});