5

Hello I was wondering if there is a proper way to pass a variable or object to a layout view?

This is what I'm doing at the moment and it works

index: function(req, res){
 res.view({ layout: 'mylayout', myvar: 'This is a view var' });
}

But on every action I have to define 'myvar' so I can use it at the layout level, so what I would like to know if there is some kind of controller or action for layouts so I can place there my logic?

Rodrigo Montano
  • 303
  • 5
  • 13

3 Answers3

19

Actually starting with Sails v0.10-rc5, you can use sails.config.views.locals hash to specify variables that should be provided by default to all views. So in config/views.js, something like:

{
   locals: {
      myvar : 'this is a view var'
   }
}

would add the var to every view. This is mostly useful for variables that affect the view engine; see here for more details.

You can also use a policy in Sails v0.10.x to set vars across multiple views, by altering req.options.locals. So if you created a policy /api/policies/decorate.js with:

module.exports = function(req, res, next) {

   // Default to an object if empty, or use existing locals that may have
   // been set elsewhere
   req.options.locals = req.options.locals || {};

   // Set a new local var that will be available to any controller that
   // implements the policy
   req.options.locals.myVar = Math.random()

and then set up your /config/policies.js with something like:

 module.exports = {

    '*': 'decorate'

 }

then any controller action that uses res.view will have that myVar variable available in the view.

sgress454
  • 24,870
  • 4
  • 74
  • 92
  • Clear and well written answer. You should submit it to the Sails docs. – dbasch Jun 04 '14 at 06:30
  • Be advised, policies will not work for routes without controllers! Issue: https://github.com/balderdashy/sails/issues/3122. – Slava Fomin II Jul 29 '15 at 17:45
  • It's pretty well documented that policies apply to controller actions. The `/config/policies.js` file only refers to controllers and actions--there's no place that would indicate that it applies to bare routes. That being said, you can apply policies directly to routes in your `config/routes.js` file, if you use the [policy target syntax](http://sailsjs.org/documentation/concepts/routes/custom-routes#?policy-target-syntax). – sgress454 Jul 29 '15 at 19:31
2

It depends on the layout engine you have configured with sails (ejs is default). However passing a variable to a view is commonly done like this:

index: function(req, res){
 res.view({ layout: 'mylayout', myModel: modelObj });
}

You have to inject the model in every view that uses it. If you want to register the model a globally you have to use a custom middleware like described here: How to create global variables accessible in all views using Express / Node.JS?

Community
  • 1
  • 1
DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601
0

You can use config.views.locals, but i like to keep this out of the config folder and put it in the api/services directory. I call it api/services/page.js

then add some variable and other view helpers if you want.

module.exports = {
  title:'test',
  appName: 'My App Name',
  getBlueprintPath: function (path) {
    return sails.config.blueprints.prefix + path;
  },
};

then in my view i have

<%= page.appName %>

the advantage of doing this way is your logic is kept inside api directory. You can still set locals for the view and not accidentally override some variable you had previously set in config.views.local.

Richard Torcato
  • 2,504
  • 25
  • 26