Express.js hbs module - register partials from .hbs file


Question

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.

1
28
11/9/2011 2:41:57 PM

Accepted Answer

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);
});
42
10/3/2012 12:36:59 AM

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!


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon