Here’s the third lesson in the Express.js tutorial. As always, there are a couple sneaky things, but overall, this isn’t that difficult.
NOTE: I found this blog post to be quite helpful for this lesson:
http://webapplog.com/jade-handlebars-express/
Let’s start with the Directions and Hints:
JADE
Exercise 3 of 8
Create an Express.js app with a home page rendered by Jade template engine.
The homepage should respond to /home.
The view should show the current date using toDateString.
——————————————————————————-
## HINTS
The Jade template file index.jade is already provided:
h1 Hello World
p Today is #{date}.
This is how to specify path in a typical Express.js app when the folder is ‘templates’:
app.set(‘views’, path.join(__dirname, ‘templates’))
However, to use our index.jade, the path to index.jade will be provided as process.argv[3]. You are welcome to use your own jade file!
To tell Express.js app what template engine to use, apply this line to the Express.js configuration:
app.set(‘view engine’, ‘jade’)
Instead of Hello World’s res.end(), the res.render() function accepts a template name and presenter data:
res.render(‘index’, {date: new Date().toDateString()})
We use toDateString() to simply return the date in a human-readable format without the time.
——————————————————————————-
## NOTE
When creating your projects from scratch, install the jade dependency with npm.
Again, the port to use is passed by expressworks to the application as process.argv[2].
The second to last line tells us that Jade is a package and that we need to install it via the npm (Node Package Manager). Here’s how we do that, and the ugly results we get back…
$ npm install jade
npm WARN package.json chat-example@0.0.0 No repository field.
npm WARN package.json chat-example@0.0.0 No license field.
npm WARN deprecated jade@1.11.0: Jade has been renamed to pug, please install the latest version of pug instead of jade
npm WARN deprecated transformers@2.1.0: Deprecated, use jstransformer
jade@1.11.0 node_modules/jade
├── commander@2.6.0
├── character-parser@1.2.1
├── void-elements@2.0.1
├── jstransformer@0.0.2 (is-promise@2.1.0, promise@6.1.0)
├── mkdirp@0.5.1 (minimist@0.0.8)
├── constantinople@3.0.2 (acorn@2.7.0)
├── with@4.0.3 (acorn@1.2.2, acorn-globals@1.0.9)
├── clean-css@3.4.13 (commander@2.8.1, source-map@0.4.4)
├── transformers@2.1.0 (promise@2.0.0, css@1.0.8, uglify-js@2.2.5)
└── uglify-js@2.6.2 (uglify-to-browserify@1.0.2, source-map@0.5.6, yargs@3.10.0)
We’ll start with the variables. Note that they tell us that, as before, the port and filePath will be supplied in process.argv.
var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];
var app = express();
We also know that we are going to listen on a port, and they give us two app.set() statements as well, giving us:
var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];
var app = express();
app.set('views', path.join(__dirname, 'templates'));
app.set('view engine', 'jade');
app.listen(port);
Finally, we’re serving a page, so we need an app.get() function, inside of which will be the page we are “rendering”. They give us this render statement, too, and so we have:
var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];
var app = express();
app.set('views', path.join(__dirname, 'templates'));
app.set('view engine', 'jade');
app.get('/', function(req, res) {
res.render('index', {date: new Date().toDateString()})
})
app.listen(port);
And………..it doesn’t work. It keeps saying “cannot get /home”. Yeah, I hate when I can’t get home too. Okay, so I thought this would be an easy fix. Remembering the first lesson, I changed the ‘/’ in the app.get statement to ‘/home’ and ran it again.
Still didn’t work.
I was a little frustrated now. What had I missed? I read and reread the instructions. Then I caught it – I hadn’t used the filePath variable anywhere, so the program didn’t know where to look for the Jade file. But the question was, where do I use it?
Well, see that app.set() with the path.join statement? That looked awfully familiar from the Static exercise, where we used:
app.use(express.static(process.argv[3]||path.join(__dirname, 'public')));
So, I added “process.argv[3]||” to my app.use() statement and, lo and behold, the program passed! Here’s the final program, for reference:
var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];
var app = express();
app.set('views', process.argv[3]||path.join(__dirname, 'templates'));
app.set('view engine', 'jade');
app.get('/home', function(req, res) {
res.render('index', {date: new Date().toDateString()})
})
app.listen(port);
See you next time!