'Handlebars registerHelper serverside with Expressjs
I am using expressjs with handlebars as templating engine with following code in Webstorm IDE with express generator.There is no visible handlebars require in the code (I guess express generator has it someplace else which is not visible)
var app = express();
.
.
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
How do i use registerHelper on serverside in this situation ?
My other renderings and partials are working.So handlebars is doing its work.Its just that registerHelper seems to be cause of worry.
Solution 1:[1]
I have given a thumbs up to @Mukesh Sharma as he very nearly had the syntax that worked for me and really led me to it.
He is doing a bit more to make it work for the front end I believe. All I needed was the following
// index.js
//in the declarations
const exphbs = require('express-handlebars');
//when configuring the app view engine
app.engine('.hbs', exphbs({
extname: '.hbs',
helpers: require('./config/handlebars-helpers') //only need this
}));
app.set('view engine', '.hbs');
Then I have a simple file I include from where I have helper stuff .
// config/handlebars-helpers.js
module.exports = {
ifeq: function(a, b, options){
if (a === b) {
return options.fn(this);
}
return options.inverse(this);
},
bar: function(){
return "BAR!";
}
}
No need to pass or import handlebars-express - including the simple object of helper functions as part of the exhbs options hash under helpers lets express hbs do all of the registering by it's own approach.
(Bonus ifeq is a tiny helper that compares two arguments and will show the block if true .. useful for something like:
class = "{{#ifeq thisUrl '/about'}}active{{/ifeq}}" .. to set a nav pill class as 'active' ) found it here https://gist.github.com/pheuter/3515945
Solution 2:[2]
I think express-generator
just sets view engine
to hbs
only. To configure the hbs
engine, you have to use express-handlebars
.
e.g.
var app = express(),
exphbs = require("express-handlebars");
app.engine("hbs", exphbs({
defaultLayout: "main",
extname: ".hbs",
helpers: require("./public/js/helpers.js").helpers, // same file that gets used on our client
partialsDir: "views/partials/", // same as default, I just like to be explicit
layoutsDir: "views/layouts/" // same as default, I just like to be explicit
}));
app.set("view engine", "hbs");
And, helpers.js
var register = function(Handlebars) {
var helpers = {
// put all of your helpers inside this object
foo: function(){
return "FOO";
},
bar: function(){
return "BAR";
}
};
if (Handlebars && typeof Handlebars.registerHelper === "function") {
// register helpers
for (var prop in helpers) {
Handlebars.registerHelper(prop, helpers[prop]);
}
} else {
// just return helpers object if we can't register helpers here
return helpers;
}
};
module.exports.register = register;
module.exports.helpers = register(null);
Source: http://www.codyrushing.com/using-handlebars-helpers-on-both-client-and-server/
Solution 3:[3]
You can register both your own customer helpers and the ones from 'handlebars-helpers' like this:
const hbshelpers = require('handlebars-helpers');
const multihelpers = hbshelpers(['object', 'string']);
const helpersDM = {
hlp: echo => `Echo: ${echo}.`,
STATIC: `/static`,
};
const hbs = exphbs.create({
layoutsDir: join(__dirname, 'views', 'layouts'),
partialsDir: join(__dirname, 'views', 'partials'),
extname: '.hbs',
defaultLayout: 'base',
helpers: {...multihelpers, ...helpersDM},
});
app.engine('.hbs', hbs.engine);
app.setViewEngine('.hbs');
Solution 4:[4]
I was able to add partial and register a helper using hbs
.
Seems to be it is the same view engine used within express
for templating with handlebars
.
According to hbs
docs, add the following to the entry point of the application: (index.js
or app.js
) and before setting the view engine in express.
index.js
const hbs = require('hbs');
const express = require('express');
hbs.registerHelper('number_format', function (option) {
// option :
// will contain the arguments passed
// to the helper from the template
// computation can be done here
return `USD ${option}`;
});
hbs.registerPartial('partial', function (options, ...rest) {
// options :
// will contain the arguments passed
// to the partial from the template
// as a object (key value pair)
// ex:
console.log(option.argOne) // 1
console.log(option.argTwo) // 2
// ----------
// Have a look at the other arguments like context data
console.log(...rest)
// computation can be done here by using argument values
return `partial value: ARG1:: ${option.argOne} & ARG2:: ${option.argTwo}`;
});
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
Partial in a hbs
template file
<h1>
{{>partial argOne=1 argTwo=2 }}
</h2>
above will generate the following,
<h1>partial value: ARG1:: 1 & ARG2:: 2<h1>
Helper in a hbs
template file
<h1>{{number_format 100 }}</h1>
above will generate the following,
<h1>USD 100</h1>
learn more about handlebars partials using their docs on partials
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | ArKan |
Solution 3 | David Dehghan |
Solution 4 | Jayanga Jayathilake |