1 |
|
2 | # Jade - template engine
|
3 |
|
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).
|
6 |
|
7 | ## Features
|
8 |
|
9 | - high performance parser
|
10 | - great readability
|
11 | - code is escaped by default for security
|
12 | - contextual error reporting at compile & run time
|
13 | - executable for compiling jade templates via the command line
|
14 | - html 5 mode (using the _!!! 5_ doctype)
|
15 | - optional memory caching
|
16 | - combine dynamic and static tag classes
|
17 | - supports [Express JS](http://expressjs.com)
|
18 | - no tag prefix
|
19 | - filters
|
20 | - :sass
|
21 | - :markdown
|
22 | - :cdata
|
23 | - :javascript
|
24 |
|
25 | ## Installation
|
26 |
|
27 | via tarball or git:
|
28 |
|
29 | make install
|
30 |
|
31 | via npm:
|
32 |
|
33 | npm install jade
|
34 |
|
35 | via kiwi:
|
36 |
|
37 | kiwi install jade
|
38 |
|
39 | ## Public API
|
40 |
|
41 | var jade = require('jade');
|
42 |
|
43 | // Render a string
|
44 | jade.render('string of jade', { options: 'here' });
|
45 |
|
46 | // Render a file
|
47 | jade.renderFile('path/to/some.jade', { options: 'here' }, function(err, html){
|
48 | // options are optional,
|
49 | // the callback can be the second arg
|
50 | });
|
51 |
|
52 | ### Options
|
53 |
|
54 | - `scope` Evaluation scope (`this`)
|
55 | - `locals` Local variable object
|
56 | - `filename` Used in exceptions, and required by `cache`
|
57 | - `cache` Cache intermediate JavaScript in memory keyed by `filename`
|
58 | - `debug` Outputs tokens and function body generated
|
59 |
|
60 | ## Syntax
|
61 |
|
62 | ### Line Endings
|
63 |
|
64 | **CRLF** and **CR** are converted to **LF** before parsing.
|
65 |
|
66 | ### Indentation
|
67 |
|
68 | Jade is indentation based, however currently only supports a _2 space_ indent.
|
69 | We may implement tab support in the future, until then use spaces, so make sure soft
|
70 | tabs are enabled in your editor.
|
71 |
|
72 | ### Tags
|
73 |
|
74 | A tag is simply a leading word:
|
75 |
|
76 | html
|
77 |
|
78 | for example is converted to `<html></html>`
|
79 |
|
80 | tags can also have ids:
|
81 |
|
82 | div#container
|
83 |
|
84 | which would render `<div id="container"></div>`
|
85 |
|
86 | how about some classes?
|
87 |
|
88 | div.user-details
|
89 |
|
90 | renders `<div class="user-details"></div>`
|
91 |
|
92 | multiple classes? _and_ an id? sure:
|
93 |
|
94 | div#foo.bar.baz
|
95 |
|
96 | renders `<div id="foo" class="bar baz"></div>`
|
97 |
|
98 | div div div sure is annoying, how about:
|
99 |
|
100 | #foo
|
101 | .bar
|
102 |
|
103 | which is syntactic sugar for what we have already been doing, and outputs:
|
104 |
|
105 | `<div id="foo"></div><div class="bar"></div>`
|
106 |
|
107 | ### Tag Text
|
108 |
|
109 | Simply place some content after the tag:
|
110 |
|
111 | p wahoo!
|
112 |
|
113 | renders `<p>wahoo!</p>`.
|
114 |
|
115 | well cool, but how about large bodies of text:
|
116 |
|
117 | p
|
118 | | foo bar baz
|
119 | | rawr rawr
|
120 | | super cool
|
121 | | go jade go
|
122 |
|
123 | renders `<p>foo bar baz rawr.....</p>`
|
124 |
|
125 | interpolation? yup! both types of text can utilize interpolation,
|
126 | if we passed `{ locals: { name: 'tj', email: 'tj@vision-media.ca' }}` to `render()`
|
127 | we can do the following:
|
128 |
|
129 | #user #{name} <#{email}>
|
130 |
|
131 | outputs `<div id="user">tj <tj@vision-media.ca></div>`
|
132 |
|
133 | Actually want `#{}` for some reason? escape it!
|
134 |
|
135 | p \#{something}
|
136 |
|
137 | now we have `<p>#{something}</p>`
|
138 |
|
139 | ### Nesting
|
140 |
|
141 | ul
|
142 | li one
|
143 | li two
|
144 | li three
|
145 |
|
146 | Fucked up your whitespace? no worries, jade's error reporting should help you out.
|
147 | Jade instruments the compiled JavaScript to provide meaningful context for runtime exceptions.
|
148 |
|
149 | ul
|
150 | li one
|
151 | li two
|
152 |
|
153 | Error: /Users/tj/Projects/jade/examples/layout.jade:2
|
154 | 1. 'ul'
|
155 | 2. ' li one'
|
156 |
|
157 | Invalid indentation, got 2 expected 1.
|
158 |
|
159 | Note: Trailing are generated on **EOS** if not present.
|
160 |
|
161 | ### Attributes
|
162 |
|
163 | Jade currently supports '(' and ')' as attribute delimiters.
|
164 |
|
165 | a(href='/login', title='View login page') Login
|
166 |
|
167 | Alternatively we may use the colon to separate pairs:
|
168 |
|
169 | a(href: '/login', title: 'View login page') Login
|
170 |
|
171 | Boolean attributes are also supported:
|
172 |
|
173 | input(type="checkbox", checked)
|
174 |
|
175 | Boolean attributes with code will only output the attribute when `true`:
|
176 |
|
177 | input(type="checkbox", checked: someValue)
|
178 |
|
179 | Note: Leading / trailing whitespace is _ignore_ for attr pairs.
|
180 |
|
181 | ### Doctypes
|
182 |
|
183 | To add a doctype simply use `!!!` followed by an optional value:
|
184 |
|
185 | !!!
|
186 |
|
187 | Will output the _transitional_ doctype, however:
|
188 |
|
189 | !!! 5
|
190 |
|
191 | Will output html 5's doctype. Below are the doctypes
|
192 | defined by default, which can easily be extended:
|
193 | var doctypes = exports.doctypes = {
|
194 | '5': '<!DOCTYPE html>',
|
195 | 'xml': '<?xml version="1.0" encoding="utf-8" ?>',
|
196 | 'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
197 | 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
198 | 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
199 | 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
200 | '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
201 | 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
|
202 | 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
|
203 | };
|
204 |
|
205 | To alter the default simply change:
|
206 |
|
207 | jade.doctypes.default = 'whatever you want';
|
208 |
|
209 | ## Filters
|
210 |
|
211 | Filters are prefixed with `:`, for example `:markdown` and
|
212 | pass the following block of text to an arbitrary function for processing. View the _features_
|
213 | at the top of this document for available filters.
|
214 |
|
215 | body
|
216 | :markdown
|
217 | | Woah! jade _and_ markdown, very **cool**
|
218 | | we can even link to [stuff](http://google.com)
|
219 |
|
220 | Renders:
|
221 |
|
222 | <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>
|
223 |
|
224 | ## Code
|
225 |
|
226 | Jade currently supports three classifications of executable code. The first
|
227 | is prefixed by `-`, and is not buffered:
|
228 |
|
229 | - var foo = 'bar';
|
230 |
|
231 | This can be used for conditionals, or iteration:
|
232 |
|
233 | - for (var key in obj)
|
234 | p= obj[key]
|
235 |
|
236 | Due to Jade's buffering techniques the following is valid as well:
|
237 |
|
238 | - if (foo)
|
239 | ul
|
240 | li yay
|
241 | li foo
|
242 | li worked
|
243 | - else
|
244 | p shit! didnt work
|
245 |
|
246 | Hell, even verbose iteration:
|
247 |
|
248 | - if (items.length)
|
249 | ul
|
250 | - items.forEach(function(item){
|
251 | li= item
|
252 | - })
|
253 |
|
254 | Anything you want!
|
255 |
|
256 | Next up we have _escaped_ buffered code, which is used to
|
257 | buffer a return value, which is prefixed by `=`:
|
258 |
|
259 | - var foo = 'bar'
|
260 | = foo
|
261 | h1= foo
|
262 |
|
263 | Which outputs `bar<h1>bar<h1/>`. Code buffered by `=` is escaped
|
264 | by default for security, however to output unescaped return values
|
265 | you may use `!=`:
|
266 |
|
267 | p!= aVarContainingMoreHTML
|
268 |
|
269 | ## bin/jade
|
270 |
|
271 | Output html to _stdout_:
|
272 |
|
273 | jade examples/*.jade --pipe
|
274 |
|
275 | Generate _examples/*.html_:
|
276 |
|
277 | jade examples/*.jade
|
278 |
|
279 | Pass options:
|
280 |
|
281 | jade examples/layout.jade --options '{ locals: { title: "foo" }}'
|
282 |
|
283 | Usage info:
|
284 |
|
285 | Usage: jade [options] <path ...>
|
286 |
|
287 | Options:
|
288 | -o, --options STR JavaScript options object passed
|
289 | -p, --pipe Output to stdout instead of PATH.html
|
290 | -h, --help Output help information
|
291 |
|