How to create global variables available in all views using Express / Node.JS?

Ok, so I created a blog using Jekyll and you can define the variables in the _config.yml file that are available in all templates / layouts.I currently use Node.JS / Express with EJS and ejs-locals (for partial / layouts. I am looking for something similar to global variables like site.title which are in _config.yml if someone is familiar with _config.yml have variables like site name (instead of page name), author / company name that remain unchanged on all my pages.

Here is an example of what I'm doing now:

 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 such as the name of my site, description, author, etc. in one place, and have them available in my layouts / templates via EJS without having to pass them as parameters for each res.render call. Is there a way to do this and still allow other variables specific to each page to be passed?

+69
template-engine express ejs
May 08 '13 at 23:52
source share
7 answers

After I was able to examine the Express 3 API Reference, I discovered what I was looking for. In particular, the entries for app.locals and then a little further on res.locals provided the answers I needed.

I myself discovered that the app.locals function takes an object and saves all its properties in the form of global variables app.locals with the application. These global variables are passed as local variables for each view. The res.locals function, however, is bound to the request, and thus the local response variables are only available for the views displayed during this particular request / response.

So for my case, in my app.js application app.js I added:

 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 these variables are available in my views as site.title , site.description , author.name , author.contact .

I could also define local variables for each response to the request with res.locals or simply pass variables, such as the page title, as options parameters in the render call.

EDIT: This method will not allow you to use these locals in your middleware. I actually came across this, as Pickels suggests in the comment below. In this case, you will need to create an intermediate function as such in its alternative (and evaluated) answer. The intermediate res.locals function will have to add them to res.locals for each response, and then call next . This middleware function should be placed on top of any other middleware that these locals should use.

EDIT: Another difference between declaring locals through app.locals and res.locals is that with app.locals variables are set once and stored throughout the application. When you install locals with res.locals in your middleware, they are installed every time you receive a request. Basically, you prefer to set global variables through app.locals if the value is independent of the request req variable passed to the middleware. If the value does not change, then it will be more efficient to set it only once in app.locals .

+94
May 11 '13 at 22:14
source share

You can do this by adding them to the locals object in the common middleware.

 app.use(function (req, res, next) { res.locals = { siteTitle: "My Website Title", pageTitle: "The Home Page", author: "Cory Gross", description: "My app description", }; next(); }); 

Locales are also a function that extends the locals object rather than overwriting it. So the following also works

 res.locals({ siteTitle: "My Website Title", pageTitle: "The Home Page", author: "Cory Gross", description: "My app description", }); 

Full example

 var app = express(); var middleware = { render: function (view) { return function (req, res, next) { res.render(view); } }, globalLocals: function (req, res, next) { res.locals({ siteTitle: "My Website Title", pageTitle: "The Root Splash Page", author: "Cory Gross", description: "My app description", }); next(); }, index: function (req, res, next) { res.locals({ indexSpecificData: someData }); next(); } }; app.use(middleware.globalLocals); app.get('/', middleware.index, middleware.render('home')); app.get('/products', middleware.products, middleware.render('products')); 

I also added general rendering middleware. This way you do not need to add res.render for each route, which means that you have better code reuse. As soon as you go down the reusable middleware path, you will notice that you will have many building blocks that will greatly accelerate development.

+48
May 9 '13 at 13:47
source share

For Express 4.0, I found that using application-level variables works a little differently, and Corey's answer doesn't work for me.

From the docs: http://expressjs.com/en/api.html#app.locals

I found that you can declare a global variable for the application in

 app.locals 

eg

 app.locals.baseUrl = "http://www.google.com" 

And then in your application you can access these variables, and in your explicit middleware, you can access them in the req object as

 req.app.locals.baseUrl 

eg.

 console.log(req.app.locals.baseUrl) //prints out http://www.google.com 
+13
Mar 18 '16 at 5:08
source share

In your app.js application you need to add something like this

 global.myvar = 100; 

Now, in all of your files that you want to use this variable, you can simply access it as myvar

+8
Sep 20 '13 at 20:46
source share

One way to do this is by updating the app.locals variable for this application in app.js

Install through the following

 var app = express(); app.locals.appName = "DRC on FHIR"; 

Get / access

 app.listen(3000, function () { console.log('[' + app.locals.appName + '] => app listening on port 3001!'); }); 

Take a screenshot from the @RamRovi example with a little improvement.

enter image description here

+1
Jul 16 '16 at 1:15
source share

you can also use global

Example:

declare the following:

  app.use(function(req,res,next){ global.site_url = req.headers.host; // hostname = 'localhost:8080' next(); }); 

Use the following: in any views or ejs file <% console.log (site_url); %>

in js files console.log (site_url);

+1
Oct 21 '16 at 8:02
source share

What I do in order to avoid a polluted global scope is to create a script that I can include anywhere.

 // my-script.js const ActionsOverTime = require('@bigteam/node-aot').ActionsOverTime; const config = require('../../config/config').actionsOverTime; let aotInstance; (function () { if (!aotInstance) { console.log('Create new aot instance'); aotInstance = ActionsOverTime.createActionOverTimeEmitter(config); } })(); exports = aotInstance; 

Doing this will create only one instance and share it wherever it is. I'm not sure if this is due to the fact that the variable is cached or because of the internal link mechanism for the application (which may include caching). Any comments on how node resolves this would be great.

Perhaps also read this to understand the essence of the work: http://fredkschott.com/post/2014/06/require-and-the-module-system/

0
Jul 26 '17 at 11:46
source share



All Articles