1 | # Haml Coffee Templates [![Build Status](https://secure.travis-ci.org/netzpirat/haml-coffee.png)](http://travis-ci.org/netzpirat/haml-coffee)
|
2 |
|
3 | Haml Coffee is a JavaScript templating solution that uses [Haml](http://haml-lang.com/) as markup, understands inline
|
4 | [CoffeeScript](http://jashkenas.github.com/coffee-script/) and generates a JavaScript function that renders to HTML. It
|
5 | can be used in client-side JavaScript applications that are using
|
6 | [Backbone.js](http://documentcloud.github.com/backbone/), [Spine.js](http://spinejs.com/),
|
7 | [JavaScriptMVC](http://javascriptmvc.com/), [KnockoutJS](http://knockoutjs.com/) and others, or on the server-side in
|
8 | frameworks like [Express](http://expressjs.com/).
|
9 |
|
10 | You can try Haml Coffee online by visiting [Haml Coffee Online](http://haml-coffee-online.herokuapp.com/).
|
11 |
|
12 | ## Installation
|
13 |
|
14 | Haml Coffee is available in NPM and can be installed with:
|
15 |
|
16 | ```bash
|
17 | $ npm install haml-coffee
|
18 | ```
|
19 |
|
20 | Please have a look at the [CHANGELOG](https://github.com/netzpirat/haml-coffee/blob/master/CHANGELOG.md) when upgrading to a
|
21 | newer Haml Coffee version with `npm update`.
|
22 |
|
23 | ## Integration
|
24 |
|
25 | There are different packages available to integrate Haml Coffee into your workflow:
|
26 |
|
27 | ### Editor
|
28 |
|
29 | * [CoffeeScriptHaml](https://github.com/jisaacks/CoffeeScriptHaml) Syntax highlighting for .hamlc files in Sublime Text.
|
30 |
|
31 | ### Node.JS
|
32 |
|
33 | * [grunt-haml](https://github.com/concordusapps/grunt-haml) for projects using [Grunt](http://gruntjs.com/).
|
34 | * [hem-haml-coffee](https://github.com/vojto/hem-haml-coffee) for projects using [Hem](https://github.com/spine/hem/).
|
35 | * [stitch-haml-coffee](https://github.com/jnbt/stitch-haml-coffee) for projects using [Stitch](https://github.com/sstephenson/stitch).
|
36 | * [Mincer](https://github.com/nodeca/mincer) the Sprockets inspired web assets compiler.
|
37 |
|
38 | ### Ruby/Rails
|
39 |
|
40 | * [haml_coffee_assets](https://github.com/netzpirat/haml_coffee_assets) for projects using Rails.
|
41 | * [guard-haml-coffee](https://github.com/ouvrages/guard-haml-coffee) for projects using [Guard](https://github.com/guard/guard).
|
42 |
|
43 | ### Browser
|
44 |
|
45 | * [Haml Coffee compiler](https://raw.github.com/netzpirat/haml-coffee/master/dist/compiler/hamlcoffee.js)
|
46 | ([minified](https://raw.github.com/netzpirat/haml-coffee/master/dist/compiler/hamlcoffee.min.js))
|
47 | for compiling in the browser.
|
48 |
|
49 | The browser distribution doesn't come bundled with CoffeeScript, so you'll have to make sure you've
|
50 | included it before requiring haml-coffee.
|
51 |
|
52 | ## Compile Haml Coffee
|
53 |
|
54 | ### Using the API
|
55 |
|
56 | You can compile a Haml Coffee template to a JavaScript function and execute the function with the locals to render the
|
57 | HTML. The following code
|
58 |
|
59 | ```coffeescript
|
60 | hamlc = require 'haml-coffee'
|
61 | tmpl = hamlc.compile '%h1= @title'
|
62 | html = tmpl title: 'Haml Coffee rocks!'
|
63 | ```
|
64 |
|
65 | will create the HTML `<h1>Haml Coffee rocks!</h1>`.
|
66 |
|
67 | The `compile` function can take the compiler options as second parameter to customize the template function:
|
68 |
|
69 | ```coffeescript
|
70 | hamlc.compile '%h1= @title'
|
71 | cleanValue: false
|
72 | escapeHtml: false
|
73 | ```
|
74 |
|
75 | See the [compiler options](#compiler-options) for detailed information about all the available options and browse
|
76 | the [codo](https://github.com/netzpirat/codo) generated
|
77 | [Haml Coffee API documentation](http://coffeedoc.info/github/netzpirat/haml-coffee/master/).
|
78 |
|
79 | ### Using with Express
|
80 |
|
81 | You can configure [Express](http://expressjs.com/) to use Haml Coffee as template engine.
|
82 |
|
83 | #### Express 3
|
84 |
|
85 | Starting with version 1.4.0, Haml Coffee has support for Express 3 and can be registered as view engine as follows:
|
86 |
|
87 | ```coffeescript
|
88 | express = require 'express'
|
89 | app = express()
|
90 |
|
91 | app.engine 'hamlc', require('haml-coffee').__express
|
92 | ```
|
93 |
|
94 | Alternatively you can also use [consolidate.js](https://github.com/visionmedia/consolidate.js) to register the engine:
|
95 |
|
96 | ```coffeescript
|
97 | express = require 'express'
|
98 | cons = require 'consolidate'
|
99 | app = express()
|
100 |
|
101 | app.engine 'hamlc', cons['haml-coffee']
|
102 | ```
|
103 |
|
104 | #### Express 2
|
105 |
|
106 | Starting with version 0.5.0, Haml Coffee has support for Express 2 and can be registered as view engine as follows:
|
107 |
|
108 | ```coffeescript
|
109 | express = require 'express'
|
110 |
|
111 | app = express.createServer()
|
112 | app.register '.hamlc', require('haml-coffee')
|
113 | ```
|
114 |
|
115 | Alternatively you can also use [consolidate.js](https://github.com/visionmedia/consolidate.js) to register the engine:
|
116 |
|
117 | ```coffeescript
|
118 | express = require 'express'
|
119 | cons = require 'consolidate'
|
120 |
|
121 | app = express.createServer()
|
122 | app.register '.hamlc', cons['haml-coffee']
|
123 | ```
|
124 |
|
125 | #### Express Usage
|
126 |
|
127 | ##### Layouts
|
128 |
|
129 | Express 2 uses a layout file `layout.hamlc` by default and you have to insert the rendered view body into the layout like
|
130 | this:
|
131 |
|
132 | ```haml
|
133 | !!!
|
134 | %head
|
135 | %title Express App
|
136 | %body
|
137 | != @body
|
138 | ```
|
139 |
|
140 | Now you can create a Haml Coffee view
|
141 |
|
142 | ```haml
|
143 | %h1= "Welcome #{ @name }"
|
144 | %p You've rendered your first Haml Coffee view.
|
145 | ```
|
146 |
|
147 | that you can render with:
|
148 |
|
149 | ```coffeescript
|
150 | app.get '/', (req, res) ->
|
151 | res.render 'index.hamlc', name: 'Express user'
|
152 | ```
|
153 |
|
154 | Express 3 has removed layout support, but you can get it back by installing
|
155 | [express-partials](https://github.com/publicclass/express-partials) and configure it as middleware:
|
156 |
|
157 | ```
|
158 | partials = require 'express-partials'
|
159 | app.use partials()
|
160 | ```
|
161 |
|
162 | ##### Default template engine
|
163 |
|
164 | It's possible to use Haml Coffee as the default template engine by setting the `view engine`:
|
165 |
|
166 | ```coffeescript
|
167 | app.configure ->
|
168 | app.set 'view engine', 'hamlc'
|
169 | ```
|
170 |
|
171 | which allows you to omit the `.hamlc` extension when rendering a template:
|
172 |
|
173 | ```coffeescript
|
174 | app.get '/', (req, res) ->
|
175 | res.render 'index', name: 'Express user'
|
176 | ```
|
177 |
|
178 | ##### Compiler options
|
179 |
|
180 | With Express 3, you can set global compiler options by using `app.locals`:
|
181 |
|
182 | ```
|
183 | app.locals.uglify = true
|
184 | ```
|
185 |
|
186 | which is the same as:
|
187 |
|
188 | ```
|
189 | res.render view, { uglify: true }
|
190 | ```
|
191 |
|
192 | See the [compiler options](#compiler-options) for detailed information about all the available options.
|
193 |
|
194 | ### Using the CLI tool
|
195 |
|
196 | After the installation you will have a `haml-coffee` binary that can be used to compile single templates and even
|
197 | compile multiple templates recursively into a single file.
|
198 |
|
199 | ```bash
|
200 | $ haml-coffee
|
201 | Usage: node haml-coffee
|
202 |
|
203 | Options:
|
204 | -i, --input Either a file or a directory name to be compiled
|
205 | -o, --output Set the output filename
|
206 | -n, --namespace Set a custom template namespace
|
207 | -t, --template Set a custom template name
|
208 | -b, --basename Ignore file path when generate the template name
|
209 | -e, --extend Extend the template scope with the context
|
210 | -r, --render Render to standalone HTML
|
211 | ```
|
212 |
|
213 | _The following section describes only the options that are unique to the command line tool._
|
214 |
|
215 | You can see all the available options by executing `haml-coffee --help` and have a look at the
|
216 | [compiler options](#compiler-options) for detailed information about all the options.
|
217 |
|
218 | The `input` and `output` are optional and you can also directly redirect the streams.
|
219 |
|
220 | #### Input filename
|
221 |
|
222 | You can either specify a single template or a directory with the `-i`/`--input` argument. When you supply a directory,
|
223 | templates are being searched recursively:
|
224 |
|
225 | ```bash
|
226 | $ haml-coffee -i template.haml
|
227 | ```
|
228 |
|
229 | This will generate a template with the same name as the file but the extension changed to `.jst`. The above command for
|
230 | example would generate a template named `template.jst`.
|
231 |
|
232 | A valid Haml Coffee template must have one of the following extensions: `.haml`, `.html.haml`, `.hamlc` or
|
233 | `.html.hamlc`.
|
234 |
|
235 | #### Output filename
|
236 |
|
237 | You can specify a single output file name to be used instead of the automatic generated output file name with the
|
238 | `-o`/`--output` argument:
|
239 |
|
240 | ```bash
|
241 | $ haml-coffee -i template.haml -o t.js
|
242 | ```
|
243 |
|
244 | This creates a template named `t.js`. You can also set a directory as input and give an output file name for
|
245 | concatenating all templates into a single file:
|
246 |
|
247 | ```bash
|
248 | $ haml-coffee -i templates -o all.js
|
249 | ```
|
250 |
|
251 | This will create all the templates under the `templates` directory into a single, combined output file `all.js`.
|
252 |
|
253 | #### Template namespace
|
254 |
|
255 | Each template will register itself by default under the `window.HAML` namespace, but you can change the namespace with
|
256 | the `-n`/`--namespace` argument:
|
257 |
|
258 | ```bash
|
259 | $ haml-coffee -i template.haml -n exports.JST
|
260 | ```
|
261 |
|
262 | #### Template name
|
263 |
|
264 | Each template must have a unique name under which it can be addressed. By default the template name is derived from the
|
265 | template file name by stripping off all extensions and remove illegal characters. Directory names are converted to
|
266 | nested namespaces under the default namespace. For example, a template named `user/show-admin.html.haml` will result in
|
267 | a template that can be accessed by `window.HAML['user/show_admin']`.
|
268 |
|
269 | Given the `-b`/`--basename` argument, the deduced template name will not include the path to the template. For example,
|
270 | a template named `user/show-admin.html.haml` will result in a template that can be accessed by
|
271 | `window.HAML['show_admin']` instead of `window.HAML['user/show_admin']`.
|
272 |
|
273 | With the `-t`/`--template` argument you can set a template name manually:
|
274 |
|
275 | ```bash
|
276 | $ haml-coffee -i template.haml -n exports.JST -t other
|
277 | ```
|
278 |
|
279 | This will result in a template that can be accessed by `exports.JST['other']`.
|
280 |
|
281 | #### Extend the template scope
|
282 |
|
283 | By extending the template scope with the context, you can access your context data without `@` or `this`:
|
284 |
|
285 | ```Haml
|
286 | %h2= title
|
287 | ```
|
288 |
|
289 | This effect is achieved by using the [with](https://developer.mozilla.org/en/JavaScript/Reference/Statements/with)
|
290 | statement. Using with is forbidden in ECMAScript 5 strict mode.
|
291 |
|
292 | #### Stream redirection
|
293 |
|
294 | You can use Haml Coffee on the command line to enter a template and stop it with `Ctrl-D`:
|
295 |
|
296 | ```bash
|
297 | $ haml-coffee -p amd
|
298 | %h1 Hello AMD
|
299 | ^D
|
300 | ```
|
301 |
|
302 | which will output the AMD module source code to the console. You either have to set the placement option to `amd` or
|
303 | give it a template name like
|
304 |
|
305 | ```bash
|
306 | $ haml-coffee -t name
|
307 | %p JST rocks!
|
308 | ^D
|
309 | ```
|
310 |
|
311 | which will output the JST source code. Now you can also redirect files like:
|
312 |
|
313 | ```bash
|
314 | $ haml-coffee -t name < input.hamlc > output.jst
|
315 | ```
|
316 |
|
317 | ## Haml support
|
318 |
|
319 | Haml Coffee implements the [Haml Spec](https://github.com/haml/haml-spec) to ensure some degree of compatibility to
|
320 | other Haml implementations and the following sections are fully compatible to Ruby Haml:
|
321 |
|
322 | * Plain text
|
323 | * Multiline: `|`
|
324 | * Element names: `%`
|
325 | * Attributes: `{}` or `()`
|
326 | * Class and ID: `.` and `#`, implicit `div` elements
|
327 | * Self-closing tags: `/`
|
328 | * Doctype: `!!!`
|
329 | * HTML comments: `/`, conditional comments: `/[]`, Haml comments: `-#`
|
330 | * Running CoffeeScript: `-`, inserting CoffeeScript: `=`
|
331 | * CoffeeScript interpolation: `#{}`
|
332 | * Whitespace preservation: `~`
|
333 | * Whitespace removal: `>` and `<`
|
334 | * Escaping `\`
|
335 | * Escaping HTML: `&=`, unescaping HTML: `!=`
|
336 | * Filters: `:plain`, `:javascript`, `:css`, `:cdata`, `:escaped`, `:preserve`
|
337 | * Boolean attributes conversion
|
338 | * Haml object reference syntax: `[]`
|
339 |
|
340 | Please consult the official [Haml reference](http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html) for more
|
341 | details.
|
342 |
|
343 | Haml Coffee supports both Ruby 1.8 and Ruby 1.9 style attributes. So the following Ruby 1.8 style attribute
|
344 |
|
345 | ```haml
|
346 | %a{ :href => 'http://haml-lang.com/', :title => 'Haml home' } Haml
|
347 | ```
|
348 |
|
349 | can also be written in Ruby 1.9 style:
|
350 |
|
351 | ```haml
|
352 | %a{ href: 'http://haml-lang.com/', title: 'Haml home' } Haml
|
353 | ```
|
354 |
|
355 | HTML style tags are also supported:
|
356 |
|
357 | ```haml
|
358 | %a( href='http://haml-lang.com/' title='Haml home') Haml
|
359 | ```
|
360 |
|
361 | ### Helpers
|
362 |
|
363 | Haml Coffee supports a small subset of the Ruby Haml [helpers](http://haml-lang.com/docs/yardoc/Haml/Helpers.html). The
|
364 | provided helpers will bind the helper function to the template context, so it isn't necessary to use `=>`.
|
365 |
|
366 | #### Surround
|
367 |
|
368 | Surrounds a block of Haml code with strings, with no whitespace in between.
|
369 |
|
370 | ```haml
|
371 | != surround '(', ')', ->
|
372 | %a{:href => "food"} chicken
|
373 | ```
|
374 |
|
375 | produces the HTML output
|
376 |
|
377 | ```html
|
378 | (<a href='food'>chicken</a>)
|
379 | ```
|
380 |
|
381 | #### Succeed
|
382 |
|
383 | Appends a string to the end of a Haml block, with no whitespace between.
|
384 |
|
385 | ```haml
|
386 | click
|
387 | != succeed '.', ->
|
388 | %a{:href=>"thing"} here
|
389 | ```
|
390 |
|
391 | produces the HTML output
|
392 |
|
393 | ```html
|
394 | click
|
395 | <a href='thing'>here</a>.
|
396 | ```
|
397 |
|
398 | #### Precede
|
399 |
|
400 | Prepends a string to the beginning of a Haml block, with no whitespace between.
|
401 |
|
402 | ```haml
|
403 | != precede '*', ->
|
404 | %span.small Not really
|
405 | ```
|
406 |
|
407 | produces the HTML output
|
408 |
|
409 | ```html
|
410 | *<span class='small'>Not really</span>
|
411 | ```
|
412 |
|
413 | ### Object reference: `[]`
|
414 |
|
415 | Haml Coffee supports object references, but they are implemented slightly different due to the underlying runtime and
|
416 | different code style for CoffeeScript.
|
417 |
|
418 | Square brackets contain a CoffeeScript object or class that is used to set the class and id of that tag. The class is
|
419 | set to the object’s constructor name (transformed to use underlines rather than camel case) and the id is set to the
|
420 | object’s constructor name, followed by the value of its `id` property or its `#to_key` or `#id` functions (in that
|
421 | order). Additionally, the second argument (if present) will be used as a prefix for both the id and class attributes.
|
422 |
|
423 | For example:
|
424 |
|
425 | ```haml
|
426 | %div[@user, 'greeting']
|
427 | Hello
|
428 | ```
|
429 |
|
430 | is compiled to:
|
431 |
|
432 | ```html
|
433 | <div class='greeting_user' id='greeting_user_15'>
|
434 | Hello!
|
435 | </div>
|
436 | ```
|
437 |
|
438 | If the user object is for example a Backbone model with the id of 15. If you require that the class be something other
|
439 | than the underscored object’s constructor name, you can implement the `#hamlObjectRef` function on the object:
|
440 |
|
441 | ```haml
|
442 | :coffeescript
|
443 | class User
|
444 | id: 23
|
445 | hamlObjectRef: -> 'custom'
|
446 |
|
447 | %div[new User()]
|
448 | Hello
|
449 | ```
|
450 |
|
451 | is compiled to:
|
452 |
|
453 | ```html
|
454 | <div class='custom' id='custom_23'>
|
455 | Hello!
|
456 | </div>
|
457 | ```
|
458 |
|
459 | ### Directives
|
460 |
|
461 | Haml Coffee supports currently a single directive that extends the Haml syntax.
|
462 |
|
463 | ### Include
|
464 |
|
465 | You can use the `+include` directive to include another template:
|
466 |
|
467 | ```haml
|
468 | %h1 Include
|
469 | +include 'partials/test'
|
470 | ```
|
471 |
|
472 | This will look up the specified template and include it. So if the partial `partials/test` contains
|
473 |
|
474 | ```haml
|
475 | %p Partial content
|
476 | ```
|
477 |
|
478 | The final result will be
|
479 |
|
480 | ```html
|
481 | <h1>Include</h1>
|
482 | <p>Partial content</p>
|
483 | ```
|
484 |
|
485 | ## CoffeeScript support
|
486 |
|
487 | Haml and CoffeeScript are a winning team, both use indention for blocks and are a perfect match for this reason. You can
|
488 | use CoffeeScript instead of Ruby in your Haml tags and the attributes.
|
489 |
|
490 | **It's not recommended to put too much logic into the template.**
|
491 |
|
492 | ### Attributes
|
493 |
|
494 | When you define an attribute value without putting it into quotes (single or double quotes), it's considered to be
|
495 | CoffeeScript code to be run at render time. By default, attributes values from CoffeeScript code are escaped before
|
496 | inserting into the document. You can change this behaviour by setting the appropriate compiler option.
|
497 |
|
498 | HTML style attributes are the most limited and can only assign a simple variable:
|
499 |
|
500 | ```haml
|
501 | %img(src='/images/demo.png' width=@width height=@height alt=alt)
|
502 | ```
|
503 |
|
504 | Both the `@width` and `@height` values must be passed as locals when rendering the template and `alt` must be defined
|
505 | before the `%img` tag.
|
506 |
|
507 | Ruby style tags can be more complex and can call functions:
|
508 |
|
509 | ```haml
|
510 | %header
|
511 | %user{ :class => App.currentUser.get('status') }= App.currentUser.getDisplayName()
|
512 | ```
|
513 |
|
514 | Attribute definitions are also supported in the Ruby 1.9 style:
|
515 |
|
516 | ```haml
|
517 | %header
|
518 | %user{ class: App.currentUser.get('status') }= App.currentUser.getDisplayName()
|
519 | ```
|
520 |
|
521 | More fancy stuff can be done when use interpolation within a double quoted attribute value:
|
522 |
|
523 | ```haml
|
524 | %header
|
525 | %user{ class: "#{ if @user.get('roles').indexOf('admin') is -1 then 'normal' else 'admin' }" }= @user.getDisplayName()
|
526 | ```
|
527 |
|
528 | _But think twice about it before putting such fancy stuff into your template, there are better places like models,
|
529 | views or helpers to put heavy logic into._
|
530 |
|
531 | You can define your attributes over multiple lines and the next line must not be correctly indented, so you can align
|
532 | them properly:
|
533 |
|
534 | ```haml
|
535 | %input#password.hint{ type: 'password', name: 'registration[password]',
|
536 | data: { hint: 'Something very important', align: 'left' } }
|
537 | ```
|
538 |
|
539 | In the above example you also see the usage for generating HTML5 data attributes.
|
540 |
|
541 | ### Running Code
|
542 |
|
543 | You can run any CoffeeScript code in your template:
|
544 |
|
545 | ```haml
|
546 | - for project in @projects
|
547 | - if project.visible
|
548 | .project
|
549 | %h1= project.name
|
550 | %p&= project.description
|
551 | ```
|
552 |
|
553 | There are several supported types to run your code:
|
554 |
|
555 | * Run code without insert anything into the document: `-`
|
556 | * Run code and insert the result into the document: `=`
|
557 |
|
558 | All inserted content from running code is escaped by default. You can change this behaviour by setting the appropriate
|
559 | compiler option.
|
560 |
|
561 | There are three variations to run code and insert its result into the document, two of them to change the escaping style
|
562 | chosen in the compile option:
|
563 |
|
564 | * Run code and do not escape the result: `!=`
|
565 | * Run code and escape the result: `&=`
|
566 | * Preserve whitespace when insert the result: `~`
|
567 |
|
568 | Again, please consult the official [Haml reference](http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html) for more
|
569 | details. Haml Coffee implements the same functionality like Ruby Haml, only for CoffeeScript.
|
570 |
|
571 | #### Interpolation
|
572 |
|
573 | If you use the CoffeeScript interpolation without explicitly run code with `=` and `-`, the interpolation output is not
|
574 | being escaped. You can manually force escaping by using the HTML escape reference `$e`:
|
575 |
|
576 | ```Haml
|
577 | %p
|
578 | foo #{ $e '<bar>' }
|
579 | ```
|
580 |
|
581 | will be rendered to
|
582 |
|
583 | ```HTML
|
584 | <p>
|
585 | foo <bar>
|
586 | </p>
|
587 | ```
|
588 |
|
589 | #### Multiline code blocks
|
590 |
|
591 | Running code must be placed on a single line and unlike Ruby Haml, you cannot stretch a it over multiple lines by
|
592 | putting a comma at the end.
|
593 |
|
594 | However, you can use multiline endings `|` to stretch your code over multiple lines to some extend:
|
595 |
|
596 | ```Haml
|
597 | - links = { |
|
598 | home: '/', |
|
599 | docs: '/docs', |
|
600 | about: '/about' |
|
601 | } |
|
602 |
|
603 | %ul
|
604 | - for name, link of links
|
605 | %li
|
606 | %a{ href: link }= name
|
607 | ```
|
608 |
|
609 | Please note, that since the line is concatenated before the compilation, you cannot omit the curly braces and the
|
610 | commas in the above example, like you'd do in normal CoffeeScript code. Therefore it's recommended to use the
|
611 | CoffeeScript filter to have real multiline code blocks:
|
612 |
|
613 | ```Haml
|
614 | :coffeescript
|
615 | links =
|
616 | home: '/'
|
617 | docs: '/docs'
|
618 | about: '/about'
|
619 |
|
620 | %ul
|
621 | - for name, link of links
|
622 | %li
|
623 | %a{ href: link }= name
|
624 | ```
|
625 |
|
626 | #### Functions
|
627 |
|
628 | You can also create functions that generate Haml:
|
629 |
|
630 | ```haml
|
631 | - sum = (a, b) ->
|
632 | %div
|
633 | %span= a
|
634 | %span= b
|
635 | %span= a+b
|
636 | = sum(1,2)
|
637 | = sum(3,4)
|
638 | ```
|
639 |
|
640 | or pass generated HTML output through a function for post-processing.
|
641 |
|
642 | ```haml
|
643 | = postProcess ->
|
644 | %a{ href: '/' }
|
645 | ```
|
646 |
|
647 | The content of the `:coffeescript` filter is run when the template is rendered and doesn't output anything into the
|
648 | resulting document. This comes in handy when you have code to run over multiple lines and don't want to prefix each line
|
649 | with `-`:
|
650 |
|
651 | ```haml
|
652 | %body
|
653 | :coffeescript
|
654 | tags = ['CoffeeScript', 'Haml']
|
655 | project = 'Haml Coffee'
|
656 | %h2= project
|
657 | %ul
|
658 | - for tag in tags
|
659 | %li= tag
|
660 | ```
|
661 |
|
662 | ## Compiler options
|
663 |
|
664 | The following section describes all the available compiler options that you can use through the JavaScript API,
|
665 | as Express view option or as argument to the command line utility.
|
666 |
|
667 | The command line arguments may be slightly different. For example instead of passing `--escape-html=false` you have to
|
668 | use the `--disable-html-escaping` argument. You can see a list of all the command line arguments by executing
|
669 | `haml-coffee --help`.
|
670 |
|
671 | ### HTML generation options
|
672 |
|
673 | The HTML options change the way how the generated HTML will look like.
|
674 |
|
675 | #### Output format
|
676 |
|
677 | * Name: 'format'
|
678 | * Type: `String`
|
679 | * Default: `html5`
|
680 |
|
681 | The Haml parser knows different HTML formats to which a given template can be rendered and it must be one of:
|
682 |
|
683 | * xhtml
|
684 | * html4
|
685 | * html5
|
686 |
|
687 | Doctype, self-closing tags and attributes handling depends on this setting. Please consult the official
|
688 | [Haml reference](http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html) for more details.
|
689 |
|
690 | #### Uglify output
|
691 |
|
692 | * Name: `uglify`
|
693 | * Type: `Boolean`
|
694 | * Default: `false`
|
695 |
|
696 | All generated HTML tags are properly indented by default, so the output looks nice. This can be helpful when debugging.
|
697 | You can skip the indention by setting the `uglify` option to false. This save you some bytes and you'll have increased
|
698 | rendering speed.
|
699 |
|
700 | #### HTML escape
|
701 |
|
702 | * Name: `escapeHtml`
|
703 | * Type: `Boolean`
|
704 | * Default: `true`
|
705 |
|
706 | The reserved HTML characters `"`, `'`, `&`, `<` and `>` are converted to their HTML entities by default when they are
|
707 | inserted into the HTML document from evaluated CoffeeScript.
|
708 |
|
709 | You can always change the escaping mode within the template to either force escaping with `&=` or force unescaping with
|
710 | `!=`.
|
711 |
|
712 | #### Attributes escape
|
713 |
|
714 | * Name: `escapeAttributes`
|
715 | * Type: `Boolean`
|
716 | * Default: `true`
|
717 |
|
718 | All HTML attributes that are generated by evaluating CoffeeScript are also escaped by default. You can turn of HTML
|
719 | escaping of the attributes only by setting `escapeAttributes` to false. You can't change this behaviour in the template
|
720 | since there is no Haml markup for this to instruct the compiler to change the escaping mode.
|
721 |
|
722 | #### Clean CoffeeScript values
|
723 |
|
724 | * Name: `cleanValue`
|
725 | * Type: `Boolean`
|
726 | * Default: `true`
|
727 |
|
728 | Every output that is generated from evaluating CoffeeScript code is cleaned before inserting into the document. The
|
729 | default implementation converts `null` or `undefined` values into an empty string and marks real boolean values with a
|
730 | hidden marker character. The hidden marker character is necessary to distinguish between String values like `'true'`,
|
731 | `'false'` and real boolean values `true`, `false` in the markup, so that a boolean attribute conversion can quickly
|
732 | convert these values to the correct HTML5/XHTML/HTML4 representation.
|
733 |
|
734 | #### Preserve whitespace tags
|
735 |
|
736 | * Name: `preserve`
|
737 | * Type: `String`
|
738 | * Default: `textarea,pre`
|
739 |
|
740 | The `preserve` option defines a list of comma separated HTML tags that are whitespace sensitive. Content from these tags
|
741 | must be preserved, so that the indention has no influence on the displayed content. This is simply done by converting
|
742 | the newline characters to their equivalent HTML entity.
|
743 |
|
744 | #### Autoclose tags
|
745 |
|
746 | * Name: `autoclose`
|
747 | * Type: `String`
|
748 | * Default: `meta,img,link,br,hr,input,area,param,col,base`
|
749 |
|
750 | The autoclose option defines a list of tag names that should be automatically closed if they have no content.
|
751 |
|
752 | #### Module loader support
|
753 |
|
754 | * Name: `placement`
|
755 | * Type: `String`
|
756 | * Default: `global`
|
757 |
|
758 | The `placement` option defines where the template function is inserted
|
759 | upon compilation.
|
760 |
|
761 | Possible values are:
|
762 |
|
763 | * `global` <br />
|
764 | Inserts the optionally namespaced template function into `window.HAML`.
|
765 |
|
766 | * 'standalone' <br />
|
767 | Returns the template function without wrapping it
|
768 |
|
769 | * `amd` <br />
|
770 | Wraps the template function into a `define()` statement to allow async
|
771 | loading via AMD.
|
772 |
|
773 | See AMD support for more information.
|
774 |
|
775 | ### Module dependencies
|
776 |
|
777 | * Name: `dependencies`
|
778 | * Type: `Object`
|
779 | * Default: `{ hc: 'hamlcoffee' }`
|
780 |
|
781 | The `dependencies` option allows you to define the modules that must be required for the AMD template `define` function.
|
782 | The object key will be the function parameter name of the module the object value defines. See AMD support for more
|
783 | information.
|
784 |
|
785 | ### Data attribute hyphenation
|
786 |
|
787 | * Name: `hyphenateDataAttrs`
|
788 | * Type: `Boolean`
|
789 | * Default: `true`
|
790 |
|
791 | Convert underscores to hyphens for data attribute keys, see
|
792 | [the Ruby Haml reference](http://haml.info/docs/yardoc/file.REFERENCE.html#html5_custom_data_attributes).
|
793 |
|
794 | ### Custom helper function options
|
795 |
|
796 | Haml Coffee provides helper functions for HTML escaping, value cleaning and whitespace preservation, which must be
|
797 | available at render time. By default every generated template function is self-contained and includes all of the helper
|
798 | functions.
|
799 |
|
800 | However you can change the reference to each helper function by providing the appropriate compiler option and there
|
801 | are good reasons to do so:
|
802 |
|
803 | * You want to reduce the template size and provide all the helpers from a central place.
|
804 | * You want to customize a helper function to better fit your needs.
|
805 |
|
806 | To change these functions, simply assign the new function name to one of the following options:
|
807 |
|
808 | * `customHtmlEscape`: Escape the reserved HTML characters into their equivalent HTML entity.
|
809 | * `customPreserve`: Converting newlines into their HTML entity.
|
810 | * `customFindAndPreserve`: Find whitespace sensitive tags and preserve their content.
|
811 | * `customCleanValue`: Clean the value that is returned after evaluating some inline CoffeeScript.
|
812 | * `customSurround`: Surrounds a block of Haml code with strings, with no whitespace in between.
|
813 | * `customSucceed`: Appends a string to the end of a Haml block, with no whitespace between.
|
814 | * `customPrecede`: Prepends a string to the beginning of a Haml block, with no whitespace between.
|
815 | * `customReference`: Creates the Haml object reference.
|
816 |
|
817 | The `customSurround`, `customSucceed` and `customPrecede` are bound to the template context.
|
818 |
|
819 | You can find a default implementation for all these helper functions in
|
820 | [Haml Coffee Assets](https://github.com/netzpirat/haml_coffee_assets/blob/master/vendor/assets/javascripts/hamlcoffee.js.coffee.erb).
|
821 |
|
822 | ## AMD support
|
823 |
|
824 | * Global dependencies
|
825 | * Trivial dependency detection
|
826 |
|
827 | Haml Coffee has built in AMD support by setting the `placement` option to `amd`. This will generate a module definition
|
828 | for the JavaScript template. The `dependencies` options can be used to provide a mapping of module names to parameters.
|
829 | To illustrate this, the default value will result in the following module declaration:
|
830 |
|
831 | ```CoffeeScript
|
832 | define ['hamlcoffee'], (hc) ->
|
833 | ```
|
834 |
|
835 | When the template contains a require call in the form of
|
836 |
|
837 | ```CoffeeScript
|
838 | - require 'module'
|
839 | - require 'deep/nested/other'
|
840 | ```
|
841 |
|
842 | it will be added to the module definition list
|
843 |
|
844 | ```CoffeeScript
|
845 | define ['hamlcoffee', 'module', 'deep/nested/other'], (hc, module, other) ->
|
846 | ```
|
847 |
|
848 | allowing you to render a partial template:
|
849 |
|
850 | ```CoffeeScript
|
851 | != module()
|
852 | != other()
|
853 | ```
|
854 |
|
855 | Of course the require call can have different quotes or parenthesises, allowing you to directly require and render:
|
856 |
|
857 | ```CoffeeScript
|
858 | != require("another/other")()
|
859 | ```
|
860 |
|
861 | ### Module dependency
|
862 |
|
863 | By default Haml Coffee AMD templates depend on the `hamlcoffee` module that provides the client side helpers needed to
|
864 | render the template. You need to supply your own module, but you can grab a copy from
|
865 | [Haml Coffee Assets AMD helpers](https://github.com/netzpirat/haml_coffee_assets/blob/master/vendor/assets/javascripts/hamlcoffee_amd.js.coffee.erb)
|
866 | and adapt it to your needs. Another option is to remove the module from the
|
867 | [module dependencies](https://github.com/netzpirat/haml-coffee#module-dependencies), but that's usually not what you
|
868 | want because it duplicates the needed function within every template.
|
869 |
|
870 | ### Static HTML
|
871 |
|
872 | By default Haml Coffee outputs pre-compiled templates for rendering dynamic content.
|
873 |
|
874 | There is a `render` helper that can be used as follows to get the standalone HTML rendering of a HAML template.
|
875 |
|
876 | ```
|
877 | hamlc = require 'haml-coffee'
|
878 | text = hamlc.render '%h1= @title', {title: 'hi'}
|
879 | text
|
880 | '<h1>hi</h1>'
|
881 | ```
|
882 |
|
883 | ## Development information
|
884 |
|
885 | Haml Coffee uses [Grunt](http://gruntjs.com/) for development, which you can install with
|
886 | [NPM](https://npmjs.org/):
|
887 |
|
888 | ```bash
|
889 | $ npm install
|
890 | ```
|
891 |
|
892 | and run Grunt to automatically run the Jasmine specs on file modification:
|
893 |
|
894 | ```bash
|
895 | $ grunt
|
896 | ```
|
897 |
|
898 | ## Changelog
|
899 |
|
900 | Feel free to take a look at the crispy [changelog](https://github.com/netzpirat/haml-coffee/blob/master/CHANGELOG.md)
|
901 | instead of crawling through the commit history.
|
902 |
|
903 | ## Related projects
|
904 |
|
905 | Haml Coffee in the Rails asset pipeline:
|
906 |
|
907 | * [haml-coffee-assets](https://github.com/netzpirat/haml_coffee_assets)
|
908 |
|
909 | ## Authors
|
910 |
|
911 | * [Michael Kessler](https://github.com/netzpirat) ([@netzpirat](http://twitter.com/#!/netzpirat), [mksoft.ch](https://mksoft.ch))
|
912 | * [Sebastion Deutsch](https://github.com/sebastiandeutsch) ([@sippndipp](http://twitter.com/#!/sippndipp), [9elements](http://9elements.com))
|
913 | * [Jan Varwig](https://github.com/janv) ([@agento](http://twitter.com/#!/agento), [9elements](http://9elements.com))
|
914 |
|
915 | ## Contributors
|
916 |
|
917 | See all contributors on [the contributor page](https://github.com/netzpirat/haml-coffee/contributors).
|
918 |
|
919 | ## License
|
920 |
|
921 | (The MIT License)
|
922 |
|
923 | Copyright (c) 2011 9elements, 2011-2013 Michael Kessler
|
924 |
|
925 | Permission is hereby granted, free of charge, to any person obtaining
|
926 | a copy of this software and associated documentation files (the
|
927 | 'Software'), to deal in the Software without restriction, including
|
928 | without limitation the rights to use, copy, modify, merge, publish,
|
929 | distribute, sublicense, and/or sell copies of the Software, and to
|
930 | permit persons to whom the Software is furnished to do so, subject to
|
931 | the following conditions:
|
932 |
|
933 | The above copyright notice and this permission notice shall be
|
934 | included in all copies or substantial portions of the Software.
|
935 |
|
936 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
937 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
938 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
939 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
940 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
941 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
942 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|