2 # Jade - template engine
4 Jade is a high performance template engine heavily influenced by [Haml](http://haml-lang.com)
5 and implemented with JavaScript for [node](http://nodejs.org).
11 - flexible indentation
15 - attribute interpolation
16 - code is escaped by default for security
17 - contextual error reporting at compile & run time
18 - executable for compiling jade templates via the command line
19 - html 5 mode (using the _!!! 5_ doctype)
20 - optional memory caching
21 - combine dynamic and static tag classes
22 - parse tree manipulation via _filters_
23 - supports [Express JS](http://expressjs.com) out of the box
24 - transparent iteration over objects, arrays, and even non-enumerables via `- each`
29 - :sass must have [sass.js](http://github.com/visionmedia/sass.js) installed
30 - :less must have [less.js](http://github.com/cloudhead/less.js) installed
31 - :markdown must have [markdown-js](http://github.com/evilstreak/markdown-js) installed or [node-discount](http://github.com/visionmedia/node-discount)
33 - :coffeescript must have [coffee-script](http://jashkenas.github.com/coffee-script/) installed
34 - [Vim Syntax](https://github.com/digitaltoad/vim-jade)
35 - [TextMate Bundle](http://github.com/miksago/jade-tmbundle)
36 - [Screencasts](http://tjholowaychuk.com/post/1004255394/jade-screencast-template-engine-for-nodejs)
37 - [html2jade](https://github.com/donpark/html2jade) converter
41 - [php](http://github.com/everzet/jade.php)
42 - [scala](http://scalate.fusesource.org/versions/snapshot/documentation/scaml-reference.html)
43 - [ruby](http://github.com/stonean/slim)
53 To compile jade to a single file compatible for client-side use simply execute:
57 Alternatively, if uglifyjs is installed via npm (`npm install uglify-js`) you may execute the following which will create both files.
64 var jade = require('jade');
67 jade.render('string of jade', { options: 'here' });
70 jade.renderFile('path/to/some.jade', { options: 'here' }, function(err, html){
71 // options are optional,
72 // the callback can be the second arg
76 var fn = jade.compile('string of jade', options);
77 fn.call(scope, locals);
82 - `scope` Evaluation scope (`this`)
83 - `self` Use a `self` namespace to hold the locals. _false by default_
84 - `locals` Local variable object
85 - `filename` Used in exceptions, and required when using includes
86 - `debug` Outputs tokens and function body generated
87 - `compiler` Compiler to replace jade's default
93 **CRLF** and **CR** are converted to **LF** before parsing.
97 A tag is simply a leading word:
101 for example is converted to `<html></html>`
103 tags can also have ids:
107 which would render `<div id="container"></div>`
109 how about some classes?
113 renders `<div class="user-details"></div>`
115 multiple classes? _and_ an id? sure:
119 renders `<div id="foo" class="bar baz"></div>`
121 div div div sure is annoying, how about:
126 which is syntactic sugar for what we have already been doing, and outputs:
128 `<div id="foo"></div><div class="bar"></div>`
132 Simply place some content after the tag:
136 renders `<p>wahoo!</p>`.
138 well cool, but how about large bodies of text:
146 renders `<p>foo bar baz rawr.....</p>`
148 interpolation? yup! both types of text can utilize interpolation,
149 if we passed `{ locals: { name: 'tj', email: 'tj@vision-media.ca' }}` to `render()`
150 we can do the following:
152 #user #{name} <#{email}>
154 outputs `<div id="user">tj <tj@vision-media.ca></div>`
156 Actually want `#{}` for some reason? escape it!
160 now we have `<p>#{something}</p>`
162 We can also utilize the unescaped variant `!{html}`, so the following
163 will result in a literal script tag:
165 - var html = "<script></script>"
168 Nested tags that also contain text can optionally use a text block:
172 input(name='user[name]')
174 or immediate tag text:
177 input(name='user[name]')
179 Tags that accept _only_ text such as `script`, `style`, and `textarea` do not
180 need the leading `|` character, for example:
192 Once again as an alternative, we may use a leading '.' to indicate a text block, for example:
211 This however differs from a leading '.' followed by a space, which although is ignored by the Jade parser, tells Jade that this period is a literal:
221 Single line comments currently look the same as JavaScript comments,
222 aka "//" and must be placed on their own line:
224 // just some paragraphs
230 <!-- just some paragraphs -->
234 Jade also supports unbuffered comments, by simply adding a hyphen:
236 //- will not output within markup
247 A block comment is legal as well:
264 Jade supports conditional-comments as well, for example:
268 a(href='http://www.mozilla.com/en-US/firefox/') Get Firefox
274 <a href="http://www.mozilla.com/en-US/firefox/">Get Firefox</a>
281 Jade supports nesting to define the tags in a natural way:
293 Block expansion allows you to create terse single-line nested tags,
294 the following example is equivalent to the nesting example above.
297 li.first: a(href='#') foo
299 li.last: a(href='#') baz
304 Jade currently supports '(' and ')' as attribute delimiters.
306 a(href='/login', title='View login page') Login
308 Boolean attributes are also supported:
310 input(type="checkbox", checked)
312 Boolean attributes with code will only output the attribute when `true`:
314 input(type="checkbox", checked= someValue)
316 Multiple lines work too:
318 input(type='checkbox',
322 Multiple lines without the comma work fine:
324 input(type='checkbox'
328 Funky whitespace? fine:
338 rss(xmlns:atom="atom")
340 Suppose we have the `user` local `{ id: 12, name: 'tobi' }`
341 and we wish to create an anchor tag with `href` pointing to "/user/12"
342 we could use regular javascript concatenation:
344 a(href='/user/' + user.id)= user.name
346 or we could use jade's interpolation:
348 a(href='/user/#{user.id}')= user.name
350 The `class` attribute is special-cased when an array is given,
351 allowing you to pass an array such as `bodyClasses = ['user', 'authenticated']` directly:
353 body(class=bodyClasses)
357 To add a doctype simply use `!!!`, or `doctype` followed by an optional value:
361 Will output the _transitional_ doctype, however:
373 doctypes are case-insensitive, so the following are equivalent:
378 Will output the _html 5_ doctype. Below are the doctypes
379 defined by default, which can easily be extended:
382 var doctypes = exports.doctypes = {
383 '5': '<!DOCTYPE html>',
384 'xml': '<?xml version="1.0" encoding="utf-8" ?>',
385 'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
386 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
387 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
388 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
389 '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
390 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
391 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
395 To alter the default simply change:
398 jade.doctypes.default = 'whatever you want';
403 Filters are prefixed with `:`, for example `:markdown` and
404 pass the following block of text to an arbitrary function for processing. View the _features_
405 at the top of this document for available filters.
409 Woah! jade _and_ markdown, very **cool**
410 we can even link to [stuff](http://google.com)
414 <body><p>Woah! jade <em>and</em> markdown, very <strong>cool</strong> we can even link to <a href="http://google.com">stuff</a></p></body>
416 Filters may also manipulate the parse tree. For example perhaps I want to
417 bake conditionals right into jade, we could do so with a filter named _conditionals_. Typically filters work on text blocks, however by passing a regular block our filter can do anything it wants with the tags nested within it.
426 Not that we no longer prefix with "-" for these code blocks. Examples of
427 how to manipulate the parse tree can be found at _./examples/conditionals.js_ and _./examples/model.js_, basically we subclass and re-implement visitor methods as needed. There are several interesting use-cases for this functionality above what was shown above such as transparently aggregating / compressing assets to reduce the number of HTTP requests, transparent record error reporting, and more.
431 Jade currently supports three classifications of executable code. The first
432 is prefixed by `-`, and is not buffered:
436 This can be used for conditionals, or iteration:
438 - for (var key in obj)
441 Due to Jade's buffering techniques the following is valid as well:
451 Hell, even verbose iteration:
455 - items.forEach(function(item){
461 Next up we have _escaped_ buffered code, which is used to
462 buffer a return value, which is prefixed by `=`:
468 Which outputs `bar<h1>bar</h1>`. Code buffered by `=` is escaped
469 by default for security, however to output unescaped return values
472 p!= aVarContainingMoreHTML
474 The on exception made in terms of allowing "vanilla" JavaScript, is
475 the `- each` token. This takes the form of:
477 - each VAL[, KEY] in OBJ
479 An example iterating over an array:
481 - var items = ["one", "two", "three"]
491 iterating an object's keys and values:
493 - var obj = { foo: 'bar' }
494 - each val, key in obj
497 would output `<li>foo: bar</li>`
499 You can also nest these!
502 - each role in user.roles
505 When a property is undefined, Jade will output an empty string. For example:
507 textarea= user.signature
509 when undefined would normally output "undefined" in your html, however recent
510 versions of Jade will simply render:
512 <textarea></textarea>
516 Includes allow you to statically include chunks of Jade
517 which lives in a separate file. The classical example is
518 including a header and footer. Suppose we have the following
526 and the following _layout.jade_:
529 include includes/head
532 p Welcome to my super amazing site.
533 include includes/foot
535 both includes _includes/head_ and _includes/foot_ are
536 read relative to the `filename` option given to _layout.jade_,
537 which should be an absolute path to this file, however Express
538 and the `renderFile()` method do this for you. Include then parses
539 these files, and injects the AST produced to render what you would expect:
544 <title>My Site</title>
545 <script src="/javascripts/jquery.js">
546 </script><script src="/javascripts/app.js"></script>
550 <p>Welcome to my super lame site.</p>
552 <p>Copyright>(c) foobar</p>
560 Mixins are converted to regular JavaScript functions in
561 the compiled template that Jade constructs. Mixins may
562 take arguments, though not required:
570 Utilizing a mixin without args looks similar, just without a block:
575 Mixins may take one or more arguments as well, the arguments
576 are regular javascripts expressions, so for example the following:
586 mixin pets(user.pets)
588 Would yield something similar to the following html:
604 Output html to _stdout_:
606 jade < my.jade > my.html
608 Generate _examples/*.html_:
614 jade examples/layout.jade --options '{ locals: { title: "foo" }}'
618 Usage: jade [options]
622 -o, --options <str> JavaScript options object passed
623 -h, --help Output help information
624 -w, --watch Watch file(s) or folder(s) for changes and re-compile
625 -v, --version Output jade version
626 --out <dir> Output the compiled html to <dir>
632 Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca>
634 Permission is hereby granted, free of charge, to any person obtaining
635 a copy of this software and associated documentation files (the
636 'Software'), to deal in the Software without restriction, including
637 without limitation the rights to use, copy, modify, merge, publish,
638 distribute, sublicense, and/or sell copies of the Software, and to
639 permit persons to whom the Software is furnished to do so, subject to
640 the following conditions:
642 The above copyright notice and this permission notice shall be
643 included in all copies or substantial portions of the Software.
645 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
646 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
647 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
648 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
649 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
650 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
651 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.