[![Build Status](https://secure.travis-ci.org/visionmedia/jade.png)](http://travis-ci.org/visionmedia/jade) # Jade - template engine Jade is a high performance template engine heavily influenced by [Haml](http://haml-lang.com) and implemented with JavaScript for [node](http://nodejs.org). For discussion join the [Google Group](http://groups.google.com/group/jadejs). ## Test drive You can test drive Jade online [here](http://naltatis.github.com/jade-syntax-docs). ## README Contents - [Features](#a1) - [Implementations](#a2) - [Installation](#a3) - [Browser Support](#a4) - [Public API](#a5) - [Syntax](#a6) - [Line Endings](#a6-1) - [Tags](#a6-2) - [Tag Text](#a6-3) - [Comments](#a6-4) - [Block Comments](#a6-5) - [Nesting](#a6-6) - [Block Expansion](#a6-7) - [Case](#a6-8) - [Attributes](#a6-9) - [HTML](#a6-10) - [Doctypes](#a6-11) - [Filters](#a7) - [Code](#a8) - [Iteration](#a9) - [Conditionals](#a10) - [Template inheritance](#a11) - [Block append / prepend](#a12) - [Includes](#a13) - [Mixins](#a14) - [Generated Output](#a15) - [Example Makefile](#a16) - [jade(1)](#a17) - [Tutorials](#a18) - [License](#a19) ## Features - client-side support - great readability - flexible indentation - block-expansion - mixins - static includes - attribute interpolation - code is escaped by default for security - contextual error reporting at compile & run time - executable for compiling jade templates via the command line - html 5 mode (the default doctype) - optional memory caching - combine dynamic and static tag classes - parse tree manipulation via _filters_ - template inheritance - block append / prepend - supports [Express JS](http://expressjs.com) out of the box - transparent iteration over objects, arrays, and even non-enumerables via `each` - block comments - no tag prefix - filters - :stylus must have [stylus](http://github.com/LearnBoost/stylus) installed - :less must have [less.js](http://github.com/cloudhead/less.js) installed - :markdown must have [markdown-js](http://github.com/evilstreak/markdown-js), [node-discount](http://github.com/visionmedia/node-discount), or [marked](http://github.com/chjj/marked) installed - :cdata - :coffeescript must have [coffee-script](http://jashkenas.github.com/coffee-script/) installed - [Emacs Mode](https://github.com/brianc/jade-mode) - [Vim Syntax](https://github.com/digitaltoad/vim-jade) - [TextMate Bundle](http://github.com/miksago/jade-tmbundle) - [Coda/SubEtha syntax Mode](https://github.com/aaronmccall/jade.mode) - [Screencasts](http://tjholowaychuk.com/post/1004255394/jade-screencast-template-engine-for-nodejs) - [html2jade](https://github.com/donpark/html2jade) converter ## Implementations - [php](http://github.com/everzet/jade.php) - [scala](http://scalate.fusesource.org/versions/snapshot/documentation/scaml-reference.html) - [ruby](http://github.com/stonean/slim) - [python](https://github.com/SyrusAkbary/pyjade) - [java](https://github.com/neuland/jade4j) ## Installation via npm: ```bash $ npm install jade ``` ## Browser Support To compile jade to a single file compatible for client-side use simply execute: ```bash $ make jade.js ``` Alternatively, if uglifyjs is installed via npm (`npm install uglify-js`) you may execute the following which will create both files. However each release builds these for you. ```bash $ make jade.min.js ``` By default Jade instruments templates with line number statements such as `__.lineno = 3` for debugging purposes. When used in a browser it's useful to minimize this boiler plate, you can do so by passing the option `{ compileDebug: false }`. The following template ```jade p Hello #{name} ``` Can then be as small as the following generated function: ```js function anonymous(locals, attrs, escape, rethrow) { var buf = []; with (locals || {}) { var interp; buf.push('\n
Hello ' + escape((interp = name) == null ? '' : interp) + '\n
'); } return buf.join(""); } ``` Through the use of Jade's `./runtime.js` you may utilize these pre-compiled templates on the client-side _without_ Jade itself, all you need is the associated utility functions (in runtime.js), which are then available as `jade.attrs`, `jade.escape` etc. To enable this you should pass `{ client: true }` to `jade.compile()` to tell Jade to reference the helper functions via `jade.attrs`, `jade.escape` etc. ```js function anonymous(locals, attrs, escape, rethrow) { var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow; var buf = []; with (locals || {}) { var interp; buf.push('\nHello ' + escape((interp = name) == null ? '' : interp) + '\n
'); } return buf.join(""); } ``` ## Public API ```js var jade = require('jade'); // Compile a function var fn = jade.compile('string of jade', options); fn(locals); ``` ### Options - `self` Use a `self` namespace to hold the locals _(false by default)_ - `locals` Local variable object - `filename` Used in exceptions, and required when using includes - `debug` Outputs tokens and function body generated - `compiler` Compiler to replace jade's default - `compileDebug` When `false` no debug instrumentation is compiled - `pretty` Add pretty-indentation whitespace to output _(false by default)_ ## Syntax ### Line Endings **CRLF** and **CR** are converted to **LF** before parsing. ### Tags A tag is simply a leading word: ```jade html ``` for example is converted to `` tags can also have ids: ```jade div#container ``` which would render `` how about some classes? ```jade div.user-details ``` renders `` multiple classes? _and_ an id? sure: ```jade div#foo.bar.baz ``` renders `` div div div sure is annoying, how about: ```jade #foo .bar ``` which is syntactic sugar for what we have already been doing, and outputs: ```html ``` ### Tag Text Simply place some content after the tag: ```jade p wahoo! ``` renders `wahoo!
`. well cool, but how about large bodies of text: ```jade p | foo bar baz | rawr rawr | super cool | go jade go ``` renders `foo bar baz rawr.....
` interpolation? yup! both types of text can utilize interpolation, if we passed `{ name: 'tj', email: 'tj@vision-media.ca' }` to the compiled function we can do the following: ```jade #user #{name} <#{email}> ``` outputs `#{something}
` We can also utilize the unescaped variant `!{html}`, so the following will result in a literal script tag: ```jade - var html = "" | !{html} ``` Nested tags that also contain text can optionally use a text block: ```jade label | Username: input(name='user[name]') ``` or immediate tag text: ```jade label Username: input(name='user[name]') ``` Tags that accept _only_ text such as `script` and `style` do not need the leading `|` character, for example: ```jade html head title Example script if (foo) { bar(); } else { baz(); } ``` Once again as an alternative, we may use a trailing `.` to indicate a text block, for example: ```jade p. foo asdf asdf asdfasdfaf asdf asd. ``` outputs: ```htmlfoo asdf asdf asdfasdfaf asdf asd.
``` This however differs from a trailing `.` followed by a space, which although is ignored by the Jade parser, tells Jade that this period is a literal: ```jade p . ``` outputs: ```html.
``` It should be noted that text blocks should be doubled escaped. For example if you desire the following output. ```htmlfoo\bar
``` use: ```jade p. foo\\bar ``` ### Comments Single line comments currently look the same as JavaScript comments, aka `//` and must be placed on their own line: ```jade // just some paragraphs p foo p bar ``` would output ```htmlfoo
bar
``` Jade also supports unbuffered comments, by simply adding a hyphen: ```jade //- will not output within markup p foo p bar ``` outputting ```htmlfoo
bar
``` ### Block Comments A block comment is legal as well: ```jade body // #content h1 Example ``` outputting ```html ``` Jade supports conditional-comments as well, for example: ```jade head //if lt IE 8 script(src='/ie-sucks.js') ``` outputs: ```html ``` ### Nesting Jade supports nesting to define the tags in a natural way: ```jade ul li.first a(href='#') foo li a(href='#') bar li.last a(href='#') baz ``` ### Block Expansion Block expansion allows you to create terse single-line nested tags, the following example is equivalent to the nesting example above. ```jade ul li.first: a(href='#') foo li: a(href='#') bar li.last: a(href='#') baz ``` ### Case The case statement takes the following form: ```jade html body friends = 10 case friends when 0 p you have no friends when 1 p you have a friend default p you have #{friends} friends ``` Block expansion may also be used: ```jade friends = 5 html body case friends when 0: p you have no friends when 1: p you have a friend default: p you have #{friends} friends ``` ### Attributes Jade currently supports `(` and `)` as attribute delimiters. ```jade a(href='/login', title='View login page') Login ``` When a value is `undefined` or `null` the attribute is _not_ added, so this is fine, it will not compile `something="null"`. ```jade div(something=null) ``` Boolean attributes are also supported: ```jade input(type="checkbox", checked) ``` Boolean attributes with code will only output the attribute when `true`: ```jade input(type="checkbox", checked=someValue) ``` Multiple lines work too: ```jade input(type='checkbox', name='agreement', checked) ``` Multiple lines without the comma work fine: ```jade input(type='checkbox' name='agreement' checked) ``` Funky whitespace? fine: ```jade input( type='checkbox' name='agreement' checked) ``` Colons work: ```jade rss(xmlns:atom="atom") ``` Suppose we have the `user` local `{ id: 12, name: 'tobi' }` and we wish to create an anchor tag with `href` pointing to "/user/12" we could use regular javascript concatenation: ```jade a(href='/user/' + user.id)= user.name ``` or we could use jade's interpolation, which I added because everyone using Ruby or CoffeeScript seems to think this is legal js..: ```jade a(href='/user/#{user.id}')= user.name ``` The `class` attribute is special-cased when an array is given, allowing you to pass an array such as `bodyClasses = ['user', 'authenticated']` directly: ```jade body(class=bodyClasses) ``` ### HTML Inline html is fine, we can use the pipe syntax to write arbitrary text, in this case some html: ```jade html body |foo bar baz
``` Or we can use the trailing `.` to indicate to Jade that we only want text in this block, allowing us to omit the pipes: ```jade html body.foo bar baz
``` Both of these examples yield the same result: ```htmlfoo bar baz
``` The same rule applies for anywhere you can have text in jade, raw html is fine: ```jade html body h1 User #{name} ``` ### Doctypes To add a doctype simply use `!!!`, or `doctype` followed by an optional value: ```jade !!! ``` or ```jade doctype ``` Will output the _html 5_ doctype, however: ```jade !!! transitional ``` Will output the _transitional_ doctype. Doctypes are case-insensitive, so the following are equivalent: ```jade doctype Basic doctype basic ``` it's also possible to simply pass a doctype literal: ```jade doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN ``` yielding: ```html ', 'transitional': '', 'strict': '', 'frameset': '', '1.1': '', 'basic': '', 'mobile': '' }; ``` To alter the default simply change: ```js jade.doctypes.default = 'whatever you want'; ``` ## Filters Filters are prefixed with `:`, for example `:markdown` and pass the following block of text to an arbitrary function for processing. View the _features_ at the top of this document for available filters. ```jade body :markdown Woah! jade _and_ markdown, very **cool** we can even link to [stuff](http://google.com) ``` Renders: ```htmlWoah! jade and markdown, very cool we can even link to stuff
``` ## Code Jade currently supports three classifications of executable code. The first is prefixed by `-`, and is not buffered: ```jade - var foo = 'bar'; ``` This can be used for conditionals, or iteration: ```jade - for (var key in obj) p= obj[key] ``` Due to Jade's buffering techniques the following is valid as well: ```jade - if (foo) ul li yay li foo li worked - else p oh no! didnt work ``` Hell, even verbose iteration: ```jade - if (items.length) ul - items.forEach(function(item){ li= item - }) ``` Anything you want! Next up we have _escaped_ buffered code, which is used to buffer a return value, which is prefixed by `=`: ```jade - var foo = 'bar' = foo h1= foo ``` Which outputs `barWelcome to my super lame site.
``` As mentioned `include` can be used to include other content such as html or css. By providing an extension Jade will not assume that the file is Jade source and will include it as a literal: ```jade html body include content.html ``` Include directives may also accept a block, in which case the the given block will be appended to the _last_ block defined in the file. For example if `head.jade` contains: ```jade head script(src='/jquery.js') ``` We may append values by providing a block to `include head` as shown below, adding the two scripts. ```jade html include head script(src='/foo.js') script(src='/bar.js') body h1 test ``` You may also `yield` within an included template, allowing you to explicitly mark where the block given to `include` will be placed. Suppose for example you wish to prepend scripts rather than append, you might do the following: ```jade head yield script(src='/jquery.js') script(src='/jquery.ui.js') ``` Since included Jade is parsed and literally merges the AST, lexically scoped variables function as if the included Jade was written right in the same file. This means `include` may be used as sort of partial, for example suppose we have `user.jade` which utilizes a `user` variable. ```jade h1= user.name p= user.occupation ``` We could then simply `include user` while iterating users, and since the `user` variable is already defined within the loop the included template will have access to it. ```jade users = [{ name: 'Tobi', occupation: 'Ferret' }] each user in users .user include user ``` yielding: ```htmlFerret
'); buf.push('Just an example'); buf.push('
'); } return buf.join(""); } catch (err) { rethrow(err, __.input, __.filename, __.lineno); } } ``` When the `compileDebug` option _is_ explicitly `false`, this instrumentation is stripped, which is very helpful for light-weight client-side templates. Combining Jade's options with the `./runtime.js` file in this repo allows you to toString() compiled templates and avoid running the entire Jade library on the client, increasing performance, and decreasing the amount of JavaScript required. ```js function anonymous(locals) { var attrs = jade.attrs, escape = jade.escape; var buf = []; with (locals || {}) { var interp; var title = 'yay' buf.push(''); buf.push('Just an example'); buf.push('
'); } return buf.join(""); } ``` ## Example Makefile Below is an example Makefile used to compile _pages/*.jade_ into _pages/*.html_ files by simply executing `make`. ```make JADE = $(shell find pages/*.jade) HTML = $(JADE:.jade=.html) all: $(HTML) %.html: %.jade jade < $< --path $< > $@ clean: rm -f $(HTML) .PHONY: clean ``` this can be combined with the `watch(1)` command to produce a watcher-like behaviour: ```bash $ watch make ``` ## jade(1) ``` Usage: jade [options] [dir|file ...] Options: -h, --help output usage information -V, --version output the version number -o, --obj