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

Express Middleware to populate a Jade variable for all app.get()'s

本文关键字:填充 Jade 变量 get app Middleware Express      更新时间:2023-09-26

我有一个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});
});

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

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

似乎这实际上是一个记录在案的功能,我只是很难找到,除非有人有更好的方法;从最新的快递文档中,

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');
});

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

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

如果在/login路由中设置res.locals.loggedin,如六氰化物所建议的那样,此本地在路由中将不可用/foores.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则可以保证在渲染时具有最新版本。

在 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', {});
});