Jade Starter Tutorial
- Transfer
- Tutorial
Jade is an HTML preprocessor and template engine that was written in JavaScript for Node.js. Simply put, Jade is exactly the tool that gives you the ability to write markup in a completely new way, with a number of advantages over regular HTML.
For example, take a look at the HTML code below:
Ocean's Eleven
- Comedy
- Thriller
Danny Ocean and his eleven accomplices plan to rob
three Las Vegas casinos simultaneously.
And so this markup looks in the Jade format:
div
h1 Ocean's Eleven
ul
li Comedy
li Thriller
p.
Danny Ocean and his eleven accomplices plan to rob
three Las Vegas casinos simultaneously.
The second option seems shorter and more elegant. But Jade is not only pretty markup. Jade has some really useful features that allow you to write modular reusable (reusable) code. But before going deeper, let's review the basics.
The basics
I am going to highlight three key features of Jade:
- Simple tags
- Adding attributes to tags;
- Blocks of text.
If you want to try the code examples below while reading the article, you can use CodePen and choose Jade as a preprocessor for your HTML, or use the online compiler on the official Jade website .
Tags
As you may have noticed earlier, there are no end tags in Jade. Instead, Jade uses tabs to determine the nesting of tags.
div
p Hello!
p World!
In the above example, paragraph tags according to their tabs when compiled will end up inside the div tag. How easy!
Hello!
World!
Jade compiles this precisely, treating the first word on each line as a tag, while subsequent words on that line are treated as text inside the tag.
View this example on CodePen
Attributes
All this, of course, is good, but how to add attributes to our tags? Actually quite simple.
Let's go back to our first example and add a couple of classes and some kind of picture-poster.
div(class="movie-card", id="oceans-11")
h1(class="movie-title") Ocean's 11
img(src="/img/oceans-11.png", class="movie-poster")
ul(class="genre-list")
li Comedy
li Thriller
How wonderful, isn't it?
Ocean's 11
- Comedy
- Thriller
View this example on CodePen
But why stop there? Jade provides special shorthand for identifiers and classes, which further simplifies our markup using familiar notation:
div.movie-card#oceans-11
h1.movie-title Ocean's 11
img.movie-poster(src="/img/oceans-11.png")
ul.genre-list
li Comedy
li Thriller
View this example on CodePen
As you can see, Jade uses a syntax similar to the one you use when writing CSS selectors.
Text blocks
Let's imagine this situation: you have a <p> tag and you want to add a rather large amount of text to it. But stop, because Jade treats the first word of each line as a new HTML tag - and what should I do?
In the very first example, you might already notice a nondescript dot after the paragraph tag. Adding a period after your tag makes it clear to the Jade compiler that everything inside this tag is text.
div
p How are you?
p.
I'm fine thank you.
And you? I heard you fell into a lake?
That's rather unfortunate. I hate it when my shoes get wet.
View this example on CodePen
For the sake of clarity: if I did not put an end after the <p> tag in the example, then the compiled HTML would have an open <i> tag inside it, breaking the phrase “I'm” at the beginning of the line.
Useful features
Now that we’ve figured out the basics, let's look at some really useful features that will make our markup smarter. Among them:
- JavaScript
- Cycles
- Interpolation;
- Mixins.
JavaScript in Jade
Jade is implemented in JavaScript, so using JavaScript in Jade is quite simple. Here is an example:
- var x = 5;
div
ul
- for (var i=1; i<=x; i++) {
li Hello
- }
What have we done here ?! Starting the line with a hyphen, we told the Jade compiler that we wanted to use JavaScript, and that’s it! And this is what we get when we compile this code in HTML:
- Hello
- Hello
- Hello
- Hello
- Hello
View this example on CodePen
We use a hyphen when code should not directly go into the output stream. In case we want to use JavaScript to output something in Jade, we use = . Let's tweak the code above to indicate the numbering of the items in the list:
- var x = 5;
div
ul
- for (var i=1; i<=x; i++) {
li= i + ". Hello"
- }
And voila, we have the numbering:
- 1. Hello
- 2. Hello
- 3. Hello
- 4. Hello
- 5. Hello
View this example on CodePen
Of course, in this case a numbered list would be much more appropriate, but did you catch the idea? See the documentation for more details .
Cycles
Jade uses great syntax to write loops, so you don’t have to resort to JavaScript. Let's walk through the elements of an array in a loop:
- var droids = ["R2D2", "C3PO", "BB8"];
div
h1 Famous Droids from Star Wars
for name in droids
div.card
h2= name
And this will be compiled as follows:
Famous Droids from Star Wars
R2D2
C3PO
BB8
View this example on CodePen.
You can navigate through array objects, as well as use the while loop. Find out more by reading the documentation .
Interpolation
Combine text and JavaScript in this way
p = "Hi there," + profileName + ". How are you doing?"may begin to procrastinate your eye. Doesn't Jade have a more elegant solution to this problem? Bet?
- var profileName = "Danny Ocean";
div
p Hi there, #{profileName}. How are you doing?
View this example on CodePen
Isn’t that more accurate?
Mixins
Mixins, they are like functions, they take parameters as input and generate the corresponding markup. Mixins are announced using the mixin keyword .
mixin thumbnail(imageName, caption)
div.thumbnail
img(src="/img/#{imageName}.jpg")
h4.image-caption= caption
After the mixin has been announced, you can call it with the + symbol .
+thumbnail("oceans-eleven", "Danny Ocean makes an elevator pitch.")
+thumbnail("pirates", "Introducing Captain Jack Sparrow!")
What will be compiled as:
Danny Ocean makes an elevator pitch.
Introducing Captain Jack Sparrow!
Putting it all together
Let's collect all that we managed to learn, in one example. Let's say we have an array of films, each object of which contains the name of the film, the cast (sub-array), rating, genre, link to the IMDB page and the path to the picture (which will be used as the movie poster). The array will look something like this:
- var movieList = [
{
title: "Ocean's Eleven",
cast: ["Julia Roberts", "George Clooney", "Brad Pitt", "Andy Garcia"],
genres: ["Comedy", "Thriller"],
posterImage: "/img/oceans-eleven",
imdbURL: "http://www.imdb.com/title/tt0240772/",
rating: 7
}
// etc...
];
We have 10 films and we want to make nice markup for each of them. Initially, we did not provide for the use of a link to the IMDB page of the film. If the rating of the film is above 5, we give it an icon with the thumb raised up, otherwise, the thumb down. We use all of the above useful Jade functions to write this modular code that will perform the following tasks:
- Create a mixin called movie-card
- Iterate over the array and withdraw the cast.
- Iterate over an array and display genres.
- Check the rating of the movie and assign it the corresponding icon.
- Scrap through an array of films and use the mixin to create markup.
And so, create a mixin:
mixin movie-card(movie)
div.movie-card
h2.movie-title= movie.title
img.movie-poster(src=movie.posterImage)
h3 Cast
ul.cast
each actor in movie.cast
li= actor
div.rating
if movie.rating > 5
img(src="img/thumbs-up")
else
img(src="img/thumbs-down")
ul.genre
each genre in movie.genres
li= genre
A lot of things are happening in this code, but I’m sure that you understand it, since we have already passed it. Now, all we need to do is call this mixin in a loop:
for movie in movieList
+movie-card(movie)
And that’s it! Isn't that cool ?! Here is the final code:
- var movieList = [
{
title: "Ocean's Eleven",
cast: ["Julia Roberts", "George Clooney", "Brad Pitt", "Andy Garcia"],
genres: ["Comedy", "Thriller"],
posterImage: "/img/oceans-eleven",
imdbURL: "http://www.imdb.com/title/tt0240772/",
rating: 9.2
},
{
title: "Pirates of the Caribbean",
cast: ["Johnny Depp", "Keira Knightley", "Orlando Bloom"],
genres: ["Adventure", "Comedy"],
posterImage: "/img/pirates-caribbean",
imdbURL: "http://www.imdb.com/title/tt0325980/",
rating: 9.7
}
];
mixin movie-card(movie)
div.movie-card
h2.movie-title= movie.title
img.movie-poster(src=movie.posterImage)
h3 Cast
ul.cast
each actor in movie.cast
li= actor
div.rating
if movie.rating > 5
img(src="img/thumbs-up")
else
img(src="img/thumbs-down")
ul.genre
each genre in movie.genres
li= genre
for movie in movieList
+movie-card(movie)
And so the code will look after compilation:
Ocean's Eleven
Cast
- Julia Roberts
- George Clooney
- Brad Pitt
- Andy Garcia
- Comedy
- Thriller
Pirates of the Carribean
Cast
- Johnny Depp
- Keira Knightley
- Orlando Bloom
- Adventure
- Comedy
But stop, wait a minute! But what if now we need the ability to go to the IMDB page of the movie by clicking on its name? We just need to add one line
a (href = movie.imdbURL)into our mixin.
mixin movie-card(movie)
div.movie-card
a(href=movie.imdbURL)
h2.movie-title= movie.title
img.movie-poster(src=movie.posterImage)
h3 Cast
ul.cast
each actor in movie.cast
li= actor
div.rating
if movie.rating > 5
img(src="img/thumbs-up")
else
img(src="img/thumbs-down")
ul.genre
each genre in movie.genres
li= genre
View this example on CodePen
Conclusion
Today we have gone from a complete ignorance of the Jade preprocessor to writing, with its help, beautiful modular markup. This is not all that Jade can do, but I hope this article touches your curiosity and you want to know more.
Important note: as some of you may already know, Jade has been renamed Pug. In the future, articles about Jade will use the new title “Pug” or “Pug.js”.