# Jade is default Template Engine for Express ( Node.js web framework)
# Jade is a high performance template engine heavily influenced by Haml (http://haml-lang.com)
and implemented with JavaScript for [ Node ].
# You can imagine a Jade Template as a View for your Node.JS application, for example,
You can put all of your JavaScript Code/Logic inside a index.js file,
This file can export
JavaScript Objects, Variable, and other data
type,
and Your Jade Template can use those things to setup/generate
a static HTML web page, using optional
export data from node.js
app (In this case, index.js)
# If you are familiar with Python/Haskell/Coffee-script etc,, they use Indentation for nesting of expressions,
same as for Jade, Here we use 2 white-space as indentation for Jade expressions to nest them into one another.
# How to Install?
# Using node package manager ( npm )
npm install jade -g
# Jade API ( using jade inside Node project )
# import jade using require() function
# All API options that can
be used while compiling or rendering Jade Template
{
filename: 'string',
doctype: 'string',
pretty: 'boolean|string',
self:
'boolean',
debug: 'boolean',
compileDebug:
'boolean',
compiler: 'class',
globals: Array<string>
}
var jade = require('jade')
> require('jade')
{ selfClosing:
[ 'area',
'base',
'br',
'col',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'menuitem',
'meta',
'param',
'source',
'track',
'wbr' ],
doctypes:
{ default: '<!DOCTYPE html>',
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">' },
filters: [Function: filter],
utils:
{ merge: [Function],
walkAST: [Function: walkAST] },
Compiler: [Function: Compiler],
Parser: [Function: Parser],
Lexer: [Function: Lexer],
nodes:
{ Node: [Function: Node],
Tag: [Function: Tag],
Code: [Function: Code],
Each: [Function: Each],
Case: { [Function: Case] When: [Function: When] },
Text: [Function: Text],
Block: [Function: Block],
MixinBlock: [Function: MixinBlock],
Mixin: [Function: Mixin],
Filter: [Function: Filter],
Comment: [Function: Comment],
Literal: [Function: Literal],
BlockComment: [Function: BlockComment],
Doctype: [Function: Doctype] },
runtime:
{ merge: [Function: merge],
joinClasses: [Function: joinClasses],
cls: [Function: cls],
attr: [Function: attr],
attrs: [Function: attrs],
escape: [Function: escape],
rethrow: [Function: rethrow] },
cache: {},
compile: [Function],
compileClient: [Function],
compileFile: [Function],
render: [Function],
renderFile: [Function],
compileFileClient: [Function],
__express: [Function] }
# compile
var fn = jade.compile('string of jade', options);
var html = fn(locals);
ssp@ssp-pc ~ $ node
> var jade = require('jade')
> var fn = jade.compile('doctype html')
> var html = fn()
> html
'<!DOCTYPE html>'
# render
var html = jade.render('string of jade', merge(options, locals));
> var html = jade.render('doctype html\nhtml(lang="eng")')
> html
'<!DOCTYPE html><html lang="eng"></html>'
# render jade file
var html = jade.renderFile('filename.jade', merge(options, locals));
# demo.jade
doctype html
html
head
title #{title}
body
h1 This is #{title}
p This is very simple paragraph
# jade template rendering
> var html = jade.renderFile('demo.jade', ('pretty', {title: 'Simple Node jade template'}))
> console.log(html)
<!DOCTYPE html>
<html>
<head>
<title>Simple Node jade template</title>
</head>
<body>
<h1>This is Simple Node jade template</h1>
<p>This is very simple paragraph</p>
</body>
</html>
# Using jade from Command line
# jade Synopsis
Usage: jade [options] [dir|file ...]
Options:
-h, --help output usage information
-V, --version output the version number
-O, --obj <str> javascript options object
-o, --out <dir> output the compiled html to <dir>
-p, --path <path> filename used to resolve includes
-P, --pretty compile pretty html output
-c, --client compile function for client-side runtime.js
-n, --name <str> The name of the compiled template (requires --client)
-D, --no-debug compile without debugging (smaller functions)
-w, --watch watch files for changes and automatically
re-render
--name-after-file Name the template after the last section of the file path
(requires --client and overriden by --name)
--doctype <str> 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
# compile Jade template using command line
jade --client --no-debug filename.jade
which will produce filename.js containing the compiled template.
ssp@ssp-pc ~ $ /usr/local/bin/jade --pretty demo.jade
rendered demo.html
ssp@ssp-pc ~ $ cat demo.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>This is </h1>
<p>This is very simple paragraph</p>
</body>
</html>ssp@ssp-/usr/local/bin/jade demo.jade
rendered demo.html
ssp@ssp-pc ~ $ cat demo.html
<!DOCTYPE html><html><head><title></title></head><body><h1>This
is </h1><p>This is very simple paragraph</p></body></html>ssp@ssp-pc ~
$
# Document type declaration inside Jade document
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">
=> Using doctype as an Option while compiling and rendering, and see its effect.
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('jade'); // importing Jade module as jade variable
// Compile a function, with doctype as XML
var fn = jade.compile('img(src="foo.png")', {doctype:
'xml'});
// Render the function
var html = fn({});
'<img src="foo.png"></img>'
//
Compile a function, with doctype as HTML
var fn = jade.compile('img(src="foo.png")', {doctype: 'html'});
// Render the
function
var html = fn({});
'<img src="foo.png">'
# Writing comments for either Jade Template or for
generated HTML document
=> 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 un-buffered comments, by simply adding a hypen
- // This is a JavaScript expression comment
//- Simple java-script
=> Block
Comments ( means a multi-line comment for HTML document)
body
//
As much text as you
want
can go here
<body>
<!--
As mush 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="it-ie9">
<![endif]-->
# Writing Plain text for Jade, that will not be processed by Jade Compiler
=> Jade provides three common ways of getting plain text,
=> Piped
Text, prefix the line with | character.
body
| Plain text can include <strong>HTML</strong>
br
| because This piped text will be passed as it was.
p
| It must always be on its own line
<body>Plain text can include <strong>HTML</strong><br/>because This piped text will be passed as it was.
<p>It must always be on its own line</p>
</body>
=> 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, useful for writing JavaScript and CSS rules inside Jade Template.
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(src="java.js").
if (usingJade())
console.log("you are awesome")
else
console.log("use Jade")
<script src="java.js">
if (usingJade())
console.log("you are awesome")
else
console.log("use Jade")
</script>
# Using HTML tags inside Jade document
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 with the help of DOCTYPE declaration.
img
<img
/>
=> Block expansion, ( for
nesting of HTML elements we generally use Indentation, but their is one
more syntax, you can use
: to nest one or more HTML elements. ). To save space, jade provides an inline syntax for nested
tags.
a: img
<a><img /></a>
=> Self Closing Tags, ( define your own self-closing tag)
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 a[[ending the / character.
Only do this if you
know what you are doing.
foo/
foo(bar='baz')/
<foo/>
<foo
bar='baz'/>
#
Using Attributes with HTML elements
=> Tag attributes look similar to HTML, however
their values are just regular JavaScript, means you need a key and put its values inside a
parenthesis, and If you have multiple attributes than separate them using comma.
a(href='google.com')
Google
<a href="google.com">Google</a>
=> All the JavaScript
expressions work fine too, You are allowed to write
any custom JavaScript code, and that might help you generate
custom html.
use a -
before the JavaScript expression, so that Jade Compiler treats that line as a JavaScript Expression.
-
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, and there is no need to use comma
to separate them.
input(
type="checkbox"
name="agreement"
checked
)
=> Unescaped Attributes, ( So, you define a value
for attribute and then you want to use that value as it is,
tell the Jade Compiler do not worry about this
value.)
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 escaped="<code>"></div>
div(unescaped!="<code>")
<div
unescaped="<code>"></div>
// Danger, You must be sure to sanitize any user inputs to avoid
Cross Site Scripting
=> Boolean Attributes
Boolean attributes are mirrored by
jade, and accept bools, like, true or false as in JavaScript.
When no value is specified, true is
assumed.
input(type='checkbox', checked)
<input type="checkbox" checked="checked">
input(type='checkbox',
checked=true)
<input type="checkbox" checked="checked">
input(type='checkbox',
checked=false)
<input type="checkbox">
input(type='checkbox', checked=true.toString())
<input
type="checkbox" checked="true">
doctype html
<!DOCTYPE html>
input(type='checkbox',
checked)
<input type="checkbox" checked>
input(type='checkbox', checked=true)
<input
type="checkbox" checked>
input(type='checkbox', checked=false)
<input
type="checkbox">
input(type='checkbox', checked=true && 'checked')
<input
type="checkbox" checked="checked">
=> Style Attributes
The style attribute
can be a string, but it can be an object, which is handy when parts of the style are generated by
JavaScript.
a(style="color:red;background:greenl") This is that simple text
<a style="color: red;
background: green;">This is that simple text</a>
=> Class Attributes
The
class attributes can ba a string, but it can be an array of class names, which is handy when generated
from Java-script.
- var classes = ['foo', 'bar', 'baz'];
a(class=classes)
<a class="foo bar baz"></a>
a(class=classes
class=['bing'])
<a class="bing foo bar biz"></a>
=> Class Literal, (
easy and Simple way to define classes for any HTML
element), If no HTML element is used with .class than a DIV
is assumed.
a.button
<a class="button"></a>
.content
<div class="content"></div>
=> ID Literal, (simple and easy way to define ID
for HTML elements), If no HTML element is used with #ID than
DIV is assumed.
a#main-link
<a id="main-link"></a.
#content
<div id="content"></div>
=> &attributes (and attributes) can be used to explode an object into attributes of an element
div#foo(data-bar="foo")&attributes({'data-foo':
'bar'}) Lets talk with me
<div id="foo" data-bar="foo" data-foo="bar">Lets talk with me</div>
Danger:
Attributes applied using &attributes are not automatically escaped, You must be sure to sanatize any
user inputs to avoid
Cross Site Scripting. This is done for you if you passing in attributes from a mixin
call.
# Case ( Generate HTML based on different cases defined by JavaScript equivalent code)
- var friends = 10; // This is JavaScript variable
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</a>
=> 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</a>
# Code and
Text Interpolation
Jade makes it possible to write inline JavaScript code in your templates,
There are three types of code,
=> Unbuffered Code
Unbuffered code starts with a -
does not add any output directly:
- 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 output 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 <escaped>!</p>
p
'This is very Simple'
p
This is very Simple
-var user = { description: 'foo bar baz'}
-var authorized = false
#user
if user.description
h2 Description
p.description user.description
p.description= user.description
<div id="user">
<h2>Description</h2>
<p class="description">user.description</p>
<p class="description">foo bar baz</p>
</div>
=>
Unescaped Buffered Code
Unescaped buffered code starts with != and output the result of
evaluating the JavaScript expression in the template.
It is not safe for user input:
p
!= 'This code is <strong>not<strong> !escaped'
<p>This code is <strong>not<strong>
escaped!</p>
=> Interpolation
Both plain-text and piped-text support
interpolation.
- var user = {name: 'Hello world!'}
p Welcome #{user.name}
<p>Welcome
Hello world!</p>
=> Unescaped Interpolation
You can also use unescaped interpolation
in output HTML:
-var user = {name: '<strong>Hello world!<strong>'}
p Welcome
#{user.name}
p Welcome !{user.name}
<p>Welcome <strong>Hello world!</strong></p>
<p>Welcome
<strong>Hello world!</strong></p>
# Conditionals, ( generate HTML code based on if-else statements )
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}
# Iteration over JavaScript objects using each and while statements
=>
each
jade's first-class iteration syntax makes it easier to iterate over arrays and objects within a
template:
ul
// Don't use white-space before = sign
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
=> 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:
-
var values = []
ul
each val in values.length ? values: ['There are no values']
li= val
<ul>
<li>There are no values</li>
</ul>
=>
while
You can also use while to create a loop
- var n = 0
ul
while n <
4
li = n++
# Extends - Template
Inheritance ( Using extends and block keyword )
The extends keyword allows a template to extend a layout or parent
template.
It can then override certain pre-defined blocks of content.
//-FILE: layout.jade
doctype html
html
head
//- So this is a block named title,
//- you can extend this into another template.
block title
body
//- This block name is content
block content
//- FILE: index.jade
extends layout.jade
//- Time to use our pre-defined blocks
block title
title Simple Node Application
block content
h1 Welcome to my first Node Application
//- FILE: index.html
<!DOCTYPE html>
<html>
<head>
<title>Simple Node Application</title>
</head>
<body>
<h1>Welcome to my first Node Application</h1>
</body>
</html>
# Filters
Filters let you use other languages (like, HTML, XML,,,)
within a jade template. They take a block of plain text as an input.
//- FILE: index.jade
:markdown
# Markdown
I Often like including markdown documents
script(type="text/coffeescript")
:coffee
console.log 'This is coffee script'
//- FILE: index.html
<h1 id="markdown">Markdown</h1>
<p>I Often like including markdown documents</p>
<script type="text/coffeescript">(function() {
console.log('This is coffee script');
}).call(this);
</script>
#
Includes ( Similar to require() or include() function in PHP Language )
=> Includes allow you to insert the content of one jade file into another.
//- FILE: index.jade
doctype html
html
include ./includes/head.jade
body
h1 My Site
p Welcome to my super lame site
include
./includes/foot.jade
//- FILE: includes/head.jade
head
title My Simple Node Application
script(type="text/javascript", src="js/jquery.min.js")
script(type="text/javascript", src="js/app.js")
//- FILE:
includes/foot.jade
#footer
p Copyright 1990-2014 (c) foobar
//- FILE: index.html (generated using Jade)
<!DOCTYPE html>
<html>
<head>
<title>My Simple Node Application</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body>
<h1>Welcome to my Simple website</h1>
<p>this is cool</p>
<div id="footer">
<p>Copyright 1990-2014 (c) foobar</p>
</div>
</body>
</html>
=>
Including filtered text
You can combine filters with includes to filter things as you include
them.
//- FILE: index.jade
doctype html
html
head
title A Simple Article
body
include:markdown article.md
//- FILE: article.md
This is an article written in
markdown.
In order to apply the transform markdown you must install one of "marked","supermarked","markdown-js","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>
//- FILE: index.html ( generated file using Jade)
<!DOCTYPE html>
<html>
<head>
<title>A Simple Article</title>
</head>
<body><p><!DOCTYPE HTML></p>
<html>
<head>
<title> An Article</title>
</head>
<body>
<h1>article.md</h1>
<p>This is an article written in markdown</p>
</body>
</html>
</body>
</html>
#
Template Inheritance
Jade supports inheritance via the Keywords block and
extends. Jade block can provide default content
=> A block is simply a "block" of jade that may be replaced within a child template. This
process is recursive
//- FILE: 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 we do not want to use the defaul content of blocks scripts and content, so lets re-define them.
//- FILE: 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
This
is possible to override a block to provide additional blocks. Here we
are extending layout.jade but we are re-defining the content block.
//- FILE:
sub-layout.jade
extends ./layout.jade
block content
.sidebar
block
sidebar
p nothing
.primary
block primary
p nothing
//- FILE: 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 and there are also some custom scripts that might be diffrent for a diffrent web pages.
//- FILE: layout.jade
html
head
block head
link(rel="stylesheet", href="style/bootstrap.min.css")
script(type="text/javascript", src="js/jquery.js")
script(type="text/javascript", src="js/bootstrap.min.js")
body
block content
Now you are extending this template for your website game/application page, and you need to add some more scripts,
This is why, you don't want to replace the default content of scripts block, This is where 'append' can help you.
//- FILE: index.jade
extends layout.jade
block append head
script(type="text/javascript", src="js/app.js")
script(type="text/javascript", src="js/game.js")
block content
h1 Welcome to my game page
//- FILE: index.html (Generated from index.jade file)
<html>
<head>
<link rel="stylesheet" href="style/bootstrap.min.css"/>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/game.js"></script>
<body>
<h1>Welcome to my game page</h1>
</body>
</head>
</html>
# Mixins ( Jade function ) ( and two global objects, attributes , and &attributes )
Mixins allow you to create reusable
blocks of jade
//- Declaration of a Jade mixins
mixin list
ul
li Simple
li Hello
li world
// using mixins
+list
+list
<ul>
<li>Simple</li>
<li>Hello</li>
<li>world</li>
</ul>
<ul>
<li>Simple</li>
<li>Hello</li>
<li>world</li>
</ul>
=> Mixins are compiled to
functions and can take arguments just like JavaScript functions.
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 BlocksMixins can also take a block of jade to act as the content
//- FILE: index.jade
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
//- FILE: index.html ( generated HTML code)
<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("/demo.html", "Demo to link")(class="btn")
<a href="/demo.html" class="btn">Demo to link</a>
=> You can also use with
&attributes
mixin link(href,name)
a(href=href)&attributes(attributes)= name
+link("/demo.html", "demo to link")(class="btn", id="button")
<a href="/demo.html" class="btn" id="button">demo to link</a>
=> Rest Arguments
You can write mixins that take an unknown number of arguments using the 'rest arguments' syntax
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>