Hey Jade!

Far from being a wannabe "missing manual" for Jade this article is simply my own "path of understanding" of how the Jade template engine is utilized in the Express framework, expressed in a simple "work in progress" app which you can find here: https://github.com/victorkane/heyjade

Now, everyone complains that there is "no documentation" for Jade. Actually, just on github, there is a lot in the Readme.md, plus a huge examples directory, plus a jade example in the Express source. Not to mention the Express Guide, which enlightens us on many aspects of how Jade is used with Express.

So I thought I would just work my way through a good part of that, by building a little sample app on github that you can step through by branching through the commits. Again, please follow along here, and check back every now and then for updates as my comprehension goes deeper and deeper (I hope).: https://github.com/victorkane/heyjade

One thing that is a little confusing to many people using Express for the first time, apart from the semantics, is where/how to install it. Do I install it globally or locally? The answer for me at least is: both. You need Express installed globally, for example, so you can use its executable as a first step in generating the scaffolding of your next app.

Step -1 Have npm and express installed globally

Install npm for the first time

(For my article on installing the whole node stack see http://awebfactory.com.ar/node/467). To install the node package manager for the first time do:

$ sudo curl http://npmjs.org/install.sh | sh

Install Express globally for the first time

$ sudo npm install -g express

Update Express globally if it's been a while since you installed it

$ sudo npm update -g express

Step 0 - The Express scaffold

$ cd /path/to/workspace
$ express heyjade
$ cd heyjade
$ vim .gitignore
$ cat .gitignore
node_modules/
logs/
pids/
$ git init
.... created repo on github, pushed scaffold

We now want to install the dependencies listed in package.json and run what we have so far:

$ npm install
jade@0.12.1 ./node_modules/jade
mime@1.2.2 ./node_modules/express/node_modules/mime
connect@1.4.3 ./node_modules/express/node_modules/connect
qs@0.1.0 ./node_modules/express/node_modules/qs
express@2.3.11 ./node_modules/express
Victor-Kanes-MacBook-Pro:heyjade victorkane$ node app.js
Express server listening on port 3000

Step 1 - What do we have initially, jade-wise?

Commit tree: https://github.com/victorkane/heyjade/tree/a6816bc720e424b0c4aaaa0e0de04...

http://localhost:3000/ now showing the classic:

 

Express

Welcome to Express

 

Lines 12 and 13 of app.js set Jade as the default template engine, and the view; so that res.render only requires the name of the index file, and does not require its path or extension.

Line 30 routes the home page to a function rendering views/index.jade. As explained in the Express Guide - View Rendering section, "since we do not use layout: false the rendered contents of index.jade will be passed as the body local variable in layout.jade". The key-value pair for title passed as the second parameter sets up a variable for the invoked jade template(s), used in both views/index.jade and views/layout.jade.

It is assumed in this article that Jade syntax is already understood in relation to the generated HTML. For a clear understanding of Jade syntax itself, see:

Step 2 - Add in elements from the express jade example

Commit tree: https://github.com/victorkane/heyjade/tree/5eb68da7d73561aa1cf5e7a5e5557...

http://localhost:3000

 

Hey Jade!

Welcome to Hey Jade!

 

 

Same as before, this just goes to /views/index.jade via the render method

http://localhost:3000/users

 

Users

tj

ciaran

aaron

 

Explanation: Starting on line 50, res.render() is once again invoked, and the parameters are now the template views/index.jade and the variables passed to it, title and users. As before, the result is automagically passed to views/layout.jade in the local variable body.

As explained in the Express Guide - View Lookup, "The view system also allows for index templates, allowing you to have a directory of the same name. For example within a route we may have res.render(‘users’) either views/users.jade, or views/users/index.jade."

Now, let's take a look at index.jade:

- if (users.length)
h1 Users
#users!= partial('user', users)

Again, as explained in the Express Guide - View Partials, partials are "“mini” views representing a document fragment." In this case, the whole array is passed to the nested template views/users/user.jade and the result is included inside the users div where the partial method, sending the users variable to the template user.jade, is invoked.

http://localhost:3000/users/list

 

  • tj

  • ciaran

  • aaron

 

The unordered list is generated by directly rendering the partial users/list when the request /users/list is received, see line 57 of app.jade:

app.get('/users/list', function(req, res){
res.partial('users/list', {
title: 'Hey Jade! - Users',
list: users
});
});

See both the res.render() section and the res.partial() section in the Express Guide. The partial view:

ul#users
- each user in list
li!= partial('user', user)

http://localhost:3000/user/0

 

tj

This time the partial users/user is directly invoked with a parameter taken from the request, corresponding to the id "0" in the array users on line 64 of app.js:

 

 

app.get('/user/:id', function(req, res){
res.partial('users/user', users[req.params.id]);
});