Skip to content
Newer
Older
100644 1285 lines (976 sloc) 41.8 KB
13f77d1 @bminer Updated docs
authored May 5, 2012
1 Blade - HTML Template Compiler
2 ==============================
477765b @bminer initial commit
authored May 3, 2012
3
13f77d1 @bminer Updated docs
authored May 5, 2012
4 Blade is a HTML Template Compiler, inspired by Jade & Haml, implemented in
3a87c0f @bminer Updated docs
authored May 5, 2012
5 JavaScript, so it will run on your microwave oven.
85b59cb @bminer Initial commit
authored May 4, 2012
6
57fd2d1 @bminer Push to version 1.0
authored May 18, 2012
7 It works like this...
8
0d9e6c0 @bminer Fixed typos
authored May 18, 2012
9 1. Write up your template in Blade (which is a Jade-like language)
10 2. Use the Blade compiler to generate a Blade template (which is a JavaScript function)
11 3. Pass variables into your generated template to produce HTML or XML
57fd2d1 @bminer Push to version 1.0
authored May 18, 2012
12
13 [View a simple example](#simple-example)
14
85b59cb @bminer Initial commit
authored May 4, 2012
15 Never write HTML again. Please.
16
95fddd1 @bminer Added update to docs about Meteor 0.4 support
authored Sep 11, 2012
17 **UPDATE:** Meteor 0.4.0 support is coming soon! Thanks for your patience! If
18 anyone wants to help implement support for Meteor 0.4.0, please contact me.
19
42c0500 @bminer Try one more time
authored May 9, 2012
20 <img src="http://www.empireonline.com/images/features/100greatestcharacters/photos/47.jpg"
8edb7a1 @bminer Sorry. Had to do it. Needed an image in the README file.
authored May 9, 2012
21 alt="Blade" width="150" height="169"/>
3f12269 @bminer Updated docs
authored Jun 8, 2012
22
42c0500 @bminer Try one more time
authored May 9, 2012
23 "Blade's blood is the key" :P Sorry... I had to...
8edb7a1 @bminer Sorry. Had to do it. Needed an image in the README file.
authored May 9, 2012
24
ed65995 @bminer Updated docs
authored May 5, 2012
25 Table of Contents
26 -----------------
27
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
28 - [Why use Blade instead of Jade?](#why-use-blade-instead-of-jade)
ed65995 @bminer Updated docs
authored May 5, 2012
29 - [Features](#features)
0a59658 @bminer Updated docs
authored May 9, 2012
30 - [Project Status](#project-status)
ed65995 @bminer Updated docs
authored May 5, 2012
31 - [Installation](#installation)
32 - [Language Syntax](#syntax)
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
33 - [The Basics](#syntax)
34 - [Functions](#functions)
35 - [Dynamic File Includes](#dynamic-file-includes)
36 - [Blocks](#blocks)
ed65995 @bminer Updated docs
authored May 5, 2012
37 - [API](#api)
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
38 - [Browser Usage](#browser-usage)
57fd2d1 @bminer Push to version 1.0
authored May 18, 2012
39 - [A Simple Example](#simple-example)
bb83b87 @bminer * Updated documentation for plugins (closes #56)
authored Jul 10, 2012
40 - [Plugins](#plugins)
41 - [Meteor Support](#meteor-support)
f8a7895 @bminer Updated docs
authored May 5, 2012
42 - [Implementation Details](#implementation-details)
5122cdf @bminer Added benchmarks section, but it needs improvement
authored May 14, 2012
43 - [Benchmarks](#benchmarks)
ed65995 @bminer Updated docs
authored May 5, 2012
44 - [License](#license)
45
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
46 Why use Blade instead of Jade?
47 -----------------------
48
49 Here are the reasons Blade *might* be considered "better" than Jade:
50
8808126 @bminer Updated docs
authored May 9, 2012
51 - Jade is an ornamental stone. Blade is a badass vampire hunter.
a50e201 @bminer Updated docs
authored May 11, 2012
52 - **Client-side templates** can be served to the browser, no problem.
53 See [Browser Usage](#browser-usage) and [Blade Middleware]
54 (#blademiddlewaresourcepath-options) for more info.
70ff59d @bminer Removed Meteor version number because I don't want to update it all o…
authored Jun 12, 2012
55 - **Meteor support** - Blade works well with [Meteor](http://meteor.com/). See the
3f12269 @bminer Updated docs
authored Jun 8, 2012
56 [documentation below](#meteor-support).
dde7b64 @bminer Updated docs
authored May 30, 2012
57 - **Compatibility** - The language syntax of Blade is very similar to Jade's. Jade is
58 an awesome templating language, and if you are already familiar with it, getting
59 started with Blade should take you very little time.
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
60 - **Smarter file includes**
61 Files compiled in Blade can be much smaller than Jade files when you are using file
62 includes because file includes happen at runtime instead of at compile-time. If you
63 re-use the same included file among multiple views, the included file does not need to
64 be reloaded.
65 - **[Blocks](#blocks) in Blade are awesome.** We removed features from Jade like explicit
66 template inheritance and then added features like blocks and parameterized blocks.
67 You might find our idea of a block to be similar to Jade's, but just wait until you
68 realize how much more flexible they are!
3f12269 @bminer Updated docs
authored Jun 8, 2012
69 - **Just [Functions](#functions), not mixins or partials.** In Blade, there are no "mixins"
70 or partial templates. There are only functions, and they work just like regular JavaScript
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
71 functions that you've come to know and love. You can put your functions into separate
72 files and include them into other templates, you can take advantage of the `arguments`
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
73 Array-like Object, or whatever you want!
74 - **Other cool features** For example, Blade provides a built-in syntax for taking
75 content rendered by a function and loading it into a variable within your view template,
76 allowing you to pass rendered HTML content to another function. This is just one of
77 the many new features you can utilize when you make the switch to Blade.
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
78
3f12269 @bminer Updated docs
authored Jun 8, 2012
79 ```
0523635 @bminer Fixed typo
authored Jun 8, 2012
80 Jade vs. Blade
3f12269 @bminer Updated docs
authored Jun 8, 2012
81 ```
f842fa1 @bminer Fixed spacing
authored Jun 8, 2012
82 <img src="http://www.pbs.org/wgbh/nova/diamond/images/gp08jade.jpg" alt="Jade" width="226" height="169"/> &nbsp;&nbsp; <img src="http://www.empireonline.com/images/features/100greatestcharacters/photos/47.jpg" alt="Blade" width="150" height="169"/>
0272459 @bminer Updated docs
authored May 9, 2012
83
3b065c9 @bminer Updated docs
authored May 9, 2012
84 OK... it's admittedly not as funny as I thought it would be. But, I tried.
85
85b59cb @bminer Initial commit
authored May 4, 2012
86 Features
87 --------
88
c780880 @bminer Updated readme
authored May 4, 2012
89 - Write extremely readable short-hand HTML
3a87c0f @bminer Updated docs
authored May 5, 2012
90 - Insert escaped and unescaped text and vanilla JavaScript code
91 - Code and text are escaped by default for security/convenience
c780880 @bminer Updated readme
authored May 4, 2012
92 - Functions (like Jade mixins)
5899bbb @bminer Updated docs
authored May 4, 2012
93 - Dynamic file includes
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
94 - Regular blocks and Parameterized blocks (aids in supporting template inheritance)
13f77d1 @bminer Updated docs
authored May 5, 2012
95 - True client-side template support with caching, etc.
96 - Supports Express.JS
97 - HTML Comments and block comments
3a87c0f @bminer Updated docs
authored May 5, 2012
98 - Text filters
56fb7a6 @bminer Updated feature list
authored May 17, 2012
99 - Nice error reporting to help you debug your broken templates
937cd81 @bminer Blade now supports escaped tag names by preceding the tag with a back…
authored May 17, 2012
100 - Command-line tool to compile/render templates (try `blade --help`)
9631381 @bminer Updated documentation
authored May 21, 2012
101 - Meteor smart package
5b31e36 @bminer * Added support for event handlers
authored Jul 6, 2012
102 - Write DOM event handlers right into your views
bb83b87 @bminer * Updated documentation for plugins (closes #56)
authored Jul 10, 2012
103 - Cool plugins (including [Live UI](https://github.com/bminer/node-blade/wiki/Live-UI-Blade-Plugin))
3a87c0f @bminer Updated docs
authored May 5, 2012
104
0a59658 @bminer Updated docs
authored May 9, 2012
105 Project Status
106 --------------
3a87c0f @bminer Updated docs
authored May 5, 2012
107
5b31e36 @bminer * Added support for event handlers
authored Jul 6, 2012
108 I'd say that Blade is **stable**. There are very few (if any)
00d3999 @bminer * Updated project status
authored Jun 7, 2012
109 [known issues](https://github.com/bminer/node-blade/issues), and I think that Blade
110 is ready for production environments. I use Blade for many of my projects.
0a59658 @bminer Updated docs
authored May 9, 2012
111
112 If you find a bug, please [report it here]
113 (https://github.com/bminer/node-blade/issues). If you include the Blade code
114 that failed along with the expected HTML output, that is always splendid.
115
116 By all means, please feel free to submit pull requests for new features,
117 new tests, or whatever! For big changes, say ~100 lines of code, you
118 might want to contact me first or submit an issue before getting started.
85b59cb @bminer Initial commit
authored May 4, 2012
119
120 Installation
121 ------------
122
9ff8b25 @bminer Clarified install documentation
authored Jun 11, 2012
123 for Node (via npm): `sudo npm install -g blade`
4acf322 @bminer Updated docs
authored May 4, 2012
124
d382639 @bminer * Blade runtime and Blade plugins can be automatically uglified by th…
authored Jul 18, 2012
125 Runtime for Browsers: `wget https://raw.github.com/bminer/node-blade/master/lib/runtime.js`
4acf322 @bminer Updated docs
authored May 4, 2012
126
bdca3ff @bminer * Reoranized runtime so that Uglify can properly perform name manglin…
authored Jul 9, 2012
127 Minified runtime is about 5-6 KB, uncompressed.
4acf322 @bminer Updated docs
authored May 4, 2012
128
85b59cb @bminer Initial commit
authored May 4, 2012
129 Syntax
130 ------
131
132 ### Tags
133
134 Like Jade, a tag is simply a word. For example, the string `html` will render to `<html></html>`.
135
136 You can have 'id's:
137
138 ```
139 div#awesome
140 ```
141
142 which renders as `<div id="awesome"></div>`.
143
f2a0def @bminer Updated docs again
authored May 4, 2012
144 Any number of classes work, separated by a dot (`.`)
85b59cb @bminer Initial commit
authored May 4, 2012
145
146 ```
147 div.task-details.container
148 ```
149
150 which renders as `<div class="task-details container"></div>`.
151
4acf322 @bminer Updated docs
authored May 4, 2012
152 Tag attributes? Yep, they work pretty much like Jade, too.
13f77d1 @bminer Updated docs
authored May 5, 2012
153 Put attributes in parenthesis, separate attributes with a comma, space, newline, or whatever.
4acf322 @bminer Updated docs
authored May 4, 2012
154
155 `a(href="/homepage", onclick="return false;")` renders as:
156
157 ```html
158 <a href="/homepage" onclick="return false;"></a>
159 ```
160
fcbd7f0 @bminer Updated docs
authored May 4, 2012
161 You can also have line feeds or weird whitespace between attributes, just like in Jade.
162 Whatever. This works, for example:
163
164 ```
165 input(
166 type="text"
167 name="email"
168 value="Your email here"
169 )
170 ```
171
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
172 You can also put substitute an attribute value with vanilla JS code like this:
173 `input(type="text" name="contact-"+name value=value)`. For example, if you passed the object
174 `{name: "fred", value: "testing"}` to your view, the above would render to:
175 `<input type="text" name="contact-fred" value="testing"/>`
176
4d020de @bminer Updated documentation and moved Benchmark section to the wiki
authored Jun 7, 2012
177 You cannot put whitespace, commas, newlines, or parentheses in the vanilla JavaScript code,
178 though. Blade uses these characters to separate each attribute or to end the tag definition.
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
179
180 And, yes... the `class` attribute is handled with extra special care. Pass an array or string.
181 Classes (delimited by ".") from before will be merged with the value of the `class` attribute.
182
183 For example:
fcbd7f0 @bminer Updated docs
authored May 4, 2012
184
185 `div#foo.bar.dummy(class="another dude")` renders as: `<div id="foo" class="bar dummy another dude"></div>`
186
d382639 @bminer * Blade runtime and Blade plugins can be automatically uglified by th…
authored Jul 18, 2012
187 Boolean attributes are allowed, as well. If the attribute value is boolean `true`, then
188 the attribute is set; if the attribute value is boolean `false`, then the attribute is
189 ignored entirely. For example:
190
191 `input(type="text" checked=true)` renders as: `<input type="text" checked="checked"/>`.
192
193 Or... you can write it [HTML 5 style](http://dev.w3.org/html5/html-author/#empty-attr) like this:
194
195 `input(type="text" checked)` which renders as: `<input type="text" checked="checked"/>`.
196
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
197 div, div, div can get annoying... so, we can omit the tag specifier if we specify an
198 id or some classes:
85b59cb @bminer Initial commit
authored May 4, 2012
199
200 ```
201 #foo
202 .bar
203 #this.is.cool
204 ```
205
206 renders as:
207
208 ```html
209 <div id="foo"></div><div class="bar"></div><div id="this" class="is cool"></div>
210 ```
211
408ae90 @bminer Updated docs
authored May 8, 2012
212 Blade just assumes anything without a tag name specifier is a `<div>` tag.
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
213
214 Also, tags without matching ending tags like `<img/>` render properly.
85b59cb @bminer Initial commit
authored May 4, 2012
215
216 ### Indenting
217
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
218 It works. You can indent with any number of spaces or with a single tab character. The
219 only rule is to be consistent within a given file.
13f77d1 @bminer Updated docs
authored May 5, 2012
220 Jade gives you a lot of weird indent flexibility. Blade, by design, does not.
85b59cb @bminer Initial commit
authored May 4, 2012
221
222 ```
223 html
224 head
225 body
226 #content
227 ```
228
229 renders as:
230
231 ```html
232 <html><head></head><body><div id="content"></div></body></html>
233 ```
234
937cd81 @bminer Blade now supports escaped tag names by preceding the tag with a back…
authored May 17, 2012
235 You can start a tag name with a bashslash to escape Blade keywords.
236 Normally, `include test` would include a file, but `\include test` renders as:
237
238 ```xml
239 <include>test</include>
240 ```
241
242 This allows you to be flexible with tag names, so you are not restricted to rendering
243 HTML, for example. You can render any XML document with Blade.
244
85b59cb @bminer Initial commit
authored May 4, 2012
245 ### Text
246
247 It works, too. Simply place content after the tag like this:
248
249 ```
250 p This text is "escaped" by default. Kinda neat.
251 ```
252
253 renders as:
254
255 ```html
256 <p>This text is &quot;escaped&quot; by default. Kinda neat.</p>
257 ```
258
259 Want unescaped text? Large blocks of text? Done.
9631381 @bminer Updated documentation
authored May 21, 2012
260 Start a line of text with a `|`.
85b59cb @bminer Initial commit
authored May 4, 2012
261
262 ```
263 p! This will be <strong>unescaped</strong> text.
264 |
4acf322 @bminer Updated docs
authored May 4, 2012
265 How about a block? (this is "escaped", btw)
85b59cb @bminer Initial commit
authored May 4, 2012
266 Yep. It just works!
267 Neato.
268 ```
269
270 renders as:
271
272 ```html
273 <p>This will be <strong>unescaped</strong> text.
4acf322 @bminer Updated docs
authored May 4, 2012
274 How about a block? (this is &quot;escaped&quot;, btw)
85b59cb @bminer Initial commit
authored May 4, 2012
275 Yep. It just works!
276 Neato.</p>
277 ```
278
4acf322 @bminer Updated docs
authored May 4, 2012
279 Rules are:
280
9631381 @bminer Updated documentation
authored May 21, 2012
281 - Text is escaped by default.
5899bbb @bminer Updated docs
authored May 4, 2012
282 - Want unescaped text? Precede with a `!`
9631381 @bminer Updated documentation
authored May 21, 2012
283 - Precede with a `=` to evaluate and output some JavaScript.
5899bbb @bminer Updated docs
authored May 4, 2012
284 - Large text block? Use `|` and indent properly.
285 - Unescaped text block? Use `|!` or even just `!` works.
9631381 @bminer Updated documentation
authored May 21, 2012
286 - JavaScript code block? Use `|=` or even just `=` works.
287 - Unescaped JavaScript code block? Yep. Use `|!=` or `!=`.
288 - Newlines in text blocks are preserved.
4acf322 @bminer Updated docs
authored May 4, 2012
289
859e6d9 @bminer Implemented variable interpolation for text blocks (fixes issue #6)
authored May 9, 2012
290 Variable interpolation is supported for text blocks. Use `#{var_name}` notation, and
291 anything between the curly braces is treated as vanilla JavaScript code.
292
293 For example, you can write:
294
b2cba0f @bminer I need to learn how to count
authored May 17, 2012
295 (caution: indents are **required** on line 4 even though it is blank)
29415fb @bminer Clarified text section
authored May 17, 2012
296
859e6d9 @bminer Implemented variable interpolation for text blocks (fixes issue #6)
authored May 9, 2012
297 ```
298 p
299 |
300 I am just testing #{whatever + ", alright?"}
301
302 Relax...
303 ```
304
305 instead of writing the equivalent, but arguably less awesome...
306
307 ```
308 p
309 |=
310 "I am just testing " + whatever + ", alright?" +
311 "\n\n" +
312 "Relax..."
313 ```
314
9631381 @bminer Updated documentation
authored May 21, 2012
315 Assuming a local variable `whatever` is passed to the template with value "Blade",
859e6d9 @bminer Implemented variable interpolation for text blocks (fixes issue #6)
authored May 9, 2012
316 both of the examples above will render to this:
317
318 ```html
319 <p>I am just testing Blade, alright?
320
321 Relax...</p>
322 ```
323
324
ed65995 @bminer Updated docs
authored May 5, 2012
325 ### Text filters
85b59cb @bminer Initial commit
authored May 4, 2012
326
10ba04e @bminer Updated docs
authored May 4, 2012
327 Need `<br/>` tags inserted? Use a built-in filter, perhaps?
85b59cb @bminer Initial commit
authored May 4, 2012
328
329 ```
330 p
331 :nl2br
332 How about some text with some breaks?
333
334 Yep! It works!
335 ```
336
337 renders as:
338
339 ```html
340 <p>How about some text with some breaks?<br/><br/>Yep! It works!</p>
341 ```
342
ed65995 @bminer Updated docs
authored May 5, 2012
343 Built-in text filters include:
c09970e @bminer Updated readme
authored May 4, 2012
344
3011f92 @bminer Fixed bug with nl2br filter to escape text beforehand.
authored May 14, 2012
345 - :nl2br - Escapes the content and converts newline characters to `<br/>`
f8a7895 @bminer Updated docs
authored May 5, 2012
346 - :cdata - Surrounds text like this: `<![CDATA[` ...text goes here... `]]>`
347 Text should not contain `]]>`.
348 - :markdown (must have [markdown-js](https://github.com/evilstreak/markdown-js) installed)
349 - :md (alias for :markdown)
fdc7fdb @bminer Updated list of text filters
authored Jun 8, 2012
350 - :javascript - Generates a `<script>` tag for your JavaScript code. If `minify` compiler
351 option is set and UglifyJS is installed, your code is uglified automatically.
352 - :js (alias for :javascript)
3011f92 @bminer Fixed bug with nl2br filter to escape text beforehand.
authored May 14, 2012
353 - :coffeescript - Generates a `<script>` tag for the generated JavaScript.
354 (must have [coffee-script](https://github.com/jashkenas/coffee-script) installed)
355 - :cs (alias for :coffeescript)
fdc7fdb @bminer Updated list of text filters
authored Jun 8, 2012
356 - :stylus - Generates a `<style>` tag for the generated CSS. If `minify` compiler
357 option is set, your CSS is compressed automatically.
3011f92 @bminer Fixed bug with nl2br filter to escape text beforehand.
authored May 14, 2012
358 (must have [stylus](https://github.com/LearnBoost/stylus) installed)
359 - :less - Generates a `<style>` tag for the generated CSS.
360 (must have [less](https://github.com/cloudhead/less.js) installed)
361 - :sass - Generates a `<style>` tag for the generated CSS.
362 (must have [sass](https://github.com/visionmedia/sass.js) installed)
ed65995 @bminer Updated docs
authored May 5, 2012
363
364 Filters are essentially functions that accept a text string and return HTML. They
3011f92 @bminer Fixed bug with nl2br filter to escape text beforehand.
authored May 14, 2012
365 cannot modify the AST directly. Also, you cannot inject JavaScript code into
366 filters.
85b59cb @bminer Initial commit
authored May 4, 2012
367
3011f92 @bminer Fixed bug with nl2br filter to escape text beforehand.
authored May 14, 2012
368 You can add custom filters at compile-time using the API.
85b59cb @bminer Initial commit
authored May 4, 2012
369
7ffc0f0 @bminer * Fixed a bug with variable interpolation
authored May 17, 2012
370 Variable interpolation is supported for certain text filters, as well. If a text
371 filter returns text in `#{var_name}` notation, then anything between the curly braces
372 is replaced with vanilla JavaScript code. To avoid this behavior, text filters can
373 either escape the `#{stuff}` with a backslash, or it can set its `interpolation`
374 property to `false`.
375
fcbd7f0 @bminer Updated docs
authored May 4, 2012
376 ### Code
377
9631381 @bminer Updated documentation
authored May 21, 2012
378 Use dash (`-`) to indicate that JavaScript code follows, which will not output into
379 the template. As before, use equals (`=`) to specify code output. A few examples, please?
fcbd7f0 @bminer Updated docs
authored May 4, 2012
380
9631381 @bminer Updated documentation
authored May 21, 2012
381 Using dash (`-`):
fcbd7f0 @bminer Updated docs
authored May 4, 2012
382
383 ```
384 #taskStatus
385 - if(task.completed)
386 p You are done. Do more! >:O
387 - else
388 p Get to work, slave!
389 ```
390
9631381 @bminer Updated documentation
authored May 21, 2012
391 When inserting lines of code with `-`, curly braces or semicolons are inserted, as
392 appropriate. In the example above, we have an `if` statement followed by an indented
393 paragraph tag. In this case, Blade wraps the indented content with curly braces.
394 If there is no indented content beneath the line of code, then a semicolon is appended
395 instead.
396
397 Code that outputs (i.e. a code block or at the end of a tag).
398 As mentioned before, it's just like a text block, except with an `=`.
fcbd7f0 @bminer Updated docs
authored May 4, 2012
399
400 ```
401 #taskStatus= task.completed ? "Yay!" : "Awww... it's ok."
402 p
403 | The task was due on
9631381 @bminer Updated documentation
authored May 21, 2012
404 |= task.dueDate
fcbd7f0 @bminer Updated docs
authored May 4, 2012
405 ```
406
407 When using code that outputs, the default is to escape all text. To turn off escaping, just
408 prepend a "!", as before:
409
410 ```
411 p
9631381 @bminer Updated documentation
authored May 21, 2012
412 |!= some_var_containing_html
fcbd7f0 @bminer Updated docs
authored May 4, 2012
413 ```
414
9631381 @bminer Updated documentation
authored May 21, 2012
415 Missing "|" characters are okay, too. Just don't forget that stuff after the "="
416 needs to be valid JavaScript code!
fcbd7f0 @bminer Updated docs
authored May 4, 2012
417
418 ```
419 p
9631381 @bminer Updated documentation
authored May 21, 2012
420 = "escape me" + " away & away"
fcbd7f0 @bminer Updated docs
authored May 4, 2012
421 ```
422
39d7d58 @bminer Updated docs again and again and again
authored May 4, 2012
423 renders `<p>escape me away &amp; away</p>`
fcbd7f0 @bminer Updated docs
authored May 4, 2012
424
f8a7895 @bminer Updated docs
authored May 5, 2012
425 #### Variable names to avoid
426
427 Blade, like other template engines, defines local variables within every single view. You
428 should avoid using these names in your view templates whenever possible:
429
430 - `locals`
431 - `cb`
432 - `__` (that's two underscores)
433 - Any of the compiler options (i.e. `debug`, `minify`, etc.)
434
fcbd7f0 @bminer Updated docs
authored May 4, 2012
435 ### Doctypes
436
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
437 Don't forget a doctype! Actually, you can, whatever...
fcbd7f0 @bminer Updated docs
authored May 4, 2012
438
d4cdf9f @bminer Updated docs
authored May 5, 2012
439 Add a doctype using the `doctype` keyword or `!!!` like this:
fcbd7f0 @bminer Updated docs
authored May 4, 2012
440
441 `!!! 5` means use HTML 5 doctype.
442
443 Use the list of built-in doctypes or pass your own like this:
444
445 ```
dd984d6 @bminer Fixed doctype bug (fixes #19)
authored May 17, 2012
446 doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
447 html
fcbd7f0 @bminer Updated docs
authored May 4, 2012
448 ```
449
dd984d6 @bminer Fixed doctype bug (fixes #19)
authored May 17, 2012
450 which renders as `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"><html></html>`
fcbd7f0 @bminer Updated docs
authored May 4, 2012
451
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
452 Put the doctype at the top of your Blade files, please. Please refer to [doctypes.js]
453 (https://github.com/bminer/node-blade/blob/master/lib/doctypes.js) for the list of built-in
454 doctypes.
fcbd7f0 @bminer Updated docs
authored May 4, 2012
455
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
456 You can modify the list of built-in doctypes through the API, if you insist.
fcbd7f0 @bminer Updated docs
authored May 4, 2012
457
458 ### Comments
459
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
460 Use `//` for a line comment. Use `//-` if you don't want the comment to be rendered.
461 Block comments work, too.
fcbd7f0 @bminer Updated docs
authored May 4, 2012
462
463 ```
464 //Comment example 1
465 //-Comment example 2
466 //
467 #wow
468 p Block comments work, too
469 ```
470
471 renders as:
472
473 ```html
474 <!--Comment example 1--><!--<div id="wow"></div><p>Block comments work, too</p>-->
475 ```
476
477 Conditional comments work like this:
478
479 ```
480 head
481 //if lt IE 8
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
482 script(src="/dear-microsoft-plz-stop-making-browsers-kthxbye.js")
fcbd7f0 @bminer Updated docs
authored May 4, 2012
483 ```
484
485 renders as:
486
487 ```html
012e13a @bminer Updated docs and added some keywords to the package.json file
authored Aug 7, 2012
488 <head><!--[if lt IE 8]><script src="/dear-microsoft-plz-stop-making-browsers-kthxbye.js"></script><![endif]--></head>
fcbd7f0 @bminer Updated docs
authored May 4, 2012
489 ```
490
9631381 @bminer Updated documentation
authored May 21, 2012
491 To comment out entire sections of Blade code, you can use non-rendering block comments
492 with a text block.
493
494 ```
495 //-
496 |
497 anything can go here... Blade code, JavaScript code, whatever...
498 just make sure that the indenting is right.
499 ```
500
1e0771b @bminer Added support for c-style block comments. Added tests and updated doc…
authored Jun 13, 2012
501 or... even better... just use C-style block comments. Begin with `/*` to generate
502 a non-rendering block comment, or begin with `/**` to generate a regular comment.
503 End the comment with `*/`. These comments are not parsed like `//` comments.
504
505 ```
506 /* h1 Testing */
507 /**
508 #header
509 h3 Notice that this chunk of Blade code is not parsed
510 */
511 ```
512
513 renders as:
514
515 ```html
516 <!--
517 #header
518 h3 Notice that this chunk of Blade code is not parsed
519 -->
520 ```
521
5b31e36 @bminer * Added support for event handlers
authored Jul 6, 2012
522 ### Event Handlers
523
524 You can write event handlers right into your Blade templates. Here's an
525 example:
526
527 ```
528 form(method="post" action="/login")
529 input(type="text" name="username")
530 {change}
531 //javascript code goes here
532 //this refers to this DOM element
533 //e refers to the browser's event Object
534 validate(this.value);
535 input(type="password" name="password")
536 {change}
537 checkPasswordStrength(this.value);
538 ```
539
540 The above code will automatically register the 'onchange' event handler with
541 the corresponding `input` tags.
542
543 As shown in the example, your event handler may reference `this` (the DOM
544 element that triggered the event) or `e` (the browser's event Object). Be
545 aware that every browser's event Object might be slightly different,
546 especially in legacy browsers. In addition, if you are rendering the template
547 in the browser (i.e. using client-side templates), your event handler will
548 have access to the view's locals.
549
4acf322 @bminer Updated docs
authored May 4, 2012
550 ### Functions
551
552 Functions are reusable mini-templates. They are similar to 'mixins' in Jade.
553
554 Defining a function:
555
556 ```
557 function textbox(name, value)
558 input(type="text", name=name, value=value)
559 ```
560
561 Calling a function and inserting into template structure:
562
563 ```
564 form
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
565 call textbox("firstName", "Blake")
4acf322 @bminer Updated docs
authored May 4, 2012
566 ```
567
568 Or... maybe just putting the generated HTML into a variable?
569
570 ```
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
571 call textbox("firstName", "Blake") > text
572 //alternative syntax: call text = textbox("firstName", "Blake")
4acf322 @bminer Updated docs
authored May 4, 2012
573 form
574 !=text
575 ```
576
10ba04e @bminer Updated docs
authored May 4, 2012
577 Both examples would render:
578
579 ```html
580 <form><input type="text" name="firstName" value="Blake"/></form>
581 ```
582
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
583 You can also append content rendered by a function to a variable:
584 `call textbox("firstName", "Blake") >> text`
585 or... alternatively...
586 `call text += textbox("firstName", "Blake")`
587
7bdffc9 @bminer Massive compiler and runtime re-work to properly support blocks and o…
authored May 10, 2012
588 Note: when you define a block (see below) within a function, and you output the rendered
589 content to a variable, the block will be destroyed immediately after the function call.
590
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
591 Yes, you can use `arguments` within your function, just like a "real" JavaScript function.
592 In fact, functions are "real" JavaScript functions, so even closures work! Although, remember
593 that functions have access to the variables in scope at the time the function was defined, not
594 the variables in scope when the function is called.
595
596 Example:
597
598 ```
599 - var x = 12;
600 function test(foo)
601 h1=foo
602 - if(x)
603 p=x
604 #example
605 call test("Header")
606 ```
607
fe10ea5 @bminer Updated docs
authored May 8, 2012
608 would render: `<div id="example"><h1>Header</h1><p>12</p></div>`
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
609
610 #### Adding classes or an id to rendered function content
611
612 Yes, you can add a class name or id to the first element rendered by a function:
613
614 ```
615 function dialog(msg)
616 .dialog
617 = msg
618 call dialog("Blade is awesome")#foobar.foo.bar
619 ```
620
621 which would render as `<div id="foobar" class="dialog foo bar">Blade is awesome</div>`.
622
623 Although, if you try it with something like this, you get an error because the first
624 child rendered by the function is not a tag.
625
626 ```
627 function dialog(msg)
628 = msg
629 call dialog("Blade is awesome")#foobar.foo.bar
9631381 @bminer Updated documentation
authored May 21, 2012
630 //compiler might generate an error, or it might just ignore the id and classes
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
631 ```
4acf322 @bminer Updated docs
authored May 4, 2012
632
633 ### Dynamic file includes
634
635 `include "file.blade"`
636
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
637 This will insert "file.blade" right into the current view at runtime, as if the contents
638 of the included file were copied right into the current view.
4acf322 @bminer Updated docs
authored May 4, 2012
639
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
640 If you don't know the name of the file to be included until runtime, that's no problem.
641 The include statement can also be followed by the name of a JavaScript variable
642 containing the filename to be included. These are called *dynamic filename includes*.
d4e2d8d @bminer Updated docs
authored May 8, 2012
643
644 ```
645 - var filename = "file.blade"
646 include filename
647 ```
648
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
649 **CAUTION:** When using *dynamic filename includes* in the browser, be sure that you
650 have properly loaded all views that might be included into the browser's cache before
651 executing the view containing the *dynamic filename include*. See the [implementation
652 details](#fileIncludeDetails) for a more detailed explanation.
653
7f781fb @bminer Updated docs
authored May 21, 2012
654 If you do not specifiy a file extension, `.blade` will be appended to your string
655 internally.
656
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
657 You may also place an `include` inside of a `function`, `block`, or `chunk`.
658
659 Finally, you can specify which local variables should be passed to the included view
660 template by using the `exposing` keyword. By default, Blade will pass the parent's
661 local variables to the included template; however, when using the `exposing` keyword,
662 you can specify exactly which variables are to be exposed to the included template.
663
664 For example:
665
666 ```
667 - header = "Header: 1, 2, 3"
668 - text = "This is some text: 1, 2, 3"
669 - for(var i = 0; i < 10; i++)
670 include "foobar" exposing i, text
671 ```
672
673 In the example above, variables `i` and `text` are exposed to "foobar.blade";
674 the `header` variable will not be accessible from "foobar.blade".
c9a8f92 @bminer Compiler now throws an Error when include statements are placed insid…
authored May 30, 2012
675
3a87c0f @bminer Updated docs
authored May 5, 2012
676 ### Blocks
4acf322 @bminer Updated docs
authored May 4, 2012
677
3a87c0f @bminer Updated docs
authored May 5, 2012
678 Blocks allow you to mark places in your template with code that may or may not be
4acf322 @bminer Updated docs
authored May 4, 2012
679 rendered later.
680
3a87c0f @bminer Updated docs
authored May 5, 2012
681 You can do a lot with blocks, including template inheritance, etc. They behave quite
682 differently from Jade.
683
684 There are two types of blocks: regular blocks and parameterized blocks.
685
686 #### Regular blocks
687
688 Regular blocks are defined using the "block" keyword followed by a block name. Then,
689 you optionally put indented block content below. Like this:
690
691 ```
692 block regular_block
693 h1 Hello
694 p This is a test
695 ```
696
697 Assuming nothing else happens to the block, it will be rendered as
698 `<h1>Hello</h1><p>This is a test</p>` as expected. Empty blocks are also permitted.
699 A simple, empty block looks like this: `block block_name`
700
701 Of course, the purpose of declaring/defining a block is to possibly modify it later.
702 You can modify a block using three different commands:
703
4acf322 @bminer Updated docs
authored May 4, 2012
704 - Use the `append` keyword to append to the matching block.
705 - Use the `prepend` keyword to prepend to the matching block.
d4cdf9f @bminer Updated docs
authored May 5, 2012
706 - Use the `replace` keyword to replace the matching block.
4acf322 @bminer Updated docs
authored May 4, 2012
707
3a87c0f @bminer Updated docs
authored May 5, 2012
708 Example:
709
710 ```
711 append regular_block
712 p This is also a test
713 ```
714
715 #### Replacing a block
716
717 Replacing a block is somewhat confusing, so I will explain further. If you replace
718 a block, you are not changing the location of the defined block; you are only
719 replacing the content of the block at its pre-defined location. If you want to change
c1b4891 @bminer Updated docs
authored May 21, 2012
720 the location of a block, simply re-define a new block ([see below]
721 (#what-happens-if-i-define-the-same-block-more-than-once)).
3a87c0f @bminer Updated docs
authored May 5, 2012
722
723 In addition, when you replace a block, all previously appended and prepended content is
724 lost. The behavior is usually desired, but it can sometimes be a source of confusion.
725
824ace1 @bminer -Fixed a bug in the compiler - blocks, func, and chunks referenced th…
authored May 26, 2012
726 If you replace a parameterized block (described below) with a regular block, you cannot
727 call "render" on that block.
3a87c0f @bminer Updated docs
authored May 5, 2012
728
824ace1 @bminer -Fixed a bug in the compiler - blocks, func, and chunks referenced th…
authored May 26, 2012
729 You can replace a regular block with a parameterized block (described below). This will
730 also clear the contents of the block, as expected.
3a87c0f @bminer Updated docs
authored May 5, 2012
731
732 #### Parameterized blocks
733
734 The other type of block is called a parameterized block, and it looks like this:
735
736 ```
824ace1 @bminer -Fixed a bug in the compiler - blocks, func, and chunks referenced th…
authored May 26, 2012
737 block param_block_yo(headerText, text)
3a87c0f @bminer Updated docs
authored May 5, 2012
738 h1= headerText
739 p= text
740 ```
741
742 Parameterized blocks do not render automatically because they require parameters.
743 Therefore, assuming nothing else happens to the block, the block will not be rendered
744 at all.
745
746 To render a block, use the "render" keyword like this:
747
748 ```
824ace1 @bminer -Fixed a bug in the compiler - blocks, func, and chunks referenced th…
authored May 26, 2012
749 render param_block_yo("Some header text", 'Some "paragraph" text')
3a87c0f @bminer Updated docs
authored May 5, 2012
750 ```
751
752 Now, assuming nothing else happens to the block, the block will be rendered as:
753
754 ```html
755 <h1>Some header text</h1><p>Some &quot;paragraph&quot; text</p>
756 ```
757
824ace1 @bminer -Fixed a bug in the compiler - blocks, func, and chunks referenced th…
authored May 26, 2012
758 You can `render` as many times as you wish, and by default, the rendered content will
759 be appended to the block. You can also prepend the rendered content to the block or
760 replace the contents of the block with rendered content. Here are the variations:
761
762 - `render param_block_yo("Some header text", 'Some "paragraph" text')`
763 - `render append param_block_yo("Some header text", 'Some "paragraph" text')`
764 (same as above)
765 - `render prepend param_block_yo("Some header text", 'Some "paragraph" text')`
766 - `render replace param_block_yo("Some header text", 'Some "paragraph" text')`
767
768 Parameterized blocks are really cool because regular "append", "prepend", and "replace"
769 all work, too. Just remember that order matters.
3a87c0f @bminer Updated docs
authored May 5, 2012
770
771 Another example:
4acf322 @bminer Updated docs
authored May 4, 2012
772
773 ```
774 head
775 block header(pageTitle)
776 title= pageTitle
777 body
778 h1 Hello
779 render header("Page Title")
780 append header
31bbe89 @bminer Added uglify-js support when `tmpl.toString()` is called (solves issue
authored May 10, 2012
781 script(type="text/javascript")
782 render header("Page Title")
4acf322 @bminer Updated docs
authored May 4, 2012
783 prepend header
784 meta
785 ```
786
787 Will output:
788
39d7d58 @bminer Updated docs again and again and again
authored May 4, 2012
789 ```html
4acf322 @bminer Updated docs
authored May 4, 2012
790 <head>
791 <meta/>
792 <title>Page Title</title>
31bbe89 @bminer Added uglify-js support when `tmpl.toString()` is called (solves issue
authored May 10, 2012
793 <script type="text/javascript"></script>
794 <title>Page Title</title>
4acf322 @bminer Updated docs
authored May 4, 2012
795 </head>
796 <body>
797 <h1>Hello</h1>
798 </body>
799 ```
800
d4cdf9f @bminer Updated docs
authored May 5, 2012
801 #### What happens if I define the same block more than once?
4acf322 @bminer Updated docs
authored May 4, 2012
802
3a87c0f @bminer Updated docs
authored May 5, 2012
803 You can re-define a block that has already been defined with another "block"
804 statement. This completely destroys the previously defined block.
805 Previously executed "append", "prepend", "replace", and "render" blocks do not affect the
806 re-defined block.
4acf322 @bminer Updated docs
authored May 4, 2012
807
3a87c0f @bminer Updated docs
authored May 5, 2012
808 In summary...
4acf322 @bminer Updated docs
authored May 4, 2012
809
3a87c0f @bminer Updated docs
authored May 5, 2012
810 - Use the `block` keyword to mark where the block will go (block definition).
811 - Use the `render` keyword to render the matching "parameterized" block.
812 Do not use this on a regular block.
813 - Use the `append` keyword to append to the matching block.
814 - Use the `prepend` keyword to prepend to the matching block.
815 - Use the `replace` keyword to replace the matching block.
4acf322 @bminer Updated docs
authored May 4, 2012
816
31bbe89 @bminer Added uglify-js support when `tmpl.toString()` is called (solves issue
authored May 10, 2012
817 You may not render, append to, prepend to, or replace undefined blocks. If you do so,
818 an error message will occur.
b502222 @bminer Initial commit. Bump to version 0.5.
authored May 6, 2012
819
7bdffc9 @bminer Massive compiler and runtime re-work to properly support blocks and o…
authored May 10, 2012
820 When you define a block within a function, and you output the function's rendered
821 content to a variable, the defined block will be destroyed immediately after
822 the function call.
823
4acf322 @bminer Updated docs
authored May 4, 2012
824 ### Template Inheritance
825
3a87c0f @bminer Updated docs
authored May 5, 2012
826 There is no `extends` keyword. Just use blocks and includes:
4acf322 @bminer Updated docs
authored May 4, 2012
827
828 layout.blade:
829
830 ```
831 html
832 head
833 block title(pageTitle)
834 title=pageTitle
835 body
836 block body
837 ```
838
839 homepage.blade:
840
841 ```
842 include "layout.blade"
843 render title("Homepage")
844 replace block body
845 h1 Hello, World
846 ```
847
3a87c0f @bminer Updated docs
authored May 5, 2012
848 If you render layout.blade, you get: `<html><head></head><body></body></html>`, but if you
849 render homepage.blade, you get:
850
851 ```html
852 <html>
853 <head>
854 <title>Homepage</title>
855 </head>
856 <body>
857 <h1>Hello, World</h1>
858 </body>
859 </html>
860 ```
4acf322 @bminer Updated docs
authored May 4, 2012
861
705169d @bminer * Added `chunk` statement, which generates a function that returns HT…
authored May 21, 2012
862 ### Chunks
863
864 Chunks are simply functions that return HTML. They behave a bit differently than
865 conventional Blade functions.
866
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
867 Functions are called with `call` statements, and their rendered content is injected
868 right into a template. You can also capture the HTML they render by outputting to a
869 variable, as described above. Chunks, on the other hand, always return HTML, and they
870 cannot be called using `call` statements. The only way to render a chunk is to call it
705169d @bminer * Added `chunk` statement, which generates a function that returns HT…
authored May 21, 2012
871 via your code (see example below).
872
873 One reason you might define a chunk is to pass it to
874 [Meteor's](http://meteor.com/)
9631381 @bminer Updated documentation
authored May 21, 2012
875 [`Meteor.ui.chunk` function](http://docs.meteor.com/#meteor_ui_chunk); however,
705169d @bminer * Added `chunk` statement, which generates a function that returns HT…
authored May 21, 2012
876 chunks can be used for other purposes, as well.
9631381 @bminer Updated documentation
authored May 21, 2012
877 You can also use chunks to work with [`Meteor.ui.listChunk`]
705169d @bminer * Added `chunk` statement, which generates a function that returns HT…
authored May 21, 2012
878 (http://docs.meteor.com/#meteor_ui_listchunk).
879
880 Example:
881
882 ```
883 chunk header(text)
884 h1= text
885
886 != __.chunk.header("Hello")
887 ```
888
889 The above example defines a named chunk `header` with one parameter. Then, the chunk
890 is called by calling the `__.chunk.header` function. When defining a chunk, parameters
891 are optional, and if you omit the name, the chunk is simply named `last`.
892
893 Another example:
894
895 ```
896 chunk
897 h1 Hello!
898 div
899 != __.chunk.last()
900 ```
901
902 renders as `<div><h1>Hello!</h1></div>`
903
904 If you override the `templateNamespace` compiler option, you will need to replace all
905 instances of the double underscore (`__`) variable with the `templateNamespace` variable.
906
85b59cb @bminer Initial commit
authored May 4, 2012
907 API
908 ---
909
f8a7895 @bminer Updated docs
authored May 5, 2012
910 `var blade = require('blade');`
911
912 ### blade.compile(string, [options,] cb)
913
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
914 Compiles a Blade template from a string.
85b59cb @bminer Initial commit
authored May 4, 2012
915
916 - `string` is a string of Blade
917 - `options` include:
14a475d @bminer blade.renderFile - Remove a few reserved local variables before passi…
authored May 30, 2012
918 - `filename` - the filename being compiled (required when using [includes]
919 (#dynamic-file-includes) or the `cache` option)
6f02aef @bminer Made some changes to default compiler options for better compatibilit…
authored May 30, 2012
920 - `cache` - if true, the compiled template will be cached (defaults to false)
14a475d @bminer blade.renderFile - Remove a few reserved local variables before passi…
authored May 30, 2012
921 - `debug` - outputs debugging information to the console (defaults to false)
f8a7895 @bminer Updated docs
authored May 5, 2012
922 - `minify` - if true, Blade generates a minified template without debugging
6f02aef @bminer Made some changes to default compiler options for better compatibilit…
authored May 30, 2012
923 information (defaults to true if `cache` option is set; false, otherwise)
14a475d @bminer blade.renderFile - Remove a few reserved local variables before passi…
authored May 30, 2012
924 If [UglifyJS](https://github.com/mishoo/UglifyJS) is installed, Blade
925 may automatically compress or prettify the template depending on whether
926 `minify` is true or false.
b502222 @bminer Initial commit. Bump to version 0.5.
authored May 6, 2012
927 - `includeSource` - if true, Blade inserts the Blade source file directly into
928 the compiled template, which can further improve error reporting, although
31bbe89 @bminer Added uglify-js support when `tmpl.toString()` is called (solves issue
authored May 10, 2012
929 the size of the template is increased significantly. (defaults to true if
930 and only if `process.env.NODE_ENV` is "development" and minify is false;
931 defaults to false, otherwise)
f8a7895 @bminer Updated docs
authored May 5, 2012
932 - `doctypes` - use this Object instead of `blade.Compiler.doctypes`
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
933 - `selfClosingTags` - use this array instead of `blade.Compiler.selfClosingTags`
f8a7895 @bminer Updated docs
authored May 5, 2012
934 - `filters` - use this Object instead of `blade.Compiler.filters`
31bbe89 @bminer Added uglify-js support when `tmpl.toString()` is called (solves issue
authored May 10, 2012
935 - `templateNamespace` - the name of the reserved variable in the view
936 (defaults to two underscores: __). Other reserved names are
937 [listed here](#variable-names-to-avoid)
705169d @bminer * Added `chunk` statement, which generates a function that returns HT…
authored May 21, 2012
938 - `basedir` - the base directory where Blade templates are located. This option is
939 primarily used by the Blade middleware to allow the Blade runtime to properly
940 load file includes.
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
941 - `cb` is a function of the form: `cb(err, tmpl)` where `err` contains
942 any parse or compile errors and `tmpl` is the compiled template.
f8a7895 @bminer Updated docs
authored May 5, 2012
943 If an error occurs, `err` may contain the following properties:
944 - `message` - The error message
945 - `expected` - If the error is a 'SyntaxError', this is an array of expected tokens
946 - `found` - If the error is a 'SyntaxError', this is the token that was found
947 - `filename` - The filename where the error occurred
b502222 @bminer Initial commit. Bump to version 0.5.
authored May 6, 2012
948 - `offset` - The offset in the string where the error occurred
f8a7895 @bminer Updated docs
authored May 5, 2012
949 - `line` - The line # where the error occurred
950 - `column` - The column # where the error occurred
951
b502222 @bminer Initial commit. Bump to version 0.5.
authored May 6, 2012
952 Note: if there is a problem with the Blade compiler, or more likely, if there
953 is a syntax error with the JavaScript code in your template, Node.js will not
012e13a @bminer Updated docs and added some keywords to the package.json file
authored Aug 7, 2012
954 provide any line number or other information about the error. See issue #40 for
955 more details.
b502222 @bminer Initial commit. Bump to version 0.5.
authored May 6, 2012
956
f8a7895 @bminer Updated docs
authored May 5, 2012
957 You can render a compiled template by calling the function: `tmpl(locals, cb)`
a4fcfd8 @bminer Fixed README
authored May 10, 2012
958
959 - `locals` are the local variables to be passed to the view template
960 - `cb` is a function of the form `function(err, html)` where `err` contains
f8a7895 @bminer Updated docs
authored May 5, 2012
961 any runtime errors and `html` contains the rendered HTML.
85b59cb @bminer Initial commit
authored May 4, 2012
962
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
963 In addition, a compiled template has these properties and methods:
a4fcfd8 @bminer Fixed README
authored May 10, 2012
964
965 - `template` - a function that also renders the template but accepts 3 parameters:
966 `tmpl.template(locals, runtime, cb)`. This simply allows you to use a custom
967 runtime environment, if you choose to do so.
968 - `filename` - the filename of the compiled template (if provided)
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
969 - `dependencies` - an array of files that might be included by this template at
970 runtime
971 - `unknownDependencies` - if true, this template uses *dynamic filename includes*
972 and may include any file at any time.
a4fcfd8 @bminer Fixed README
authored May 10, 2012
973 - `toString()` - a function that converts the view template function into a string
974 of JavaScript code. If you need a client-side template for example, you can
14a475d @bminer blade.renderFile - Remove a few reserved local variables before passi…
authored May 30, 2012
975 use this function. [UglifyJS](https://github.com/mishoo/UglifyJS) is now used
a4fcfd8 @bminer Fixed README
authored May 10, 2012
976 if you have it installed.
fcbd7f0 @bminer Updated docs
authored May 4, 2012
977
f8a7895 @bminer Updated docs
authored May 5, 2012
978 ### blade.compileFile(filename, [options,] cb)
85b59cb @bminer Initial commit
authored May 4, 2012
979
f8a7895 @bminer Updated docs
authored May 5, 2012
980 Asynchronously compile a Blade template from a filename on the filesystem.
85b59cb @bminer Initial commit
authored May 4, 2012
981
f8a7895 @bminer Updated docs
authored May 5, 2012
982 - `filename` is the filename
983 - `options` - same as `blade.compile` above, except `filename` option is always
705169d @bminer * Added `chunk` statement, which generates a function that returns HT…
authored May 21, 2012
984 overwritten with the `filename` specified. There is also a `synchronous`
985 option that will tell Blade to read and compile the file synchronously
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
986 instead of asynchronously.
f8a7895 @bminer Updated docs
authored May 5, 2012
987 - `cb` - same as `blade.compile` above
85b59cb @bminer Initial commit
authored May 4, 2012
988
f8a7895 @bminer Updated docs
authored May 5, 2012
989 ### blade.renderFile(filename, options, cb)
85b59cb @bminer Initial commit
authored May 4, 2012
990
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
991 Convenience function to compile a template and render it.
85b59cb @bminer Initial commit
authored May 4, 2012
992
f8a7895 @bminer Updated docs
authored May 5, 2012
993 - `filename` is the filename
994 - `options` - same as `blade.compileFile` above. This object is also passed
14a475d @bminer blade.renderFile - Remove a few reserved local variables before passi…
authored May 30, 2012
995 to the view, so it should also contain your view's local variables.
996 A few [reserved local variables](#variable-names-to-avoid) are removed
997 before passing the locals to the view.
f8a7895 @bminer Updated docs
authored May 5, 2012
998 - `cb` - a function of the form `function(err, html)`
999
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1000 ### blade.middleware(sourcePath, options)
1001
1002 Express middleware for serving compiled client-side templates to the browser.
1003 For example, if you visit the URL "/views/homepage.blade" on your server, you
1004 can compile the view stored at `sourcePath + "/homepage.blade"`
1005
1006 - `sourcePath` - the path on the server where your views are stored
1007 - `options` include:
1008 - `mount` - the URL path where you can request compiled views (defaults to
1009 "/views/")
380dbb3 @bminer Added `runtimeMount` option to Blade middleware. Closes #42
authored Jun 22, 2012
1010 - `runtimeMount` - the URL path where the minified Blade runtime is served
1011 to the browser (defaults to "/blade/blade.js"). Use `null` to disable
1012 this functionality.
cd1f989 @bminer * Added Blade plugins directory
authored Jul 6, 2012
1013 - `pluginsMount` - the URL path where Blade plugins will be served to the
1014 browser (defaults to "/blade/plugins/"). Use `null` to disable this
1015 functionality.
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1016 - `compileOptions` - options passed to `blade.compile()`. Defaults to:
1017
1018 ```javascript
1019 {
1020 'cache': process.env.NODE_ENV == "production",
1021 'minify': process.env.NODE_ENV == "production",
1022 'includeSource': process.env.NODE_ENV == "development"
1023 };
1024 ````
1025
f8a7895 @bminer Updated docs
authored May 5, 2012
1026 ### blade.Compiler
1027
1028 The compiler itself. It has some useful methods and properties.
1029
1030 ### blade.Compiler.parse(string)
1031
1032 Just generates the parse tree for the string. For debugging purposes only.
85b59cb @bminer Initial commit
authored May 4, 2012
1033
ed73626 @bminer Added `filename` property to the compiled template wrapper function
authored May 8, 2012
1034 Example using the API:
1035
85b59cb @bminer Initial commit
authored May 4, 2012
1036 ```javascript
1037 var blade = require('blade');
f8a7895 @bminer Updated docs
authored May 5, 2012
1038 blade.compile("string of blade", options, function(err, tmpl) {
1039 tmpl(locals, function(err, html) {
1040 console.log(html);
1041 });
1042 });
85b59cb @bminer Initial commit
authored May 4, 2012
1043 ```
1044
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1045 Here is a sample Express application that uses Blade for server-side and client-side
1046 templates:
1047
1048 ```javascript
1049 var express = require('express'),
1050 blade = require('blade');
1051 var app = express.createServer();
012e13a @bminer Updated docs and added some keywords to the package.json file
authored Aug 7, 2012
1052 app.use(blade.middleware(__dirname + '/views') ); //for client-side templates
1053 app.use(express.static(__dirname + "/public") ); //maybe we have some static files
1054 app.set('views', __dirname + '/views'); //tells Express where our views are stored
1055 app.set('view engine', 'blade'); //Yes! Blade works with Express out of the box!
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1056 app.get('/', function(req, res, next) {
1057 res.render('homepage');
1058 });
1059 app.listen(8000);
1060 ```
1061
1062 Browser Usage
1063 -------------
1064
012e13a @bminer Updated docs and added some keywords to the package.json file
authored Aug 7, 2012
1065 The Blade runtime should work on every browser, and since Blade provides an
1066 Express middleware for serving compiled templates to the browser ([see above]
1067 (#blademiddlewaresourcepath-options)), rendering Blade templates in the browser
1068 is a breeze.
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1069
1070 Once you have the middleware setup, you can now serve your compiled Blade views
4a07608 @bminer * Blade middleware now uses client caching by default.
authored Jun 28, 2012
1071 to the client. Simply include the /blade/blade.js file in your `<script>`
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1072 tags, and then call `blade.runtime.loadTemplate`.
1073
4a07608 @bminer * Blade middleware now uses client caching by default.
authored Jun 28, 2012
1074 ### blade.runtime.loadTemplate(filename, cb)
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1075
1076 - `filename` - the filename of the view you wish to retrieve, relative to the
1077 `sourcePath` you setup in the Blade middleware.
205c70e @bminer Improved runtime environment to make the client-side API a bit cleaner
authored May 14, 2012
1078 - `cb` - your callback of the form `cb(err, tmpl)` where `tmpl` is your compiled
1079 Blade template. Call the template like this:
1080 `tmpl(locals, function(err, html) {...});`
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1081
4a07608 @bminer * Blade middleware now uses client caching by default.
authored Jun 28, 2012
1082 Your template will be stored in `blade.cachedViews` and will be cached until the
1083 user reloads the page or navigates to another page.
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1084
1085 Yes, included files work, too. Like magic.
1086
1087 Example client-side JavaScript:
1088
1089 ```javascript
205c70e @bminer Improved runtime environment to make the client-side API a bit cleaner
authored May 14, 2012
1090 blade.runtime.loadTemplate("homepage.blade", function(err, tmpl) {
1091 tmpl({'users': ['John', 'Joe']}, function(err, html) {
a307fc3 @bminer Changed how files were included to better support client-side templates
authored May 11, 2012
1092 console.log(html); //YAY! We have rendered HTML
1093 });
1094 });
1095 ```
1096
205c70e @bminer Improved runtime environment to make the client-side API a bit cleaner
authored May 14, 2012
1097 As a side note, you can override the `blade.runtime.loadTemplate` function with
1098 your own implementation.
1099
57fd2d1 @bminer Push to version 1.0
authored May 18, 2012
1100 Simple Example
1101 --------------
1102
1103 The following Blade document ...
1104
1105 ```blade
1106 !!! 5
1107 html
1108 head
1109 title Blade
1110 body
1111 #nav
1112 ul
1113 - for(var i in nav)
1114 li
1115 a(href=nav[i])= i
1116 #content.center
1117 h1 Blade is cool
1118 ```
1119
1120 ... compiles to this JavaScript function ...
1121
1122 ```javascript
8d57948 @bminer Updated compiled template example
authored May 19, 2012
1123 function tmpl(locals,cb,__){var __=__||[];__.r=__.r||blade.runtime,__.blocks=__.blocks||{},__.func=__.func||{},__.locals=locals||{};with(__.locals){__.push("<!DOCTYPE html>","<html",">","<head",">","<title",">",__.r.escape("Blade"),"</title>","</head>","<body",">","<div",' id="nav"',">","<ul",">");for(var i in nav)__.push("<li",">","<a"),__.r.attrs({href:{val:nav[i],escape:!0}},__,this),__.push(">",__.r.escape(i),"</a>","</li>");__.push("</ul>","</div>","<div",' id="content"',' class="center"',">","<h1",">",__.r.escape("Blade is cool"),"</h1>","</div>","</body>","</html>"),__.inc||__.r.done(__)}cb(null,__.join(""),__)}
57fd2d1 @bminer Push to version 1.0
authored May 18, 2012
1124 ```
1125
1126 ... now you call the function like this...
1127
1128 ```javascript
1129 tmpl({
1130 'nav': {
0d9e6c0 @bminer Fixed typos
authored May 18, 2012
1131 'Home': '/',
57fd2d1 @bminer Push to version 1.0
authored May 18, 2012
1132 'About Us': '/about',
1133 'Contact': '/contact'
1134 }
1135 }, function(err, html) {
1136 if(err) throw err;
1137 console.log(html);
1138 });
1139 ```
1140
1141 ... and you get this:
1142
1143 ```html
1144 <!DOCTYPE html>
1145 <html>
1146 <head>
1147 <title>Blade</title>
1148 </head>
1149 <body>
1150 <div id="nav">
1151 <ul>
1152 <li><a href="/">Home</a></li>
1153 <li><a href="/about">About Us</a></li>
1154 <li><a href="/contact">Contact</a></li>
1155 </ul>
1156 </div>
1157 <div id="content" class="center">
1158 <h1>Blade is cool</h1>
1159 </div>
1160 </body>
1161 </html>
1162 ```
1163
bb83b87 @bminer * Updated documentation for plugins (closes #56)
authored Jul 10, 2012
1164 Plugins
1165 -------
1166
06f4008 @bminer * Updated changelog and documentation
authored Jul 17, 2012
1167 **Live UI**
bb83b87 @bminer * Updated documentation for plugins (closes #56)
authored Jul 10, 2012
1168
1169 Blade provides a Live UI plugin that allows Blade to support live binding. Live binding
1170 provides automatic two-way synchronization between your models and views on a given web
1171 page. That is, when data in your Model is updated, the rendered Blade views on the
1172 client's browser are automatically updated with the new content, and similarly, when a
1173 Blade view is rendered in the browser, the Blade [event handlers](#event-handlers) can
1174 update data in the model.
1175
012e13a @bminer Updated docs and added some keywords to the package.json file
authored Aug 7, 2012
1176 **Complete documentation for the Live UI plugin (including several examples)
1177 can be found on the [Live UI Plugin wiki page]
1178 (https://github.com/bminer/node-blade/wiki/Live-UI-Blade-Plugin).**
bb83b87 @bminer * Updated documentation for plugins (closes #56)
authored Jul 10, 2012
1179
1180 Eventually, the Live UI plugin might live in a separate repository and work for any
1181 templating language.
1182
06f4008 @bminer * Updated changelog and documentation
authored Jul 17, 2012
1183 **definePropertyIE8**
bb83b87 @bminer * Updated documentation for plugins (closes #56)
authored Jul 10, 2012
1184
1185 This plugin is a prerequisite for the Live UI plugin if you plan on using Live UI in
1186 Internet Explorer 8.
1187
1188 Meteor Support
1189 --------------
1190
1191 Blade also provides a [Meteor smart package](http://docs.meteor.com/#smartpackages)
1192 under the `meteor` directory. At the time of this writing, Blade is not a part of the
1193 Meteor core smart package list. The easiest thing to do right now is to symlink that
1194 directory into your Meteor packages directory like this:
1195
1196 `ln -s /path/to/.../blade/meteor /path/to/.../meteor/packages/blade`
1197
1198 Of course, the actual path where Blade and Meteor are installed on your system may vary.
1199 You need to replace the above command with the correct paths, as appropriate.
1200
1201 Then, execute `meteor add blade` in your Meteor project directory.
1202
1203 **More documentation and examples for Meteor + Blade can be found [on this wiki page]
012e13a @bminer Updated docs and added some keywords to the package.json file
authored Aug 7, 2012
1204 (https://github.com/bminer/node-blade/wiki/Using-Blade-with-Meteor).**
bb83b87 @bminer * Updated documentation for plugins (closes #56)
authored Jul 10, 2012
1205
85b59cb @bminer Initial commit
authored May 4, 2012
1206 Implementation Details
1207 ----------------------
1208
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
1209 **PEG.js**
1210
85b59cb @bminer Initial commit
authored May 4, 2012
1211 The Blade parser is built using [PEG.js](https://github.com/dmajda/pegjs).
1212 Thanks to the PEG.js team for making this project much easier than I had
0a59658 @bminer Updated docs
authored May 9, 2012
1213 anticipated! To modify the parser, simply change `./lib/parser/blade-grammer.pegjs`,
1214 and the new parser will be automatically built the next time you run tests.
1215
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
1216 **Running tests**
1217
af0907f @bminer Fixed typo
authored May 14, 2012
1218 To install all devDependencies, just do: `npm link` or install manually.
0a59658 @bminer Updated docs
authored May 9, 2012
1219 To run tests, ensure devDependencies are installed, then run: `npm test`
3a87c0f @bminer Updated docs
authored May 5, 2012
1220
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
1221 **Compiler-runtime relationship**
1222
705169d @bminer * Added `chunk` statement, which generates a function that returns HT…
authored May 21, 2012
1223 Also, I'd like to mention here that the Blade compiler and Blade runtime are rather
1224 closely coupled. Unfortunately, that means that templates compiled with an older
1225 Blade compiler might not be compatible with a newer runtime and vice versa.
1226 To avoid issues, be sure that your Blade templates were compiled with the compiler of
1227 the same version as the runtime on which they will run. If you think this is too
1228 inconvenient, please feel free to complain, but I probably will ignore you. :)
1229
00c8af7 @bminer Fixed documentation
authored Aug 7, 2012
1230 <a name="fileIncludeDetails"></a>
1231 **File Includes**
00213d3 @bminer * File includes are now synchronous and are now permitted in blocks, …
authored Jun 28, 2012
1232
1233 Included Blade templates MUST be loaded synchronously, and if this is not possible, an
1234 error will be thrown. Obviously, when rendering views on the server, this is not a
1235 problem since Node provides synchronous file system calls; however, on the client, it is
1236 only possible to include a file synchronously when the file is already in the browser's
1237 cache. When the name of the file to be included is known at compile-time (i.e. you are
1238 not using a *dynamic filename include*), the compiler will notify the Blade middleware
1239 of a particular view's dependencies. This allows the client-side template loader to
1240 also load and cache any dependent views in advance, preventing any issues from occurring.
1241 Nevertheless, when *dynamic filename includes* are used, the compiler has no way of
1242 determining which views will be included at runtime, and if a dynamically included view
1243 is not loaded into the browser's cache when the include statement is reached, the
1244 included view must be be loaded asynchronously and, as such, an error will be thrown.
1245
1246 Loading and compiling files synchronously may temporarily reduce your application's
1247 responsiveness, but because compiled views are often cached, this is not really much
1248 of an issue.
1249
82926e1 @bminer Added some implementation notes about event handlers
authored Jul 12, 2012
1250 **Event Handlers**
1251
1252 Event handlers in Blade work by injecting the event handler function as an HTML comment
1253 directly before the bound element. Then, the appropriate event attribute (i.e.
1254 onclick, onchange, etc.) on the element is set to call `blade.runtime.trigger`. The
1255 `trigger` function basically grabs the HTML comment, passes the contents through eval(),
1256 and binds the event handler directly to the element. This means that the event handlers
1257 work on templates rendered on the browser or on the server. Everything gets wired up the
1258 first time that the event occurs on the browser.
1259
1260 The Blade runtime also keeps track of any event handlers bound to a specific element
1261 by assigning each element an 'id' attribute, if necessary. When the view has
1262 finished rendering, the Blade runtime will pass a bunch of information (chunks, blocks,
1263 functions, or event handlers that were defined, etc.) to the 3rd (undocumented) argument
1264 of the render callback function. If you are rendering Blade templates on the browser,
1265 you can access the list of event handlers and bind the defined event handler directly
1266 to the element by looking up the element by its 'id' instead of letting the `trigger`
1267 function do its magic. The advantage of binding direclty to the defined event handler is
1268 that (thanks to closures) you can still reference the locals that were passed to your
1269 view and modify them, as needed... directly from your event handler. This allows your view
1270 code to automatically synchronize with your model, providing one-way view-to-model
1271 synchronization capabilties. Very cool! For examples of this and for more information,
1272 check out the [Live UI plugin]
1273 (https://github.com/bminer/node-blade/wiki/Live-UI-Blade-Plugin).
1274
5122cdf @bminer Added benchmarks section, but it needs improvement
authored May 14, 2012
1275 Benchmarks
1276 ----------
1277
b700146 @bminer Fixed typo
authored Jun 7, 2012
1278 See the [Benchmark wiki page](https://github.com/bminer/node-blade/wiki/Benchmarks)
4d020de @bminer Updated documentation and moved Benchmark section to the wiki
authored Jun 7, 2012
1279 for more information.
5122cdf @bminer Added benchmarks section, but it needs improvement
authored May 14, 2012
1280
3a87c0f @bminer Updated docs
authored May 5, 2012
1281 License
1282 -------
1283
eb2acf0 @bminer Added index.js and updated documentation
authored May 5, 2012
1284 See the [LICENSE.txt file](https://raw.github.com/bminer/node-blade/master/LICENSE.txt).
Something went wrong with that request. Please try again.