Build Express.js Web Applications Faster with Jade and Stylus
If I had a dollar for every hour spent over the past 15 years agonizing over HTML and CSS, my Developer.com articles would be filed from a penthouse balcony in San Juan. Paradoxically, the almost manic obsession with constantly tweaking Web layouts seems to be particularly prevalent among those who tend to experience the most frustration in doing so, namely developers lacking refined design skills. Falling squarely into this crowd, the process of sorting through seemingly countless DIV
s, classes, selectors, and inheritances has always seemed an exercise in insanity, one which stood out in stark contrast to my highly organized coding environment.
These frustrations largely vanished when I began working with Node.js a few months ago. Although still relatively nascent, the Node.js community has really seemed adept at acknowledging the Web's past successes and failures, creating a powerful ecosystem of technologies which collectively contribute to a highly productive development environment. Among these contributions are the Jade templating engine and Stylus CSS preprocessor. I like to think of Jade and Stylus as HTML and CSS done right, particularly for developers who prefer a somewhat more structured environment.
Introducing Jade
The Jade templating engine is one of many Node.js-related projects created and maintained by the apparently insomnia-stricken developer TJ Holowaychuk. Based upon the ideas of HAML, another popular templating engine which seeks to introduce clarity into the HTML development process, Jade relies upon a blend of indentation, intuitive syntactical shortcuts, and the introduction of just enough logic to produce even the most sophisticated HTML layouts. Consider for instance the following Jade template:
!!! 5
html
head
title Tailgating Recipes
body
div#container
h1 Turkey Chili
ul.recipe
li 1 pound turkey
li Tomato sauce
Rendered using Jade, the above template will produce the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>Tailgating Recipes</title>
</head>
<body>
<div id="container">
<h1>Turkey Chili</h1>
<ul class="recipe">
<li>1 pound turkey</li>
<li>Tomato sauce</li>
</ul>
</div>
</body>
</html>
A quick glance at the source and output should be enough for most developers to conclude which syntax is more enjoyable to write.
Using Jade with Express
Although Jade was created with Node.js in mind, a number of ports have already been made, including for PHP, Ruby, and Scala. I'd imagine the majority of readers would like to know more about Jade's Node-specific applicability, and so I will demonstrate how to go about integrating it into the Express Node.js framework. Presuming you've already installed Node.js and Express, install Jade using the Node Package Manager:
$ npm install jade
Although I'm jumping ahead a bit, go ahead and install Stylus as well, since we'll be talking about it later in this article:
$ npm install stylus
Next, create a new Express application, adding Jade and Stylus support:
$ express -t jade -c stylus
Express will create a Jade template (views/layout.jade
) and home page view (views/index.jade
). Open up the layout.jade
file and you'll see the following markup:
!!!
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body!= body
The title= title
and body!= body
declarations are Express' way of determining where a view variable should be inserted, and where the view should be inserted into the layout, respectively, but everything else you otherwise see is Jade-specific. Try tinkering with the layout.jade
and index.jade
markup, using the many examples found in the Jade README as the basis for experimentation.
Iterating Over Dynamic Data with Jade
One feature which tends to confuse many Jade beginners pertains to how dynamic data can be embedded into a Jade template. Using Express, this task is actually pretty easy. As an example, modify the index
route, passing along an array containing various tailgating recipes:
app.get('/', function(req, res){
res.render('index', {
title: 'Tailgating Recipes',
recipes: ['Turkey Chili', 'Jalapeno Poppers', 'Fudge Brownies']
});
});
Within the corresponding index.jade
view, you can use Jade's each
iterator to iterate over each array:
h1= title
p Welcome to #{title}
ul
each recipe in recipes
li= recipe
It's that simple!
Originally published on https://www.developer.com.
Page 1 of 2
This article was originally published on November 11, 2011