You are on page 1of 33

API Documentation

This page details how to render jade using the JavaScript API in node.js

Installation
via npm:
npm install jade

Usage
options
All API methods take the following set of options:
{
filename:
string
Used in exceptions, and required for relative includes and extends
doctype:
string
If the doctype is not specified as part of the template, you can specify it here. It is sometimes
useful to get self-closing tags and remove mirroring of boolean attributes.
pretty:
boolean | string
Adds whitespace to the resulting html to make it easier for a human to read using ' ' as
indentation. If a string is specified, that will be used as indentation instead (e.g. '\t').
self:
boolean
Use a self namespace to hold the locals (false by default)
debug:
boolean
If set to true, the tokens and function body is logged to stdout
compileDebug:
boolean
If set to true, the function source will be included in the compiled template for better error
messages (sometimes useful in development). It is enabled by default unless used with express in
production mode.
cache:
boolean
If set to true, compiled functions are cached. filename must be set as the cache key.
compiler:
class
Override the default compiler
parser:

class
Override the default parser
globals:
Array.<string>
Add a list of global names to make accessible in templates
}

jade.compile(source, options)
Compile some jade source to a function which can be rendered multiple times with different locals.
source
string
The source jade to compile
options
options
An options object (see above)
returns
function
A function to generate the html from an object containing locals
var jade = require('jade');
// Compile a function
var fn = jade.compile('string of jade', options);
// Render the function
var html = fn(locals);
// => '<string>of jade</string>'

jade.compileFile(path, options)
Compile some jade source from a file to a function which can be rendered multiple times with different
locals.
source
path
The path to a jade file
options
options
An options object (see above)
returns
function
A function to generate the html from an object containing locals
var jade = require('jade');
// Compile a function

var fn = jade.compileFile('path to jade file', options);


// Render the function
var html = fn(locals);
// => '<string>of jade</string>'

jade.compileClient(source, options)
Compile some jade source to a string of JavaScript that can be used client side along with the jade
runtime.
source
string
The source jade to compile
options
options
An options object (see above)
returns
string
A string of JavaScript representing a function
var jade = require('jade');
// Compile a function
var fn = jade.compileClient('string of jade', options);
// Render the function
var html = fn(locals);
// => 'function template(locals) { return "<string>of jade</string>"; }'

jade.compileClientWithDependenciesTracked(source, options)
See jade.compileClient except that this method returns an object of the form:
{
}

'body': 'function (locals) {...}',


'dependencies': ['filename.jade']

You should only use this method if you need to implement something like watching for changes to the
jade files.

jade.compileFileClient(path, options)
Compile a jade template file to a string of Javascript that can be used client side along with the jade
runtime.
path
string
The path to a jade file
options

options
An options object (see above)
options.name
string
If you pass a .name property on the options object, it will be used as the function name for your
client side template function.
returns
string
A Javascript function body.
First, our template file.
h1 This is a Jade template
h2 By #{author}

Then, we compile the jade file into a function string.


var fs
= require('fs');
var jade = require('jade');
// Compile the template to a function string
var jsFunctionString = jade.compileFileClient('/path/to/jadeFile.jade', {name:
"fancyTemplateFun"});
// Maybe you want to compile all of your templates to a templates.js file and serve
it to the client
fs.writeFileSync("templates.js", jsFunctionString);

Here's what the output function string looks like (written to templates.js).
function fancyTemplateFun(locals) {
var buf = [];
var jade_mixins = {};
var jade_interp;
var locals_for_with = (locals || {});
(function (author) {
buf.push("<h1>This is a Jade template</h1><h2>By "
+ (jade.escape((jade_interp = author) == null ? '' : jade_interp))
+ "</h2>");
}.call(this, "author" in locals_for_with ?
locals_for_with.author : typeof author !== "undefined" ?
author : undefined)
);
return buf.join("");
}

Be sure to send the Jade runtime (node_modules/jade/runtime.js) to the client in addition to


the template that you just compiled.
<!DOCTYPE html>

<html>
<head>
<script src="/runtime.js"></script>
<script src="/templates.js"></script>
</head>
<body>
<h1>This is one fancy template.</h1>
<script type="text/javascript">
var html = window.fancyTemplateFun({author: "enlore"});
var div = document.createElement("div");
div.innerHTML = html;
document.body.appendChild(div);
</script>
</body>
</html>

jade.render(source, options)
source
string
The source jade to render
options
options
An options object (see above), also used as the locals object
returns
string
The resulting html string
var jade = require('jade');
var html = jade.render('string of jade', options);
// => '<string>of jade</string>'

jade.renderFile(filename, options)
filename
string
The path to the jade file to render
options
options
An options object (see above), also used as the locals object
returns
string
The resulting html string
var jade = require('jade');
var html = jade.renderFile('path/to/file.jade', options);
// ...

Command Line
Installation
via npm:
$ npm install jade --global

Usage
$ jade [options] [dir|file ...]

Options
-h, --help
-V, --version
-O, --obj <path|str>
-o, --out <dir>
-p, --path <path>
-P, --pretty
-c, --client
-n, --name <str>
-D, --no-debug
-w, --watch
-E, --extension <ext>
--name-after-file
--doctype <str>

output usage information


output the version number
JavaScript options object or JSON file containing it
output the compiled html to <dir>
filename used to resolve includes
compile pretty html output
compile function for client-side runtime.js
the name of the compiled template (requires --client)
compile without debugging (smaller functions)
watch files for changes and automatically re-render
specify the output file extension
name the template after the last section of the file path
(requires --client and overriden by --name)
specify the doctype on the command line (useful if it
is not specified by the template)

Examples
Translate jade the templates dir:
$ jade templates

Create {foo,bar}.html
$ jade {foo,bar}.jade

Jade over stdio


$ jade < my.jade > my.html

Jade over stdio


$ echo "h1 Jade!" | jade

foo, bar dirs rendering to /tmp


$ jade foo bar --out /tmp

Language Reference
API
Command Line

Change Log
Code Coverage
Test Results
GitHub Repository

attributes
case
code
comments
conditionals
doctype
extends
filters
includes
inheritance
interpolation
iteration
mixins

plain text
tags

Language Reference
Jade is a terse language for writing HTML templates.
Produces HTML
Supports dynamic code
Supports reusability (DRY)
To read about the features of the language, select them from the navigation menu on the left.
Jade is a template language maintained by @ForbesLindesay and contributed by many others.

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 href="google.com" class="button">Google</a>

All the normal JavaScript expressions work fine too:


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

If you have many attributes, you can also spread them across many lines:
input(
type='checkbox'
name='agreement'
checked
)
<input type="checkbox" name="agreement" checked="checked"/>

Unescaped Attributes
By default, all attributes are escaped (replacing special characters with escape sequences) to prevent
attacks such as cross site scripting. If you need to use special characters you can use != instead of =.
div(escaped="<code>")
div(unescaped!="<code>")
<div escaped="&lt;code&gt;"></div>
<div unescaped="<code>"></div>

Danger
Unescaped buffered code can be dangerous. You must be sure to sanitize any user inputs to avoid crosssite scripting.

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">

Style Attributes
The style attribute can be a string (like any normal attribute) but it can also be an object, which is
handy when parts of the style are generated by JavaScript.
a(style={color: 'red', background: 'green'})
<a style="color:red;background:green"></a>

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="bing foo bar baz bing"></a>

It can also be an object mapping class names to true or false values, which is useful for applying
conditional classes
- var currentUrl = '/about'
a(class={active: currentUrl === '/'} href='/') Home
a(class={active: currentUrl === '/about'} href='/about') About
<a href="/">Home</a><a href="/about" class="active">About</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>

&attributes
Pronounced "and attributes", the &attributes syntax can be used to explode an object into
attributes of an element.
div#foo(data-bar="foo")&attributes({'data-foo': 'bar'})
<div id="foo" data-bar="foo" data-foo="bar"></div>

The object does not have to be an object literal. It can also just be a variable that has an object as its
value (see also Mixin Attributes)
- var attributes = {'data-foo': 'bar'};
div#foo(data-bar="foo")&attributes(attributes)
<div id="foo" data-bar="foo" data-foo="bar"></div>

Danger
Attributes applied using &attributes are not automatically escaped. You must be sure to sanitize
any user inputs to avoid cross-site scripting. This is done for you if you are passing in attributes
from a mixin call.

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 friends
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>

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>

Jade also supports block unbuffered code:


list = ["Uno", "Dos", "Tres",
"Cuatro", "Cinco", "Seis"]
each item in list
li= item
<li>Uno</li>
<li>Dos</li>
<li>Tres</li>
<li>Cuatro</li>
<li>Cinco</li>
<li>Seis</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>

Danger
Unescaped buffered code can be dangerous. You must be sure to sanitize any user inputs to avoid crosssite scripting.

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>

Conditional Comments
Jade does not have any special syntax for conditional comments. If your line begins with < then it is
treated as plain text. So just use normal HTML style conditional comments:
<!--[if IE 8]>
<html lang="en" class="lt-ie9">
<![endif]-->
<!--[if gt IE 8]><!-->
<html lang="en">

<!--<![endif]-->
<!--[if IE 8]>
<html lang="en" class="lt-ie9">
<![endif]-->
<!--[if gt IE 8]><!-->
<html lang="en">
<!--<![endif]-->

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' }
- var authorised = false
#user
if user.description
h2 Description
p.description= user.description
else if authorised
h2 Description
p.description.
User has no description,
why not add one...
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}

Doctype
doctype html
<!DOCTYPE html>

Doctype Shortcuts
There are shortcuts for commonly used doctypes:
doctype html
<!DOCTYPE html>

doctype xml
<?xml version="1.0" encoding="utf-8" ?>

doctype transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

doctype strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

doctype frameset
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

doctype 1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

doctype basic

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


"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">

doctype mobile
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN"
"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">

Custom Doctypes
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">

Doctype Option
The doctype affects compilation in some other cases, for example self closing tags and boolean
attributes). For this reason, you might sometimes want to specify it manually. You can do this via the
doctype option. e.g.
var jade = require('./');
// Compile a function
var fn = jade.compile('img(src="foo.png")', {doctype: 'xml'});
// Render the function
var html = fn({});
// => '<img src="foo.png"></img>'
// Compile a function
var fn = jade.compile('img(src="foo.png")', {doctype: 'html'});
// Render the function
var html = fn({});
// => '<img src="foo.png">'

Extends - Template Inheritance


The extends keyword allows a template to extend a layout or parent template. It can then override
certain pre-defined blocks of content.
//- layout.jade
doctype html
html
head
block title
title Default title
body
block content

//- index.jade
extends ./layout.jade
block title
title Article Title
block content
h1 My Article
<!doctype html>
<html>
<head>
<title>Article Title</title>
</head>
<body>
<h1>My Article</h1>
</body>
</html>

Note
You can have multiple levels of inheritance, allowing you to create powerful hierarchies of templates.

Filters
Filters let you use other languages within a jade template. They take a block of plain text as an input.
All JSTransformers can be used as jade filters. Popular filters include :coffee-script, :babel,
:uglify-js, :less, and :markdown-it.
:markdown
# Markdown
I often like including markdown documents.
script
:coffee-script
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>

Warning
Filters are compile time. This makes them fast but means they cannot support dynamic content.
Built in filters are not available in the browser as they would not all work. Providing you compile your
templates server side, they will still work fine though.

Includes
Includes allow you to insert the contents of one jade file into another.
//- index.jade
doctype html

html
include ./includes/head.jade
body
h1 My Site
p Welcome to my super lame site.
include ./includes/foot.jade
//- 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>

Including Plain Text


Including files that are not jade just includes the raw text.
//- index.jade
doctype html
html
head
style
include style.css
body
h1 My Site
p Welcome to my super lame site.
script
include script.js
/* style.css */
h1 { color: red; }
// script.js
console.log('You are awesome');
<!doctype html>

<html>
<head>
<style>
/* style.css */
h1 { color: red; }
</style>
</head>
<body>
<h1>My Site</h1>
<p>Welcome to my super lame site.</p>
<script>
// script.js
console.log('You are awesome');
</script>
</body>
</html>

Including Filtered Text


You can combine filters with includes to filter things as you include them.
//- index.jade
doctype html
html
head
title An Article
body
include:markdown article.md

# article.md
This is an article written in markdown.

<!doctype html>
<html>
<head>
<title>An Article</title>
</head>
<body>
<h1>article.md</h1>
<p>This is an article written in markdown.</p>
</body>
</html>

Template inheritance
Jade supports template inheritance via the block and extends keywords. A block is simply a
"block" of Jade that may be replaced within a child template. This process is recursive.
Jade blocks can provide default content if desired, however optional as shown below by block
scripts, block content, and block foot.

layout.jade
html
head
title My Site - #{title}
block scripts
script(src='/jquery.js')
body
block content
block foot
#footer
p some footer content

Now to extend the layout, simply create a new file and use the extends directive as shown below,
giving the path (with or without the .jade extension). You may now define one or more blocks that will
override the parent block content, note that here the foot block is not redefined and will output "some
footer content".
page-a.jade
extends ./layout.jade
block scripts
script(src='/jquery.js')
script(src='/pets.js')
block content
h1= title
each pet in pets
include pet

It's also possible to override a block to provide additional blocks, as shown in the following example
where content now exposes a sidebar and primary block for overriding, or the child template
could override content all together.
sub-layout.jade
extends ./layout.jade
block content
.sidebar
block sidebar
p nothing
.primary
block primary
p nothing

page-b.jade
extends ./sub-layout.jade
block content
.sidebar
block sidebar
p nothing

.primary
block primary
p nothing

Block append / prepend


Jade allows you to replace (default), prepend, or append blocks. Suppose for example you have default
scripts in a "head" block that you wish to utilize on every page, you might do this:
html
head
block head
script(src='/vendor/jquery.js')
script(src='/vendor/caustic.js')
body
block content

Now suppose you have a page of your application for a JavaScript game, you want some game related
scripts as well as these defaults, you can simply append the block:
extends layout
block append head
script(src='/vendor/three.js')
script(src='/game.js')

When using block append or block prepend the block is optional:


extends layout
append head
script(src='/vendor/three.js')
script(src='/game.js')

Interpolation
Jade provides operators for a variety of your different interpolative needs.

String Interpolation, Escaped


Consider the placement of the template locals title, author, and theGreat in the following
template.
- var title = "On Dogs: Man's Best Friend";
- var author = "enlore";
- var theGreat = "<span>escape!</span>";

h1= title
p Written with love by #{author}
p This will be safe: #{theGreat}

<h1>On Dogs: Man's Best Friend</h1>


<p>Written with love by enlore</p>
<p>This will be safe: &lt;span&gt;escape!&lt;/span&gt;</p>

title follows the basic pattern for evaluating a template local, but the code in between #{ and } is
evaluated, escaped, and the result buffered into the output of the template being rendered.
This can be any valid Javascript expression, so you can do whatever feels good.
- var msg = "not my inside voice";
p This is #{msg.toUpperCase()}

<p>This is NOT MY INSIDE VOICE</p>

String Interpolation, Unescaped


You don't have to play it safe. You can buffer unescaped values into your templates, too.
- var riskyBusiness = "<em>Some of the girls are wearing my mother's
clothing.</em>";
.quote
p Joel: !{riskyBusiness}

<div class="quote">
<p>Joel: <em>Some of the girls are wearing my mother's clothing.</em></p>
</div>

Danger
Keep in mind that buffering unescaped content into your templates can be mighty risky if that content
comes fresh from your users. Never trust user input!

Tag Interpolation
If you take a look at this page's source on GitHub, you'll see several places where the tag interpolation
operator is used, like so.
p.
If you take a look at this page's source #[a(target="_blank",
href="https://github.com/jadejs/jade/blob/master/docs/views/reference/interpolation
.jade") on GitHub],
you'll see several places where the tag interpolation operator is
used, like so.

<p>If you take a look at this page's source <a target="_blank"


href="https://github.com/jadejs/jade/blob/master/docs/views/reference/interpolation
.jade">on GitHub</a>,
you'll see several places where the tag interpolation operator is
used, like so.
</p>

You could accomplish the same thing by writing an HTML tag inline with your Jade, but then what's
the point of writing the Jade? Wrap an inline Jade tag declaration in #[ and ] and it'll be evaluated and
buffered into the content of its containing tag.

Iteration
Jade supports two primary methods of iteration, each and while.

each
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 or almost anything else. e.g.
- var values = [];
ul

each val in values.length ? values : ['There are no values']


li= val
<ul>
<li>There are no values</li>
</ul>

You can also use for as an alias of each.

while
You can also use while to create a loop:
- var n = 0
ul
while n < 4
li= n++
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>

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 pet(name)
li.pet= name
ul
+pet('cat')
+pet('dog')
+pet('pig')
<ul>
<li class="pet">cat</li>
<li class="pet">dog</li>
<li class="pet">pig</li>
</ul>

Mixin Blocks
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>

Mixin Attributes
Mixins also get an implicit attributes argument taken from the attributes passed to the mixin:
mixin link(href, name)
//- attributes == {class: "btn"}
a(class!=attributes.class, href=href)= name

+link('/foo', 'foo')(class="btn")
<a href="/foo" class="btn">foo</a>

Note
The values in attributes are already escaped so you should use != to avoid escaping them a
second time (see also unescaped attributes).
You can also use with &attributes (see also &attributes)
mixin link(href, name)
a(href=href)&attributes(attributes)= name

+link('/foo', 'foo')(class="btn")
<a href="/foo" class="btn">foo</a>

Rest Arguments
You can write mixins that take an unknown number of arguments using the "rest arguments" syntax.
e.g.
mixin list(id, ...items)
ul(id=id)
each item in items
li= item

+list('my-list', 1, 2, 3, 4)
<ul id="my-list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>

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>

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>

Self Closing Tags


Tags such as img, meta, link and so on are automatically self-closing (unless you use the xml
doctype). You can also explicitly self close a tag by simply appending the / character. Only do this if
you know what you're doing
foo/
foo(bar='baz')/
<foo/>
<foo bar="baz"/>

You might also like