Search code examples
javascriptexpresshandlebars.jshelper

How to make a handlebars helper global (in expressjs)


I've got a pretty simple handlebars helper file in helpers/handlebars.js:

var hbs = require('express-handlebars');

hbs.registerHelper("inc", function(value, options) {
    return parseInt(value) + 1;
});

However, as expected, I can't refer to the {{#inc}} helper because I didn't pass it into the res.render() function. Is there a way to make all helpers in my file global and "auto-included"?

edit:

After trying @1cgonza's awesome answer, I get:

hbs.registerHelper("inc", function(value, options) {
      ^
TypeError: undefined is not a function

When running the app. Here's the app.js:

var engine      = require('express-handlebars');
                  require('./helpers/handlebars.js')(engine);

app.engine('hbs',           engine({defaultLayout: 'layout', extname: 'hbs'}));
app.set('view engine',      'hbs');

Any ideas?


Solution

  • You could try exporting your helpers as a module and then include them in your main app.js

    Something like this:

    In your helpers/handlebars.js

    function hbsHelpers(hbs) {
      hbs.registerHelper("inc", function(value, options) {
        return parseInt(value) + 1;
      });
    
      // More helpers...
    }
    
    module.exports = hbsHelpers;
    

    Then in your app.js (or the file you are using as the index).

    var hbs = require('express-handlebars');
    require('./helpers/handlebars')(hbs);
    

    Does that work for you?

    EDIT

    Based on the express-handlebars docs, I would change the function in your helpers/handlebars.js to something like this:

    function hbsHelpers(hbs) {
      return hbs.create({
        helpers: { // This was missing
          inc: function(value, options) {
            console.log('reading it');
            return parseInt(value) + 1;
          }
    
          // More helpers...
        }
    
      });
    }
    
    module.exports = hbsHelpers;
    

    Let us know if it works.

    EDIT 2:

    My Bad, wrapping your helpers inside a helpers:{} was missing from the create() function in the handelbars.js file. I've edited my previous answer, see where I placed the comment to know what I am talking about.

    As for the app.js I think it is a little mixed up, so let me rename a few things to make it clear:

    // I've changed this from engine to exphbs,
    // so there is no confusion with the express engine object that we use later.
    var exphbs = require('express-handlebars');
    
    // Create an instance of the express-handlebars
    // If you want to pass any option offered by express-handlebar module
    // do it inside the create() in the handlebars.js file
    var handlebars  = require('./helpers/handlebars.js')(exphbs);
    
    // The handlebars variable now has an object called engine.
    // Use that to define your app.engine
    // As said before, you don't need to define any options here.
    // Everything is defined in the create() in handlebars.js
    app.engine('hbs', handlebars.engine);
    
    // If you are using a different extension, you can change hbs to whatever you are using. 
    app.set('view engine', 'hbs');