Fork me on GitHub

Language Reference

On this page:

doctype

To add a doctype use doctype followed by an optional value (which defaults to html). The shorthand !!! has been deprecated.

doctype html
<!DOCTYPE html>

There are shortcuts for commonly used doctypes:

xml
<?xml version="1.0" encoding="utf-8" ?>
transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
frameset
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
basic
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
mobile
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">

You can also use your own literal custom doctype:

doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN">

Tags

By default, text at the start of a line (or after only white space) represents an html tag. Indented tags are nested, creating the tree like structure of html.

ul
  li Item A
  li Item B
  li Item C
<ul>
  <li>Item A</li>
  <li>Item B</li>
  <li>Item C</li>
</ul>

Jade also knows which elements are self closing:

img
<img/>

Block Expansion

To save space, jade provides an inline syntax for nested tags.

a: img
<a><img/></a>

Attributes

Tag attributes look similar to html, however their values are just regular JavaScript.

a(href='google.com') Google
a(class='button', href='google.com') Google
<a href="google.com">Google</a>
<a class="button" href="google.com">Google</a>

All the normal JavaScript expressions work fine too:

- var authenticated = true
body(class=authenticated?'authed':'anon')
<body class="authed"></body>

Boolean Attributes

Boolean attributes are mirrored by Jade, and accept bools, aka true or false. When no value is specified true is assumed.

input(type='checkbox', checked)
input(type='checkbox', checked=true)
input(type='checkbox', checked=false)
input(type='checkbox', checked=true.toString())
<input type="checkbox" checked="checked" />
<input type="checkbox" checked="checked" />
<input type="checkbox" />
<input type="checkbox" checked="true" />

If the doctype is html jade knows not to mirror the attribute and uses the terse style (understood by all browsers).

doctype html
input(type='checkbox', checked)
input(type='checkbox', checked=true)
input(type='checkbox', checked=false)
input(type='checkbox', checked=true && 'checked')
<!DOCTYPE html>
<input type="checkbox" checked>
<input type="checkbox" checked>
<input type="checkbox">
<input type="checkbox" checked="checked">

Class Attributes

The class attribute can be a string (like any normal attribute) but it can also be an array of class names, which is handy when generated from JavaScript.

- var classes = ['foo', 'bar', 'baz']
a(class=classes)
//- the class attribute may also be repeated to merge arrays
a.bing(class=classes class=['bing'])
<a class="foo bar baz"></a>
<a class="foo bar baz bing"></a>

Class Literal

Classes may be defined using a .classname syntax:

a.button
<a class="button"></a>

Since div's are such a common choice of tag, it is the default if you omit the tag name:

.content
<div class="content"></div>

ID Literal

IDs may be defined using a #idname syntax:

a#main-link
<a id="main-link"></a>

Since div's are such a common choice of tag, it is the default if you omit the tag name:

#content
<div id="content"></div>

Plain Text

Jade provides three common ways of getting plain text. They are useful in different situations

Piped Text

The simplest way of adding plain text to templates is to prefix the line with a | character (pronounced "pipe").

| Plain text can include <strong>html</strong>
p
  | It must always be on its own line
Plain text can include <strong>html</strong>
<p>It must always be on its own line</p>

Inline in a Tag

Since it's a common use case, you can put text in a tag just by adding it inline after a space.

p Plain text can include <strong>html</strong>
<p>Plain text can include <strong>html</strong></p>

Block in a Tag

Often you might want large blocks of text within a tag. A good example is with inline scripts or styles. To do this, just add a . after the tag (with no preceding space):

script.
  if (usingJade)
    console.log('you are awesome')
  else
    console.log('use jade')
<script>
  if (usingJade)
    console.log('you are awesome')
  else
    console.log('use jade')
</script>

Code

Jade makes it possible to write inline JavaScript code in your templates. There are three types of code.

Unbuffered Code

Unbuffered code starts with - does not add any output directly, e.g.

- for (var x = 0; x < 3; x++)
  li item
<li>item</li>
<li>item</li>
<li>item</li>

Buffered Code

Buffered code starts with = and outputs the result of evaluating the JavaScript expression in the template. For security, it is first HTML escaped:

p
  = 'This code is <escaped>!'
<p>This code is &lt;escaped&gt;!</p>

It can also be written inline with attributes, and supports the full range of JavaScript expressions:

p= 'This code is' + ' <escaped>!'
<p>This code is &lt;escaped&gt;!</p>

Unescaped Buffered Code

Unescaped buffered code starts with != and outputs the result of evaluating the JavaScript expression in the template. This does not do any escaping, so is not safe for user input:

p
  != 'This code is <strong>not</strong> escaped!'
<p>This code is <strong>not</strong> escaped!</p>

It can also be written inline with attributes, and supports the full range of JavaScript expressions:

p!= 'This code is <strong>not</strong> escaped!'
<p>This code is <strong>not</strong> escaped!</p>

Comments

Single line comments look the same as JavaScript comments and must be placed on their own line:

// just some paragraphs
p foo
p bar
<!-- just some paragraphs -->
<p>foo</p>
<p>bar</p>

Jade also supports unbuffered comments, by simply adding a hyphen

//- will not output within markup
p foo
p bar
<p>foo</p>
<p>bar</p>

Block Comments

A block comment is legal as well:

body
  //
    As much text as you want
    can go here.
<body>
  <!--
  As much text as you want
  can go here.
  -->
</body>

Conditionals

Jade's first-class conditional syntax allows for optional parenthesis, and you may now omit the leading - otherwise it's identical, still just regular javascript:

- var user = { description: 'foo bar baz' }
#user
  if user.description
    h2 Description
    p.description= user.description
  else
    h1 Description
    p.description User has no description
<div id="user">
  <h2>Description</h2>
  <p class="description">foo bar baz</p>
</div>

Jade also provides a negated version unless (the following are therefore equivalent):

unless user.isAnonymous
  p You're logged in as #{user.name}
if !user.isAnonymous
  p You're logged in as #{user.name}

Iteration

Jade's first-class iteration syntax makes it easier to iterate over arrays and objects within a template:

ul
  each val in [1, 2, 3, 4, 5]
    li= val
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

You can also get the index as you iterate:

ul
  each val, index in ['zero', 'one', 'two']
    li= index + ': ' + val
<ul>
  <li>0: zero</li>
  <li>1: one</li>
  <li>2: two</li>
</ul>

Jade also lets you iterate over the keys in an object:

ul
  each val, index in {1:'one',2:'two',3:'three'}
    li= index + ': ' + val
<ul>
  <li>1: one</li>
  <li>2: two</li>
  <li>3: three</li>
</ul>

The object or array to iterate over is just plain JavaScript so it can be a variable or the result of a function call as well.

Case

The case statement is a shorthand for JavaScript's switch statement and takes the following form:

- var friends = 10
case friends
  when 0
    p you have no friends
  when 1
    p you have a friend
  default
    p you have #{friends} friends
<p>you have 10 friends</p>

Case Fall Through

You can use fall through just like in a select statement in JavaScript

- var friends = 0
case friends
  when 0
  when 1
    p you have very few
  default
    p you have #{friends} friends
<p>you have very few friends</p>

Block Expansion

Block expansion may also be used:

- var friends = 1
case friends
  when 0: p you have no friends
  when 1: p you have a friend
  default: p you have #{friends} friends
<p>you have a friend</p>

Filters

Filters let you use other languages within a jade template. They take a block of plain text as an input.

:markdown
  # Markdown
  
  I often like including markdown documents.
script
  :coffee
    console.log 'This is coffee script'
<h1>Markdown</h1>
<p>I often like including markdown documents.</p>
<script>console.log('This is coffee script')</script>

Mixins

Mixins allow you to create reusable blocks of jade.

//- Declaration
mixin list
  ul
    li foo
    li bar
    li baz
//- Use
+list()
+list()
<ul>
  <li>foo</li>
  <li>bar</li>
  <li>baz</li>
</ul>
<ul>
  <li>foo</li>
  <li>bar</li>
  <li>baz</li>
</ul>

They are compiled to functions and can take arguments:

mixin pets(pets)
  ul.pets
    - each pet in pets
      li= pet
+pets(['cat', 'dog', 'pig'])
<ul class="pets">
  <li>cat</li>
  <li>dog</li>
  <li>pig</li>
</ul>

Mixins can also take a block of jade to act as the content:

mixin article(title)
  .article
    .article-wrapper
      h1= title
      if block
        block
      else
        p No content provided
        
+article('Hello world')

+article('Hello world')
  p This is my
  p Amazing article
<div class="article">
  <div class="article-wrapper">
    <h1>Hello world</h1>
    <p>No content provided</p>
  </div>
</div>

<div class="article">
  <div class="article-wrapper">
    <h1>Hello world</h1>
    <p>This is my</p>
    <p>Amazing article</p>
  </div>
</div>

Mixins also get an implicit attributes argument taken from the attributes passed to the mixin:

mixin link(href, name)
  a(class!=attributes.class, href=href)= name
  
+link('/foo', 'foo')(class="btn")
<a class="btn" href="/foo">foo</a>

Includes

Includes allow you to insert the contents of one jade file into another.

// index.jade
doctype html
html
  include includes/head
body
  h1 My Site
  p Welcome to my super lame site.
  include includes/foot
// includes/head.jade
head
  title My Site
  script(src='/javascripts/jquery.js')
  script(src='/javascripts/app.js')
  
// includes/foot.jade
#footer
  p Copyright (c) foobar
<!doctype html>
<html>
  <head>
    <title>My Site</title>
    <script src='/javascripts/jquery.js'></script>
    <script src='/javascripts/app.js'></script>
  </head>
  <body>
    <h1>My Site</h1>
    <p>Welcome to my super lame site.</p>
    <div id="footer">
      <p>Copyright (c) foobar</p>
    </div>
  </body>
</html>