Let’s Learn: Jade

A flexible template language

Jade is one of many front end template languages out there that aim to remove some of the more tedious parts of HTML while providing additional functionality. What sets Jade apart from others is its simplicity, its readability, and its powerful flexibility.

You simply write your HTML templates in Jade (the language reference is handy). Using the Jade program, you compile Jade templates to HTML.

Let’s Get Started: Install All the Things

$ brew install node
  • Install Jade via npm (the Node.js package manager)
$ npm install jade --global

Writing and Compiling Jade

Let’s assume that we’re working out of a directory called project. Create a file called index.jade.

project$ touch index.jade

Within that file, add a some basic HTML5 code to get you started. However, we’re going to write everything in Jade from now on.

1. doctype html
2. html
3. head
4. title Hello, Jade!
5. meta(charset="utf-8")
6. body
7. h1 Hello, Jade!
8. p This is my first Jade project.

Let’s go over what we wrote:

  • Line 1: HTML5 simplified the doctype switch, and Jade simplifies it even more. Write this every time unless you have to deal with browsers from the early-to-mid-2000s (Jade has something for those too).
  • Line 2: If you’re used to Haml or (particularly) Slim, then you’ll feel right at home. Tags are written plainly — just type the name, all lowercase.
  • Line 3: Jade is indentation-dependent. Be sure to keep your template code nice and lined-up.
  • Line 5: You specify attributes by placing parentheses next to your tag, then writing the attributes just as you would in regular HTML.
  • Line 7 & 8: To write inline/text content, place a space after the starting tag and start writing.

Let’s compile, and see our result.

project$ jade -P .

The -P flag tells Jade to compile pretty HTML output. Otherwise, Jade will minify your HTML by default, which is good for later when compiling your code for a production environment or for distribution.

Here’s what we get:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>Hello, Jade!</title>
5. <meta charset="utf-8">
6. </head>
7. <body>
8. <h1>Hello, Jade!</h1>
9. <p>This is my first Jade project.</p>
10. </body>
11. </html>

Let’s discuss some of the differences:

  • Jade doesn’t require you to remember to close your tags — it automatically handles it for you. The HTML output is already 3 lines, or 27+%, longer.
  • Because Jade is so terse, it’s quicker to write the code you want to write with less details getting in the way.
  • The dependence on indentation makes it fast to quickly and visually parse where your code is hierarchically and avoids tag soup. If you want your code one level higher in the DOM tree, just outdent.

Let’s cover some more of the basics.

Actually…

Actually, let’s not cover more of the basics; they’re already nicely covered in the Jade docs! In fact, leave this article, spend an hour in the excellent Jade Language Reference, then come back. Get comfy with Jade, because we’re going to fast-forward quite a bit.

I’ll wait right here.

You back? Good! Let’s move on.

Let’s Mix it Up

In the docs, you may have run across mixins towards the end. Mixins are a lifesaver, and probably my favorite part of Jade. Think of mixins like a snippet of code that you can juse use over and over again. However, these mixins can change depending on how you set them up. Let’s look at some examples.

Let’s say I’m rendering a page that displays a list of links to news articles. Each of these news article links includes a title, excerpt, and a URL for the link.

//- index.jade
...
section.articles
article
h1
a(href="#") News Article Title
p This is a small excerpt that describes the article that we are writing about.
article
h1
a(href="#") News Article Title
p This is a small excerpt that describes the article that we are writing about.
article
h1
a(href="#") News Article Title
p This is a small excerpt that describes the article that we are writing about.
article
h1
a(href="#") News Article Title
p This is a small excerpt that describes the article that we are writing about.

Great! we have 4 articles listed, we can see what it looks like after we compile, and it looks a lot cleaner than plain old HTML. However, the code looks a little redundant. There’s got to be a way to DRY this up.

Let’s use a loop!

Nope. Well, let’s just see what that looks like.

//- index.jade
...
section.articles
- for (var i = 0; i < 4; i++)
article
h1
a(href="#") News Article Title
p This is a small excerpt that describes the article that we are writing about.

Not bad, but let’s try it with mixins.

//- _mixins.jade
mixin article
article
h1
a(href="#") News Article Title
p This is a small excerpt that describes the article that we are writing about.
//- index.jade
include _mixins
...
section.articles
+article
+article
+article
+article

By convention, files that usually don’t get compiled themselves to an HTML, such as _mixins.jade, start their filenames with an underscore. We don’t want Jade to have to deal with compiling these files, so when you call Jade, you can modify the call a bit to ignore all the files that have an underscore.

jade -P ./[^_]*.jade

In the scenario, we’ve set up a separate _mixins.jade file that will include all my mixin code. At the top of index.jade, we have to include the file to make sure index.jade knows about out mixins that we made. When it’s time to display the articles, it’s easy to just throw out +article whenever we need a new one.

This feature is powerful in that it abstracts all the code that you don’t have to worry about. All you should have to worry about in this instance is displaying articles. With mixins, you don’t have to worry about displaying the same old clunky-looking HTML code over and over again. It’s almost like a lite version of a web component. If you ever have to update the code for an article, you just update the mixin itself, and the code will update every instance where the mixin was used.

We can optimize this a little further… how about a loop?

Good idea, but… nope.

Let’s make it so we can change some of the data of each one.

//- _mixins.jade
mixin article(title, excerpt, url)
article
h1
a(href=url || "#")!= title || "News Article Title"
p!=excerpt || "This is a small excerpt that describes the article that we are writing about."
//- index.jade
...
section.articles
+article("Area Man Reads Book")
+article("Big Surf Swell Today", "The waves put on a display for tourists and locals alike.")
+article("Avengers 15", "Marvel sets record with an unprecedented $3.5 billion revenue take.", "http://marvel.com/printmoney")
+article

Now, we can customize each of the mixins with content and still abstract the architecture of a news article. We can even use these mixins within other pages on the site while keeping the HTML consistent everywhere.

Scratching the Surface

This definitely deserves a follow-up article. We still haven’t gone over layouts, blocks, or integration with gulp. In the meantime, read the documentation and use these mixin examples (and build on top of them!) to help you start to use Jade on your projects.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.