7

我有一个名为 layout.jade 的所有模板都扩展的 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 的对象自动设置一些默认选项?还是有更好的方法来做到这一点?

基本上我在问我如何才能让一些变量始终发送到模板,以及通过在路由中手动设置它们来在某些模板中提供某些自定义变量的能力。

4

3 回答 3

7

看来这实际上是一个我很难找到的记录功能,除非有人有更好的方法;从最新的Express 文档中,

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
于 2013-09-20T08:00:56.143 回答
5

如果您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,则保证在渲染时拥有最新版本。

于 2013-09-19T01:47:41.173 回答
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', {});
});
于 2013-09-19T01:39:18.830 回答