ExpressJS without Jade? Use Underscore template!
Many of you must have felt like a burden knowing that Express recommended you to learn another template language (Jade).
Don’t worry, you can code all your templates on HTML using underscoreJS!
Oh yay?
Let’s take a look on how you implement that on your express app.
First install express package, create your express app:
$ npm install -g express $ express ./foo && cd ./foo
Install your underscore package
$ npm install -d underscore
If you edit
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
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());
});
// Routes
app.get('/', routes.index);
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
Now, all you need to do is, to comment out 1 line and register underscorejs:
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
//app.set('view engine', 'jade'); ----> Comment this out!!
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
// Add these lines to register underscore template
var _ = require('underscore');
app.register('.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({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', routes.index);
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
Now, go to routesindex.js:
$ vi routes/index.js
Change the template name from ‘index’ to ‘index.html’:
/*
* GET home page.
*/
exports.index = function(req, res){
res.render('index.html', { title: 'Login' })
};
Next, go to views directory and create layout.html
< html >
< head >
< title ><%=title%>< /title >
< /head >
< body >
<%=body%>
< /body >
< /html >
And last, still in views directory, create another file called index.html
Hello World!
And there you go.. you can write your HTMl code in peace =)
Great tutorial. Thumbs up
In reality you would just use https://github.com/visionmedia/ejs since that’s what underscore’s template is based on, except ejs actually supports error reporting etc vs being a ~5 line function taken from John Resig
Cools, ill definitely take a look at ejs. Thanks for the pointer!
Uggg. Alex, Underscore is horrible as a templating language.
The same code in Jade would be:
html
head
title= myTitle
body= myBody
The key to jade being that each element closes itself and elements are nested based on how many spaces are on the line.
With jade you can use tabs for your nesting or two spaces.
html
^^head
^^^^title= myTitle
^^body= myBody
So in this example, everything is inside HTML, head and body are nested 1 level deep, title is nested two levels deep.
Once you know how to read and work with Jade, it becomes a lot clearer and easier to understand than a long HTML document. The real bonus is that you never forget to close a tag anymore because Jade does it for you.
You can also heck out #HAML which is the Ruby-on-Rails default templating language. It operates under a similar design theory.
http://haml-lang.com/
At the end of the day, a Jade or Haml template should theoretically reduce the amount of code you’ve got to write and reduce document complexity. The payoff being faster development and fewer bugs (in a perfect world)
Great post, having to learn yet another tool like Jade while learning Node and Express.js is definitively not ideal. Thanks for posting this. Now I need to check out TJ’s els and see if it is as simple as it sounds
Greetings, register() is now engine() with the most recent version of Express, you might want to mention this as your blog is one of the top hits on making underscore work with Node.
Take care,
TjD.
That’s fucking right, thanks TjD