ericf / express-handlebars

A Handlebars view engine for Express which doesn't suck.
BSD 3-Clause "New" or "Revised" License
2.31k stars 384 forks source link

handlebar helpers not available at application level #177

Open robsilva opened 8 years ago

robsilva commented 8 years ago

I would like to have my handlebar helpers available to all my views, but for some reason this doesn't work:

var express = require('express');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var logger = require('morgan');
var handlebars = require("express-handlebars");
var path = require('path');
var favicon = require('serve-favicon');

module.exports = function(app, envConfig){
  // view engine setup
  app.set('views', path.join(envConfig.rootPath, 'views'));

  var hbs = handlebars.create({
    helpers: {
      foo: function () { return 'FOO!'; },
      bar: function () { return 'BAR!'; }
    }
  });

  app.engine('.hbs', handlebars({
    extname: '.hbs',
    defaultLayout: 'main', 
    layoutsDir: path.join(envConfig.rootPath,'views/layouts'),
    partialsDir: path.join(envConfig.rootPath, 'views/partials')
  }));
  app.set('view engine', '.hbs');
  app.use(logger('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({extended: true}));
  app.use(cookieParser());  
   app.use(session({
    secret: 'temporary',
    resave: true,
    saveUninitialized: true
  }));
  app.use(flash());
  app.use(express.static(path.join(envConfig.rootPath, 'public')));
};

When I try to output that in my view I get nothing.

But if I set the function inside my render() method, it works:

var request = require('request');
var faker = require('faker');
var _ = require('lodash');

module.exports = {
  index: function(req, res){

      var numRecords = 10;
        var profiles = [];
        for(i=0; i < numRecords; i++) {

            profiles.push({
                full_name: faker.name.findName(),
                blurb: faker.lorem.words(5),
                avatar: faker.image.avatar()
            });
        }

    res.render('profiles/index', { 
        profiles: profiles, 
        layout : 'main',
        helpers: {
        foo: function () { return 'FOO!'; },
        bar: function () { return 'BAR!'; }
        }
     });
  }
};

Has anyone run into this issue?

Thank you in advance.

pranavmahajan21 commented 8 years ago

When I call the helper like this {{foo}} it works, but with inbuilt helpers like this {{#each foo}} {{/each}} it doesn't work. Are you facing the same issue? http://stackoverflow.com/questions/37178436/express-handlebars-built-in-helpers-not-working

mariano-aguero commented 8 years ago

Same problem here

piyushbeli commented 8 years ago

Same here, also if I register any custom helpers in exhbs.handlebars instance then also it is not available in applicaiton helper. If we can not set the custom helper in global handlebar's instance then this module is of no use. I am currrently using https://github.com/barc/express-hbs in my project but because of slow rendering I was trying some alternative library.

anderskristo commented 8 years ago

Bah, same problems here...

Can only render helper functionality from the render method. Is there anyone with an answer to this?

bendersej commented 8 years ago
app.engine('handlebars', exphbs({
  defaultLayout: 'main',
  helpers: {
    yourFirstGlobalHelper: function (foo) { return foo },
    yourSecondGlobalHelper : function (bar) { return bar}
  }
}));

app.set('view engine', 'handlebars');

And in your templates, simply call your global helpers this way:

<div>{{yourFirstGlobalHelper foo }}</div>

zolitch commented 7 years ago

I've replicated this too.

So for me when I have a an each helper: {{#each someArray}} {{>partial itemInArray}} {{/each}} Then in the partial.hbs, custom helpers that have been added to global Express are not available.

This also seems to be true for parent context items when in each ( ../parentItem) and there is a bug for this too: #196