且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用Express / Node.JS在所有视图中创建全局变量?

更新时间:2023-11-14 10:04:22

有机会要学习 Express 3 API参考 ,我发现我发现了什么对于。具体来说, app.locals 的条目 ,然后再进一步 res.locals 保存了我需要的答案。



我发现自己的功能 app.locals 获取一个对象,并将其所有属性存储为范围为应用程序的全局变量。这些全局变量作为局部变量传递给每个视图。然而,功能 res.locals 的范围限于请求,因此,响应局部变量只能访问在该特定请求/响应期间呈现的视图。 / p>

所以对于我的例子,我的 app.js 我所做的是添加:

  app.locals({
site:{
title:'ExpressBootstrapEJS',
description:'一个简单的样板具有Node.JS和Express后端的Web应用程序,以及使用Twitter Bootstrap的EJS模板。
},
作者:{
name:'Cory Gross',
contact :'CoryG89@gmail.com'
}
});

然后,所有这些变量都可以在我的视图中访问为 site.title site.description author.name author.contact



我还可以为每个响应定义本地变量,其中包含 res.locals ,或者简单地将 c> c 中的选项$ c>参数中的变量像页面的标题一样传递。 >

编辑:此方法将允许您在中间件中使用这些本地人。 Pickels在下面的评论中建议我实际上是这样做的。在这种情况下,您将需要在他的替代(和赞赏)答案中创建一个中间件功能。您的中间件功能将需要将它们添加到每个响应的 res.locals 中,然后调用 next 。这个中间件功能需要放置在任何其他需要使用这些本地化的中间件之上。



编辑: code> app.locals 和 res.locals 是与 app.locals 变量设置为单一时间,并在应用程序的整个生命周期中持续存在。当您在中间件中设置 res.locals 的本地人时,每当您收到请求时都会设置这些。您应该基本上喜欢通过 app.locals 设置全局变量,除非该值取决于传递到中间件的请求 req 变量。如果值不变,那么在 app.locals 中只能设置一次就更有效了。


Ok, so I have built a blog using Jekyll and you can define variables in a file _config.yml which are accessible in all of the templates/layouts. I am currently using Node.JS / Express with EJS templates and ejs-locals (for partials/layouts. I am looking to do something similar to the global variables like site.title that are found in _config.yml if anyone is familiar with Jekyll. I have variables like the site's title, (rather than page title), author/company name, which stay the same on all of my pages.

Here is an example of what I am currently doing.:

exports.index = function(req, res){
    res.render('index', { 
        siteTitle: 'My Website Title',
        pageTitle: 'The Root Splash Page',
        author: 'Cory Gross',
        description: 'My app description',
        indexSpecificData: someData
    });
};

exports.home = function (req, res) {
    res.render('home', {
        siteTitle: 'My Website Title',
        pageTitle: 'The Home Page',
        author: 'Cory Gross',
        description: 'My app description',
        homeSpecificData: someOtherData
    });
};

I would like to be able to define variables like my site's title, description, author, etc in one place and have them accessible in my layouts/templates through EJS without having to pass them as options to each call to res.render. Is there a way to do this and still allow me to pass in other variables specific to each page?

After having a chance to study the Express 3 API Reference a bit more I discovered what I was looking for. Specifically the entries for app.locals and then a bit farther down res.locals held the answers I needed.

I discovered for myself that the function app.locals takes an object and stores all of its properties as global variables scoped to the application. These globals are passed as local variables to each view. The function res.locals, however, is scoped to the request and thus, response local variables are accessible only to the view(s) rendered during that particular request/response.

So for my case in my app.js what I did was add:

app.locals({
    site: {
        title: 'ExpressBootstrapEJS',
        description: 'A boilerplate for a simple web application with a Node.JS and Express backend, with an EJS template with using Twitter Bootstrap.'
    },
    author: {
        name: 'Cory Gross',
        contact: 'CoryG89@gmail.com'
    }
});

Then all of these variables are accessible in my views as site.title, site.description, author.name, author.contact.

I could also define local variables for each response to a request with res.locals, or simply pass variables like the page's title in as the optionsparameter in the render call.

EDIT: This method will not allow you to use these locals in your middleware. I actually did run into this as Pickels suggests in the comment below. In this case you will need to create a middleware function as such in his alternative (and appreciated) answer. Your middleware function will need to add them to res.locals in for each response and then call next. This middleware function will need to be placed above any other middleware which needs to use these locals.

EDIT: Another difference between declaring locals via app.locals and res.locals is that with app.locals the variables are set a single time and persist throughout the life of the application. When you set locals with res.locals in your middleware, these are set everytime you get a request. You should basically prefer setting globals via app.locals unless the value depends on the request req variable passed into the middleware. If the value doesn't change then it will be more efficient for it to be set just once in app.locals.