Express.js hbs module - register partials from .hbs file
Solution 1
This code loads all the partial templates in a directory and makes them available by filename:
var hbs = require('hbs');
var fs = require('fs');
var partialsDir = __dirname + '/../views/partials';
var filenames = fs.readdirSync(partialsDir);
filenames.forEach(function (filename) {
var matches = /^([^.]+).hbs$/.exec(filename);
if (!matches) {
return;
}
var name = matches[1];
var template = fs.readFileSync(partialsDir + '/' + filename, 'utf8');
hbs.registerPartial(name, template);
});
Solution 2
For convenience, registerPartials provides a quick way to load all partials from a specific directory:
var hbs = require('hbs');
hbs.registerPartials(__dirname + '/views/partials');
Partials that are loaded from a directory are named based on their filename, where spaces and hyphens are replaced with an underscore character:
template.html -> {{> template}}
template 2.html -> {{> template_2}}
login view.hbs -> {{> login_view}}
template-file.html -> {{> template_file}}
Cheers!
Solution 3
Looks like creating a variable and pulling in the template code manually works:
var hbs = require('hbs')
, fs = require('fs')
, headerTemplate = fs.readFileSync(__dirname + '/views/_header.hbs', 'utf8');
and later:
hbs.registerPartial('headPartial', headerTemplate);
Solution 4
For me I had template file my-partial.hbs
Then I tried to access them via:
{{> my-partial }}
But the partial was stored in hbs as my_partial regardless of the filename.
This is thanks to hbs version 3.1.0 line 218
.slice(0, -(ext.length)).replace(/[ -]/g, '_').replace('\\', '/');
This is in the readme
Solution 5
For me, I have a function like:
var hbs = require('hbs');
var fs = require('fs');
var statupfunc = {
registerHbsPartials : function(){
//this is run when app start
hbs.registerPartials(__dirname + "/" + resource.src.views + '/partials');
},
registerOneHbsPartials : function(event){
//this is run for gulp watch
if(event.type == 'deleted')
{
return;
}
var filename = event.path;
var matches = /^.*\\(.+?)\.hbs$/.exec(filename);
if (!matches) {
return;
}
var name = matches[1];
var template = fs.readFileSync(filename, 'utf8');
hbs.registerPartial(name, template);
}
};
Run statupfunc.registerHbsPartials at app startup and then register gulp watch with statupfunc.registerOneHbsPartials to register partials on new creation
gulp.task('watch', function() {
gulp.watch(resource.src.views + '/partials/*.*', statupfunc.registerOneHbsPartials);
});
![swatkins](https://i.stack.imgur.com/1y6jS.jpg?s=256&g=1)
Comments
-
swatkins almost 2 years
I'm using the handlebars.js hbs wrapper in express.js. I have templates working fine, but I'm needing to add in partials to be rendered with my views.
I'd like to do something like this:
hbs.registerPartial('headPartial', 'header'); // where "header" is an .hbs file in my views folder
However, it's throwing a "header partial can not be found".
I can make the registerPartial work if I pass a string of html to the second param, but I'd like to use separate view files for my partials.
I haven't found any documentation on this, but hoping I may just be missing something easy.
Does anyone know how to use view files in the registerPartial method? If so, how do I implement this?
UPDATE
To give more context, let me add more code. Here is my "server" file - app.js
var express = require('express') , routes = require('./routes') , hbs = require('hbs'); var app = module.exports = express.createServer(); // Configuration app.configure(function(){ app.set('views', __dirname + '/views'); app.set('view engine', 'hbs'); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public')); }); app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); app.configure('production', function(){ app.use(express.errorHandler()); }); // this is the line that generates the error hbs.registerPartial('headPartial', 'header'); // What I'm expecting is for "headPartial" to be a compiled template partial // of the template within views/header.hbs, but it is not loading this way. // If I do something like hbs.registerPartial('headPartial', '<p>test</p>'); // then it does work. I need to know how to pass an .hbs file to the // registerPartial method. // Routes app.get('/', routes.index); app.listen(3000);
And here is my routes.index file:
exports.index = function(req, res){ res.render('index', { title: 'Express' }) };
In my views folder, I have three templates:
views/ header.hbs (this is my partial) index.hbs layout.hbs
In my index.hbs file, I'm calling the 'headPartial' partial with:
{{> headPartial}}
Any help is greatly appreciated.