31

Is there a way to register helper functions to EJS templates, so that they can be called from any EJS template? So, it should work something like this.

app.js

ejs.helpers.sayHi = function(name) {
    return 'Hello ' + name;
});

index.ejs

<%= sayHi('Bob') %>
Farzher
  • 13,934
  • 21
  • 69
  • 100
  • did this work with <%= ? – chovy Nov 04 '12 at 23:30
  • I made up `ejs.helpers` as an example of what I'm looking for, it doesn't exist. So it doesn't matter either way, but you're right I should probably switch it to `<%=` – Farzher Nov 04 '12 at 23:32
  • Are filters out of the question? They're helper-like and documented up front on the EJS github. Your helper would translate to something like `<%= 'Bob' | sayHi %>` in the template. The function would be written identically. – numbers1311407 Nov 04 '12 at 23:36
  • My apologies if you're not talking about visionmedia's ejs. Jumping to conclusions over here. – numbers1311407 Nov 04 '12 at 23:42
  • I was trying to test if using filters would actually work, and allow me to pass multiple arguments. I suppose if I passed an object as the argument, that would work. It feels like a workaround though. – Farzher Nov 04 '12 at 23:47
  • They do. Just separate args with commas. The parsing can get a little wonky though, if your arguments are complex, like objects. – numbers1311407 Nov 04 '12 at 23:53

4 Answers4

38

Yes, in Express 3 you can add helpers to app.locals. Ex:

app.locals.somevar = "hello world";

app.locals.someHelper = function(name) {
  return ("hello " + name);
}

These would be accessible inside your views like this:

<% somevar %>

<% someHelper('world') %>

Note: Express 2.5 did helpers differently.

dylanized
  • 3,765
  • 6
  • 32
  • 44
  • And where do you write such code? A link would have been helpful. – Vadorequest Feb 02 '14 at 11:08
  • You can write this code in the main application body, after doing var app = express(); – dylanized Feb 03 '14 at 17:02
  • Hum. I just don't have app, because it's overloaded by sails.js, and it's probably a bad idea to write that into the app.js, I would prefer to write this into another file called by the app.js – Vadorequest Feb 03 '14 at 18:06
  • 1
    the middleware.js in the config folder gives you an indication of how to do it in https://github.com/stefanbuck/sails-social-auth-example. You could define it there – ajeeshpu Feb 10 '14 at 00:41
  • you can find a gist [here](https://gist.github.com/ajeeshpu/8908454) @Vadorequest for getting the current year based on my comment above. – ajeeshpu Feb 10 '14 at 00:50
  • @ajeeshpu Thanks! I'll take a better look into that, interesting! – Vadorequest Feb 10 '14 at 06:54
  • 1
    I found that an equals was required to make the call in the .ejs document work: <%= someHelper('world') %>. – harvzor Apr 18 '15 at 18:53
  • EDIT: it's working -- This is not working for me... it says `funcName is not defined` – David Callanan Nov 02 '17 at 21:14
23

I have another solution to this, and I think it has some advantages:

  • Don't polute your code exporting filters.
  • Access any method without the need to export them all.
  • Better ejs usage (no | pipes).

On your controller:

exports.index = function(req, res) {
// send your function to ejs
    res.render('index', { sayHi: sayHi });
}

function sayHi(name) {
    return 'Hello ' + name;
};

Now you can use sayHi function inside your ejs:

<html>
    <h1><%= sayHi('Nice Monkey!') %></h1>
</html>

You can use this method to send modules to ejs, for example, you could send 'moment' module to format or parse dates.

robertomarin
  • 1,262
  • 10
  • 8
  • 1
    **+1** The only thing that helped solve my problem on this page was the `=` before the function `<%= sayHi() %>` otherwise it wouldn't print – iConnor Jan 11 '14 at 17:56
5

Here's an example filter...I'm not familiar with helpers.

var ejs = require('ejs');

ejs.filters.pluralize = function(num, str){
    return num == 1 ? str : str+'s';
};


 <%=: items.length | pluralize:'Item' %>

Will produce "Item" if it's 1, or if 0 or > 1, produces "Items"

app.js

ejs.filters.sayHi = function(name) {
    return 'Hello ' + name;
});

index.ejs

<%=: 'Bob' |  sayHi %>
chovy
  • 72,281
  • 52
  • 227
  • 295
4

I am using:

In helpers/helper.js

var func = {
    sayhi: function(name) {
        return "Hello " + name;
    }, 
    foo: function(date) {
        //do somethings
    }    
};
module.exports = func;

In router:

router.get('/', function(req, res, next) {
    res.render('home/index', {
        helper: require('../helpers/helper'),
        title: 'Express'
    });
});

In template:

<%= helper.sayhi("Dung Vu") %>

goodluck

Dũng IT
  • 2,751
  • 30
  • 29