1

Coming from a Rails/Sinatra background, I won't feel at home without being able to use helper functions in my view files, however achieving this in express.js has proven quite difficult.

You can set locals to be automatically included like this...

app.set("name", "Adam's App");

Then in the view file, accessing the variable is as simple as:

<!-- views/template.ejs -->
<title><%= settings.name %></title>

But what about for functions? What if I want to have a date_helper function in my views? I tried setting it like you would a variable...

app.set("date_helper", function(timestamp){ ... });

...however calling <%= settings.date_helper %> won't execute the function (obviously), let alone enable me to pass the timestamp argument to it.

Am I going about this the right way?

3
  • When you render it, do you try passing the function directly? .render('something', { settings: app.settings, helper: function(){...} }, function (err, stuff) {...}); along those lines ish Commented Jul 31, 2014 at 12:01
  • @Deryck I haven't needed to use settings: app.settings (I think that's been deprecated in express 3.0?). That aside - my aim here is to have access to these functions without having to specify it in the .render block. It seems pretty lame having to use date_helper: function(){..} in every route I define, agreed? Commented Jul 31, 2014 at 12:11
  • 1
    Yeah I was just saying as a troubleshooting option but the answer below me actually has it. I was going to suggest the app.locals.date_helper assignment but looks like his is better than what I was gonna say lol Commented Jul 31, 2014 at 12:34

2 Answers 2

2

You can set view variables at the app level, the response level, and/or at the time of render.

So you could combine these and do something like:

app.locals.date_helper = function(ts) {
  return (new Date(ts)).toISOString();
});

app.get('/', function(req, res) {
  res.render('main', { timestamp: 1406809421643 });
});

Then inside your template:

The date is: <%= date_helper(timestamp) %>

On a semi-related note, you should be aware of special view variable names used by ejs.

Sign up to request clarification or add additional context in comments.

5 Comments

Cool. Doesn't app.set(x) do exactly the same thing as app.locals.x though?
You probably could use that, but then you have to do things like settings.date_helper(timestamp) in your views. app.set()/app.get()/settings should generally be used for application settings only, not adding helpers and other similar view-specific things.
Mhmmm. Suppose you had an object with helper functions to set: var helpers = { date_helper: function(){...}, name_helper: function(){...} }. If we were to loop through each kv pair in the object to set each one, would it be possible to set them using app.locals?
I currently do it with app.set using: Object.keys(helpers).forEach(function(helper) { app.set(helper, helpers[helper]) });
Yes, you could do something similar for app.locals: Object.keys(helpers).forEach(function(helper) { app.locals[helper] = helpers[helper] });
0

use app middleware

app.use((req, res, next) => {
    res.locals = {
        test: 'Sample Test',
        test_function: (name) => {
            return 'Hello ' + name;
        }
    }
    next();
});

in view you can use

<%= test %> // output = " Sample test "
<%= test_function("Abdo") %> // output = " Hello Abdo"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.