How to use Underscore templates instead of Jade in Express?

I don't want to use the Jade templating engine that comes by default with Express. I tried to follow this guide but it fails:

http://blog.luksidadi.com/expressjs-underscore-template/

The error in question is:

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: callback function required
    at Function.engine (/home/me/blog/node_modules/express/lib/application.js:173:38)
    at Object.<anonymous> (/home/tk/blog/app.js:28:5)
    at Module._compile (module.js:432:26)
    at Object..js (module.js:450:10)
    at Module.load (module.js:351:31)
    at Function._load (module.js:310:12)
    at Array.0 (module.js:470:10)
    at EventEmitter._tickCallback (node.js:192:40)

I get this when I try to start the server with:

node app.js

How to solve this?

app.js:

/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  //app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

// Add these lines to register underscore template
var _ = require('underscore');
app.engine('.html', {
  compile: function(str, options){
    var compiled = require('underscore').template(str);
    return function(locals) {
        return compiled(locals);
    };
  }
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index);
app.get('/users', user.list);

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

routes/index.js:

/*
 * GET home page.
 */

exports.index = function(req, res){
  res.render('index.html', { title: 'Express' });
};

layout.html:

< html >
  < head >
    < title ><%=title%>< /title >
  < /head >
  < body >
  <%=body%>
  < /body >
< /html >

index.html:

Hello world

Use consolidate.js to convert Underscore's template functions to accept the format Express requires in 3.x (path[, locals], callback).

First, you are calling app.engine with an extension name and an object whereas it takes a function as second parameter (see source documentation).

This function has 3 parameters : the path to the file, options and the callback.

As, written in the documentation, it's advised to use consolidate.js as an helper to use template engines that are not express friendly.

Here a simple integration of consolidate.js quoted from its README and adapted to use underscore:

// assign the swig engine to .html files
app.engine('html', cons.underscore);

// set .html as the default extension 
app.set('view engine', 'html');

Also, I don't know how to handle your layout.html with underscore under Express, I don't think it's possible out of the box.

var cons = require('consolidate');

// view engine setup

app.engine('html',cons.underscore);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');

in terminal

npm install consolidate --save