Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 373
- Log:
Initial import of Radiant 0.9.1, which is now packaged as a gem. This is an
import of the tagged 0.9.1 source checked out from GitHub, which isn't quite
the same as the gem distribution - but it doesn't seem to be available in an
archived form and the installed gem already has modifications, so this is
the closest I can get.
- Author:
- rool
- Date:
- Mon Mar 21 13:40:05 +0000 2011
- Size:
- 31773 Bytes
1 | # Haml (XHTML Abstraction Markup Language) |
2 | |
3 | * Table of contents |
4 | {:toc} |
5 | |
6 | Haml is a markup language |
7 | that's used to cleanly and simply describe the XHTML of any web document, |
8 | without the use of inline code. |
9 | Haml functions as a replacement |
10 | for inline page templating systems such as PHP, ERB, and ASP. |
11 | However, Haml avoids the need for explicitly coding XHTML into the template, |
12 | because it is actually an abstract description of the XHTML, |
13 | with some code to generate dynamic content. |
14 | |
15 | ## Features |
16 | |
17 | * Whitespace active |
18 | * Well-formatted markup |
19 | * DRY |
20 | * Follows CSS conventions |
21 | * Integrates Ruby code |
22 | * Implements Rails templates with the .haml extension |
23 | |
24 | ## Using Haml |
25 | |
26 | Haml can be used in three ways: |
27 | as a command-line tool, |
28 | as a plugin for Ruby on Rails, |
29 | and as a standalone Ruby module. |
30 | The first step for all of these is to install the Haml gem: |
31 | |
32 | gem install haml |
33 | |
34 | To run Haml from the command line, just use |
35 | |
36 | haml input.haml output.html |
37 | |
38 | Use `haml --help` for full documentation. |
39 | |
40 | ### Rails/Merb Plugin {#plugin} |
41 | |
42 | To enable Haml as a Rails plugin, run |
43 | |
44 | haml --rails path/to/rails/app |
45 | |
46 | Once it's installed, all view files with the `".html.haml"` extension |
47 | will be compiled using Haml. |
48 | Haml is enabled by default in Merb. |
49 | |
50 | You can access instance variables in Haml templates |
51 | the same way you do in ERB templates. |
52 | Helper methods are also available in Haml templates. |
53 | For example (this example uses Rails, but the principle for Merb is the same): |
54 | |
55 | # file: app/controllers/movies_controller.rb |
56 | |
57 | class MoviesController < ApplicationController |
58 | def index |
59 | @title = "Teen Wolf" |
60 | end |
61 | end |
62 | |
63 | -# file: app/views/movies/index.haml |
64 | |
65 | #content |
66 | .title |
67 | %h1= @title |
68 | = link_to 'Home', home_url |
69 | |
70 | may be compiled to: |
71 | |
72 | <div id='content'> |
73 | <div class='title'> |
74 | <h1>Teen Wolf</h1> |
75 | <a href='/'>Home</a> |
76 | </div> |
77 | </div> |
78 | |
79 | #### Rails XSS Protection |
80 | |
81 | Haml supports Rails' XSS protection scheme, |
82 | which was introduced in Rails 2.3.5+ and is enabled by default in 3.0.0+. |
83 | If it's enabled, Haml's [`:escape_html`](#escape_html-option) |
84 | option is set to `true` by default - |
85 | like in ERB, all strings printed to a Haml template are escaped by default. |
86 | Also like ERB, strings marked as HTML safe are not escaped. |
87 | Haml also has [its own syntax for printing a raw string to the template](#unescaping_html). |
88 | |
89 | If the `:escape_html` option is set to false when XSS protection is enabled, |
90 | Haml doesn't escape Ruby strings by default. |
91 | However, if a string marked HTML-safe is passed to [Haml's escaping syntax](#escaping_html), |
92 | it won't be escaped. |
93 | |
94 | Finally, all the {file:Haml/Helpers.html Haml helpers} that return strings |
95 | that are known to be HTML safe are marked as such. |
96 | In addition, string input is escaped unless it's HTML safe. |
97 | |
98 | ### Ruby Module |
99 | |
100 | Haml can also be used completely separately from Rails and ActionView. |
101 | To do this, install the gem with RubyGems: |
102 | |
103 | gem install haml |
104 | |
105 | You can then use it by including the "haml" gem in Ruby code, |
106 | and using {Haml::Engine} like so: |
107 | |
108 | engine = Haml::Engine.new("%p Haml code!") |
109 | engine.render #=> "<p>Haml code!</p>\n" |
110 | |
111 | ### Options |
112 | |
113 | Options can be set by setting the {Haml::Template#options Haml::Template.options} hash |
114 | in `environment.rb` in Rails... |
115 | |
116 | Haml::Template.options[:format] = :html5 |
117 | |
118 | ...or by setting the `Merb::Plugin.config[:haml]` hash in `init.rb` in Merb... |
119 | |
120 | Merb::Plugin.config[:haml][:format] = :html5 |
121 | |
122 | ...or by passing an options hash to {Haml::Engine#initialize}. |
123 | Available options are: |
124 | |
125 | {#format-option} `:format` |
126 | : Determines the output format. The default is `:xhtml`. |
127 | Other options are `:html4` and `:html5`, which are |
128 | identical to `:xhtml` except there are no self-closing tags, |
129 | the XML prolog is ignored and correct DOCTYPEs are generated. |
130 | |
131 | {#escape_html-option} `:escape_html` |
132 | : Sets whether or not to escape HTML-sensitive characters in script. |
133 | If this is true, `=` behaves like [`&=`](#escaping_html); |
134 | otherwise, it behaves like [`!=`](#unescaping_html). |
135 | Note that if this is set, `!=` should be used for yielding to subtemplates |
136 | and rendering partials. |
137 | See also [Escaping HTML](#escaping_html) and [Unescaping HTML](#unescaping_html) |
138 | Defaults to false. |
139 | |
140 | {#ugly-option} `:ugly` |
141 | : If set to `true`, Haml makes no attempt to properly |
142 | indent or format the HTML output. |
143 | This significantly improves rendering performance |
144 | but makes viewing the source unpleasant. |
145 | Defaults to `true` in Rails production mode, and `false` |
146 | everywhere else. |
147 | |
148 | {#suppress_eval-option} `:suppress_eval` |
149 | : Whether or not attribute hashes and Ruby scripts |
150 | designated by `=` or `~` should be |
151 | evaluated. If this is `true`, said scripts are |
152 | rendered as empty strings. Defaults to `false`. |
153 | |
154 | {#attr_wrapper-option} `:attr_wrapper` |
155 | : The character that should wrap element attributes. |
156 | This defaults to `'` (an apostrophe). Characters |
157 | of this type within the attributes will be escaped |
158 | (e.g. by replacing them with `'`) if |
159 | the character is an apostrophe or a quotation mark. |
160 | |
161 | {#filename-option} `:filename` |
162 | : The name of the Haml file being parsed. |
163 | This is only used as information when exceptions are raised. |
164 | This is automatically assigned when working through ActionView, |
165 | so it's really only useful for the user to assign |
166 | when dealing with Haml programatically. |
167 | |
168 | {#line-option} `:line` |
169 | : The line offset of the Haml template being parsed. |
170 | This is useful for inline templates, |
171 | similar to the last argument to `Kernel#eval`. |
172 | |
173 | {#autoclose-option} `:autoclose` |
174 | : A list of tag names that should be automatically self-closed |
175 | if they have no content. |
176 | Defaults to `['meta', 'img', 'link', 'br', 'hr', 'input', 'area', 'param', 'col', 'base']`. |
177 | |
178 | {#preserve-option} `:preserve` |
179 | : A list of tag names that should automatically have their newlines preserved |
180 | using the {Haml::Helpers#preserve} helper. |
181 | This means that any content given on the same line as the tag will be preserved. |
182 | For example, `%textarea= "Foo\nBar"` compiles to `<textarea>Foo
Bar</textarea>`. |
183 | Defaults to `['textarea', 'pre']`. |
184 | See also [Whitespace Preservation](#whitespace_preservation). |
185 | |
186 | {#encoding-option} `:encoding` |
187 | : The encoding to use for the HTML output. |
188 | Only available in Ruby 1.9 or higher. |
189 | This can be a string or an `Encoding` Object. |
190 | Note that Haml **does not** automatically re-encode Ruby values; |
191 | any strings coming from outside the application should be converted |
192 | before being passed into the Haml template. |
193 | Defaults to `Encoding.default_internal` or, if that's not set, `"utf-8"`. |
194 | <br/><br/> <!-- There's no better way to do a paragraph break in a dl in Maruku --> |
195 | Many Ruby database drivers are not yet Ruby 1.9 compatible; |
196 | in particular, they return strings marked as ASCII-encoded |
197 | even when those strings contain non-ASCII characters (such as UTF-8). |
198 | **This will cause encoding errors** if the Haml encoding isn't set to `"ascii-8bit"`. |
199 | To solve this, either call `#force_encoding` on all the strings returned from the database, |
200 | set `:encoding` to `"ascii-8bit"`, or try to get the authors of the database drivers |
201 | to make them Ruby 1.9 compatible. |
202 | |
203 | ## Plain Text |
204 | |
205 | A substantial portion of any HTML document is its content, |
206 | which is plain old text. |
207 | Any Haml line that's not interpreted as something else |
208 | is taken to be plain text, and passed through unmodified. |
209 | For example: |
210 | |
211 | %gee |
212 | %whiz |
213 | Wow this is cool! |
214 | |
215 | is compiled to: |
216 | |
217 | <gee> |
218 | <whiz> |
219 | Wow this is cool! |
220 | </whiz> |
221 | </gee> |
222 | |
223 | Note that HTML tags are passed through unmodified as well. |
224 | If you have some HTML you don't want to convert to Haml, |
225 | or you're converting a file line-by-line, |
226 | you can just include it as-is. |
227 | For example: |
228 | |
229 | %p |
230 | <div id="blah">Blah!</div> |
231 | |
232 | is compiled to: |
233 | |
234 | <p> |
235 | <div id="blah">Blah!</div> |
236 | </p> |
237 | |
238 | ### Escaping: `\` |
239 | |
240 | The backslash character escapes the first character of a line, |
241 | allowing use of otherwise interpreted characters as plain text. |
242 | For example: |
243 | |
244 | %title |
245 | = @title |
246 | \= @title |
247 | |
248 | is compiled to: |
249 | |
250 | <title> |
251 | MyPage |
252 | = @title |
253 | </title> |
254 | |
255 | ## HTML Elements |
256 | |
257 | |
258 | ### Element Name: `%` |
259 | |
260 | The percent character is placed at the beginning of a line. |
261 | It's followed immediately by the name of an element, |
262 | then optionally by modifiers (see below), a space, |
263 | and text to be rendered inside the element. |
264 | It creates an element in the form of `<element></element>`. |
265 | For example: |
266 | |
267 | %one |
268 | %two |
269 | %three Hey there |
270 | |
271 | is compiled to: |
272 | |
273 | <one> |
274 | <two> |
275 | <three>Hey there</three> |
276 | </two> |
277 | </one> |
278 | |
279 | Any string is a valid element name; |
280 | Haml will automatically generate opening and closing tags for any element. |
281 | |
282 | ### Attributes: `{}` or `()` {#attributes} |
283 | |
284 | Brackets represent a Ruby hash |
285 | that is used for specifying the attributes of an element. |
286 | It is literally evaluated as a Ruby hash, |
287 | so logic will work in it and local variables may be used. |
288 | Quote characters within the attribute |
289 | will be replaced by appropriate escape sequences. |
290 | The hash is placed after the tag is defined. |
291 | For example: |
292 | |
293 | %html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"} |
294 | |
295 | is compiled to: |
296 | |
297 | <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'></html> |
298 | |
299 | Attribute hashes can also be stretched out over multiple lines |
300 | to accommodate many attributes. |
301 | However, newlines may only be placed immediately after commas. |
302 | For example: |
303 | |
304 | %script{:type => "text/javascript", |
305 | :src => "javascripts/script_#{2 + 7}"} |
306 | |
307 | is compiled to: |
308 | |
309 | <script src='javascripts/script_9' type='text/javascript'></script> |
310 | |
311 | #### HTML-style Attributes: `()` |
312 | |
313 | Haml also supports a terser, less Ruby-specific attribute syntax |
314 | based on HTML's attributes. |
315 | These are used with parentheses instead of brackets, like so: |
316 | |
317 | %html(xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en") |
318 | |
319 | Ruby variables can be used by omitting the quotes. |
320 | Local variables or instance variables can be used. |
321 | For example: |
322 | |
323 | %a(title=@title href=href) Stuff |
324 | |
325 | This is the same as: |
326 | |
327 | %a{:title => @title, :href => href} Stuff |
328 | |
329 | Because there are no commas separating attributes, though, |
330 | more complicated expressions aren't allowed. |
331 | For those you'll have to use the `{}` syntax. |
332 | You can, however, use both syntaxes together: |
333 | |
334 | %a(title=@title){:href => @link.href} Stuff |
335 | |
336 | You can also use `#{}` interpolation to insert complicated expressions |
337 | in a HTML-style attribute: |
338 | |
339 | %span(class="widget_#{@widget.number}") |
340 | |
341 | HTML-style attributes can be stretched across multiple lines |
342 | just like hash-style attributes: |
343 | |
344 | %script(type="text/javascript" |
345 | src="javascripts/script_#{2 + 7}") |
346 | |
347 | #### Attribute Methods |
348 | |
349 | A Ruby method call that returns a hash |
350 | can be substituted for the hash contents. |
351 | For example, {Haml::Helpers} defines the following method: |
352 | |
353 | def html_attrs(lang = 'en-US') |
354 | {:xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => lang, :lang => lang} |
355 | end |
356 | |
357 | This can then be used in Haml, like so: |
358 | |
359 | %html{html_attrs('fr-fr')} |
360 | |
361 | This is compiled to: |
362 | |
363 | <html lang='fr-fr' xml:lang='fr-fr' xmlns='http://www.w3.org/1999/xhtml'> |
364 | </html> |
365 | |
366 | You can use as many such attribute methods as you want |
367 | by separating them with commas, |
368 | like a Ruby argument list. |
369 | All the hashes will me merged together, from left to right. |
370 | For example, if you defined |
371 | |
372 | def hash1 |
373 | {:bread => 'white', :filling => 'peanut butter and jelly'} |
374 | end |
375 | |
376 | def hash2 |
377 | {:bread => 'whole wheat'} |
378 | end |
379 | |
380 | then |
381 | |
382 | %sandwich{hash1, hash2, :delicious => true}/ |
383 | |
384 | would compile to: |
385 | |
386 | <sandwich bread='whole wheat' delicious='true' filling='peanut butter and jelly' /> |
387 | |
388 | Note that the Haml attributes list has the same syntax as a Ruby method call. |
389 | This means that any attribute methods must come before the hash literal. |
390 | |
391 | Attribute methods aren't supported for HTML-style attributes. |
392 | |
393 | #### Boolean Attributes |
394 | |
395 | Some attributes, such as "checked" for `input` tags or "selected" for `option` tags, |
396 | are "boolean" in the sense that their values don't matter - |
397 | it only matters whether or not they're present. |
398 | In HTML (but not XHTML), these attributes can be written as |
399 | |
400 | <input selected> |
401 | |
402 | To do this in Haml using hash-style attributes, just assign a Ruby |
403 | `true` value to the attribute: |
404 | |
405 | %input{:selected => true} |
406 | |
407 | In XHTML, the only valid value for these attributes is the name of the |
408 | attribute. Thus this will render in XHTML as |
409 | |
410 | <input selected='selected'> |
411 | |
412 | To set these attributes to false, simply assign them to a Ruby false value. |
413 | In both XHTML and HTML |
414 | |
415 | %input{:selected => false} |
416 | |
417 | will just render as |
418 | |
419 | <input> |
420 | |
421 | HTML-style boolean attributes can be written just like HTML: |
422 | |
423 | %input(selected) |
424 | |
425 | or using `true` and `false`: |
426 | |
427 | %input(selected=true) |
428 | |
429 | ### Class and ID: `.` and `#` |
430 | |
431 | The period and pound sign are borrowed from CSS. |
432 | They are used as shortcuts to specify the `class` |
433 | and `id` attributes of an element, respectively. |
434 | Multiple class names can be specified in a similar way to CSS, |
435 | by chaining the class names together with periods. |
436 | They are placed immediately after the tag and before an attributes hash. |
437 | For example: |
438 | |
439 | %div#things |
440 | %span#rice Chicken Fried |
441 | %p.beans{ :food => 'true' } The magical fruit |
442 | %h1.class.otherclass#id La La La |
443 | |
444 | is compiled to: |
445 | |
446 | <div id='things'> |
447 | <span id='rice'>Chicken Fried</span> |
448 | <p class='beans' food='true'>The magical fruit</p> |
449 | <h1 class='class otherclass' id='id'>La La La</h1> |
450 | </div> |
451 | |
452 | And, |
453 | |
454 | #content |
455 | .articles |
456 | .article.title Doogie Howser Comes Out |
457 | .article.date 2006-11-05 |
458 | .article.entry |
459 | Neil Patrick Harris would like to dispel any rumors that he is straight |
460 | |
461 | is compiled to: |
462 | |
463 | <div id='content'> |
464 | <div class='articles'> |
465 | <div class='article title'>Doogie Howser Comes Out</div> |
466 | <div class='article date'>2006-11-05</div> |
467 | <div class='article entry'> |
468 | Neil Patrick Harris would like to dispel any rumors that he is straight |
469 | </div> |
470 | </div> |
471 | </div> |
472 | |
473 | #### Implicit Div Elements |
474 | |
475 | Because divs are used so often, they're the default elements. |
476 | If you only define a class and/or id using `.` or `#`, |
477 | a div is automatically used. |
478 | For example: |
479 | |
480 | #collection |
481 | .item |
482 | .description What a cool item! |
483 | |
484 | is the same as: |
485 | |
486 | %div#collection |
487 | %div.item |
488 | %div.description What a cool item! |
489 | |
490 | and is compiled to: |
491 | |
492 | <div id='collection'> |
493 | <div class='item'> |
494 | <div class='description'>What a cool item!</div> |
495 | </div> |
496 | </div> |
497 | |
498 | ### Self-Closing Tags: `/` |
499 | |
500 | The forward slash character, when placed at the end of a tag definition, |
501 | causes the tag to be self-closed. |
502 | For example: |
503 | |
504 | %br/ |
505 | %meta{'http-equiv' => 'Content-Type', :content => 'text/html'}/ |
506 | |
507 | is compiled to: |
508 | |
509 | <br /> |
510 | <meta http-equiv='Content-Type' content='text/html' /> |
511 | |
512 | Some tags are automatically closed, as long as they have no content. |
513 | `meta`, `img`, `link`, `script`, `br`, and `hr` tags are closed by default. |
514 | This list can be customized by setting the [`:autoclose`](#autoclose-option) option. |
515 | For example: |
516 | |
517 | %br |
518 | %meta{'http-equiv' => 'Content-Type', :content => 'text/html'} |
519 | |
520 | is also compiled to: |
521 | |
522 | <br /> |
523 | <meta http-equiv='Content-Type' content='text/html' /> |
524 | |
525 | ### Whitespace Removal: `>` and `<` |
526 | |
527 | `>` and `<` give you more control over the whitespace near a tag. |
528 | `>` will remove all whitespace surrounding a tag, |
529 | while `<` will remove all whitespace immediately within a tag. |
530 | You can think of them as alligators eating the whitespace: |
531 | `>` faces out of the tag and eats the whitespace on the outside, |
532 | and `<` faces into the tag and eats the whitespace on the inside. |
533 | They're placed at the end of a tag definition, |
534 | after class, id, and attribute declarations |
535 | but before `/` or `=`. |
536 | For example: |
537 | |
538 | %blockquote< |
539 | %div |
540 | Foo! |
541 | |
542 | is compiled to: |
543 | |
544 | <blockquote><div> |
545 | Foo! |
546 | </div></blockquote> |
547 | |
548 | And: |
549 | |
550 | %img |
551 | %img> |
552 | %img |
553 | |
554 | is compiled to: |
555 | |
556 | <img /><img /><img /> |
557 | |
558 | And: |
559 | |
560 | %p<= "Foo\nBar" |
561 | |
562 | is compiled to: |
563 | |
564 | <p>Foo |
565 | Bar</p> |
566 | |
567 | And finally: |
568 | |
569 | %img |
570 | %pre>< |
571 | foo |
572 | bar |
573 | %img |
574 | |
575 | is compiled to: |
576 | |
577 | <img /><pre>foo |
578 | bar</pre><img /> |
579 | |
580 | ### Object Reference: `[]` |
581 | |
582 | Square brackets follow a tag definition and contain a Ruby object |
583 | that is used to set the class and id of that tag. |
584 | The class is set to the object's class |
585 | (transformed to use underlines rather than camel case) |
586 | and the id is set to the object's class, followed by its id. |
587 | Because the id of an object is normally an obscure implementation detail, |
588 | this is most useful for elements that represent instances of Models. |
589 | Additionally, the second argument (if present) will be used as a prefix for |
590 | both the id and class attributes. |
591 | For example: |
592 | |
593 | # file: app/controllers/users_controller.rb |
594 | |
595 | def show |
596 | @user = CrazyUser.find(15) |
597 | end |
598 | |
599 | -# file: app/views/users/show.haml |
600 | |
601 | %div[@user, :greeting] |
602 | %bar[290]/ |
603 | Hello! |
604 | |
605 | is compiled to: |
606 | |
607 | <div class='greeting_crazy_user' id='greeting_crazy_user_15'> |
608 | <bar class='fixnum' id='fixnum_581' /> |
609 | Hello! |
610 | </div> |
611 | |
612 | ## Doctype: `!!!` |
613 | |
614 | When describing HTML documents with Haml, |
615 | you can have a document type or XML prolog generated automatically |
616 | by including the characters `!!!`. |
617 | For example: |
618 | |
619 | !!! XML |
620 | !!! |
621 | %html |
622 | %head |
623 | %title Myspace |
624 | %body |
625 | %h1 I am the international space station |
626 | %p Sign my guestbook |
627 | |
628 | is compiled to: |
629 | |
630 | <?xml version='1.0' encoding='utf-8' ?> |
631 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
632 | <html> |
633 | <head> |
634 | <title>Myspace</title> |
635 | </head> |
636 | <body> |
637 | <h1>I am the international space station</h1> |
638 | <p>Sign my guestbook</p> |
639 | </body> |
640 | </html> |
641 | |
642 | You can also specify the specific doctype after the `!!!` |
643 | When the [`:format`](#format) is set to `:xhtml` (the default), |
644 | the following doctypes are supported: |
645 | |
646 | `!!!` |
647 | : XHTML 1.0 Transitional<br/> |
648 | `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">` |
649 | |
650 | `!!! Strict` |
651 | : XHTML 1.0 Strict<br/> |
652 | `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">` |
653 | |
654 | `!!! Frameset` |
655 | : XHTML 1.0 Frameset<br/> |
656 | `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">` |
657 | |
658 | `!!! 5` |
659 | : XHTML 5<br/> |
660 | `<!DOCTYPE html>`<br/> |
661 | |
662 | `!!! 1.1` |
663 | : XHTML 1.1<br/> |
664 | `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">` |
665 | |
666 | `!!! Basic` |
667 | : XHTML Basic 1.1<br/> |
668 | `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"> ` |
669 | |
670 | `!!! Mobile` |
671 | : XHTML Mobile 1.2<br/> |
672 | `<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">` |
673 | |
674 | When the [`:format`](#format) option is set to `:html4`, |
675 | the following doctypes are supported: |
676 | |
677 | `!!!` |
678 | : HTML 4.01 Transitional<br/> |
679 | `<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">` |
680 | |
681 | `!!! Strict` |
682 | : HTML 4.01 Strict<br/> |
683 | `<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">` |
684 | |
685 | `!!! Frameset` |
686 | : HTML 4.01 Frameset<br/> |
687 | `<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">` |
688 | |
689 | When the [`:format`](#format) option is set to `:html5`, |
690 | `!!!` is always `<!DOCTYPE html>`. |
691 | |
692 | If you're not using the UTF-8 character set for your document, |
693 | you can specify which encoding should appear |
694 | in the XML prolog in a similar way. |
695 | For example: |
696 | |
697 | !!! XML iso-8859-1 |
698 | |
699 | is compiled to: |
700 | |
701 | <?xml version='1.0' encoding='iso-8859-1' ?> |
702 | |
703 | ## Comments |
704 | |
705 | Haml supports two sorts of comments: |
706 | those that show up in the HTML output |
707 | and those that don't. |
708 | |
709 | ### HTML Comments: `/` |
710 | |
711 | The forward slash character, when placed at the beginning of a line, |
712 | wraps all text after it in an HTML comment. |
713 | For example: |
714 | |
715 | %peanutbutterjelly |
716 | / This is the peanutbutterjelly element |
717 | I like sandwiches! |
718 | |
719 | is compiled to: |
720 | |
721 | <peanutbutterjelly> |
722 | <!-- This is the peanutbutterjelly element --> |
723 | I like sandwiches! |
724 | </peanutbutterjelly> |
725 | |
726 | The forward slash can also wrap indented sections of code. For example: |
727 | |
728 | / |
729 | %p This doesn't render... |
730 | %div |
731 | %h1 Because it's commented out! |
732 | |
733 | is compiled to: |
734 | |
735 | <!-- |
736 | <p>This doesn't render...</p> |
737 | <div> |
738 | <h1>Because it's commented out!</h1> |
739 | </div> |
740 | --> |
741 | |
742 | #### Conditional Comments: `/[]` |
743 | |
744 | You can also use [Internet Explorer conditional comments](http://www.quirksmode.org/css/condcom.html) |
745 | by enclosing the condition in square brackets after the `/`. |
746 | For example: |
747 | |
748 | /[if IE] |
749 | %a{ :href => 'http://www.mozilla.com/en-US/firefox/' } |
750 | %h1 Get Firefox |
751 | |
752 | is compiled to: |
753 | |
754 | <!--[if IE]> |
755 | <a href='http://www.mozilla.com/en-US/firefox/'> |
756 | <h1>Get Firefox</h1> |
757 | </a> |
758 | <![endif]--> |
759 | |
760 | ### Haml Comments: `-#` |
761 | |
762 | The hyphen followed immediately by the pound sign |
763 | signifies a silent comment. |
764 | Any text following this isn't rendered in the resulting document |
765 | at all. |
766 | |
767 | For example: |
768 | |
769 | %p foo |
770 | -# This is a comment |
771 | %p bar |
772 | |
773 | is compiled to: |
774 | |
775 | <p>foo</p> |
776 | <p>bar</p> |
777 | |
778 | You can also nest text beneath a silent comment. |
779 | None of this text will be rendered. |
780 | For example: |
781 | |
782 | %p foo |
783 | -# |
784 | This won't be displayed |
785 | Nor will this |
786 | %p bar |
787 | |
788 | is compiled to: |
789 | |
790 | <p>foo</p> |
791 | <p>bar</p> |
792 | |
793 | ## Ruby Evaluation |
794 | |
795 | ### Inserting Ruby: `=` |
796 | |
797 | The equals character is followed by Ruby code. |
798 | This code is evaluated and the output is inserted into the document. |
799 | For example: |
800 | |
801 | %p |
802 | = ['hi', 'there', 'reader!'].join " " |
803 | = "yo" |
804 | |
805 | is compiled to: |
806 | |
807 | <p> |
808 | hi there reader! |
809 | yo |
810 | </p> |
811 | |
812 | If the [`:escape_html`](#escape_html-option) option is set, `=` will sanitize any |
813 | HTML-sensitive characters generated by the script. For example: |
814 | |
815 | = '<script>alert("I\'m evil!");</script>' |
816 | |
817 | would be compiled to |
818 | |
819 | <script>alert("I'm evil!");</script> |
820 | |
821 | `=` can also be used at the end of a tag to insert Ruby code within that tag. |
822 | For example: |
823 | |
824 | %p= "hello" |
825 | |
826 | would be compiled to |
827 | |
828 | <p>hello</p> |
829 | |
830 | Note that it's illegal to nest code within a tag that ends with `=`. |
831 | |
832 | ### Running Ruby: `-` |
833 | |
834 | The hyphen character is also followed by Ruby code. |
835 | This code is evaluated but *not* inserted into the document. |
836 | |
837 | **It is not recommended that you use this widely; |
838 | almost all processing code and logic should be restricted |
839 | to the Controller, the Helper, or partials.** |
840 | |
841 | For example: |
842 | |
843 | - foo = "hello" |
844 | - foo << " there" |
845 | - foo << " you!" |
846 | %p= foo |
847 | |
848 | is compiled to: |
849 | |
850 | <p> |
851 | hello there you! |
852 | </p> |
853 | |
854 | #### Ruby Blocks |
855 | |
856 | Ruby blocks, like XHTML tags, don't need to be explicitly closed in Haml. |
857 | Rather, they're automatically closed, based on indentation. |
858 | A block begins whenever the indentation is increased |
859 | after a Ruby evaluation command. |
860 | It ends when the indentation decreases |
861 | (as long as it's not an `else` clause or something similar). |
862 | For example: |
863 | |
864 | - (42...47).each do |i| |
865 | %p= i |
866 | %p See, I can count! |
867 | |
868 | is compiled to: |
869 | |
870 | <p>42</p> |
871 | <p>43</p> |
872 | <p>44</p> |
873 | <p>45</p> |
874 | <p>46</p> |
875 | <p>See, I can count!</p> |
876 | |
877 | Another example: |
878 | |
879 | %p |
880 | - case 2 |
881 | - when 1 |
882 | = "1!" |
883 | - when 2 |
884 | = "2?" |
885 | - when 3 |
886 | = "3." |
887 | |
888 | is compiled to: |
889 | |
890 | <p> |
891 | 2? |
892 | </p> |
893 | |
894 | ### Whitespace Preservation: `~` {#tilde} |
895 | |
896 | `~` works just like `=`, except that it runs {Haml::Helpers#find\_and\_preserve} on its input. |
897 | For example, |
898 | |
899 | ~ "Foo\n<pre>Bar\nBaz</pre>" |
900 | |
901 | is the same as: |
902 | |
903 | = find_and_preserve("Foo\n<pre>Bar\nBaz</pre>") |
904 | |
905 | and is compiled to: |
906 | |
907 | Foo |
908 | <pre>Bar
Baz</pre> |
909 | |
910 | See also [Whitespace Preservation](#whitespace_preservation). |
911 | |
912 | ### Ruby Interpolation: `#{}` |
913 | |
914 | Ruby code can also be interpolated within plain text using `#{}`, |
915 | similarly to Ruby string interpolation. |
916 | For example, |
917 | |
918 | %p This is #{h quality} cake! |
919 | |
920 | is the same as |
921 | |
922 | %p= "This is the #{h quality} cake!" |
923 | |
924 | and might compile to |
925 | |
926 | <p>This is scrumptious cake!</p> |
927 | |
928 | Backslashes can be used to escape `#{` strings, |
929 | but they don't act as escapes anywhere else in the string. |
930 | For example: |
931 | |
932 | %p |
933 | Look at \\#{h word} lack of backslash: \#{foo} |
934 | And yon presence thereof: \{foo} |
935 | |
936 | might compile to |
937 | |
938 | <p> |
939 | Look at \yon lack of backslash: #{foo} |
940 | And yon presence thereof: \{foo} |
941 | </p> |
942 | |
943 | Interpolation can also be used within [filters](#filters). |
944 | For example: |
945 | |
946 | :javascript |
947 | $(document).ready(function() { |
948 | alert(#{@message.to_json}); |
949 | }); |
950 | |
951 | might compile to |
952 | |
953 | <script type='text/javascript'> |
954 | //<![CDATA[ |
955 | $(document).ready(function() { |
956 | alert("Hi there!"); |
957 | }); |
958 | //]]> |
959 | </script> |
960 | |
961 | ### Escaping HTML: `&=` {#escaping_html} |
962 | |
963 | An ampersand followed by one or two equals characters |
964 | evaluates Ruby code just like the equals without the ampersand, |
965 | but sanitizes any HTML-sensitive characters in the result of the code. |
966 | For example: |
967 | |
968 | &= "I like cheese & crackers" |
969 | |
970 | compiles to |
971 | |
972 | I like cheese & crackers |
973 | |
974 | If the [`:escape_html`](#escape_html-option) option is set, |
975 | `&=` behaves identically to `=`. |
976 | |
977 | `&` can also be used on its own so that `#{}` interpolation is escaped. |
978 | For example, |
979 | |
980 | & I like #{"cheese & crackers"} |
981 | |
982 | compiles to |
983 | |
984 | I like cheese & crackers |
985 | |
986 | ### Unescaping HTML: `!=` {#unescaping_html} |
987 | |
988 | An exclamation mark followed by one or two equals characters |
989 | evaluates Ruby code just like the equals would, |
990 | but never sanitizes the HTML. |
991 | |
992 | By default, the single equals doesn't sanitize HTML either. |
993 | However, if the [`:escape_html`](#escape_html-option) option is set, |
994 | `=` will sanitize the HTML, but `!=` still won't. |
995 | For example, if `:escape_html` is set: |
996 | |
997 | = "I feel <strong>!" |
998 | != "I feel <strong>!" |
999 | |
1000 | compiles to |
1001 | |
1002 | I feel <strong>! |
1003 | I feel <strong>! |
1004 | |
1005 | `!` can also be used on its own so that `#{}` interpolation is unescaped. |
1006 | For example, |
1007 | |
1008 | ! I feel #{"<strong>"}! |
1009 | |
1010 | compiles to |
1011 | |
1012 | I feel <strong>! |
1013 | |
1014 | ## Filters {#filters} |
1015 | |
1016 | The colon character designates a filter. |
1017 | This allows you to pass an indented block of text as input |
1018 | to another filtering program and add the result to the output of Haml. |
1019 | The syntax is simply a colon followed by the name of the filter. |
1020 | For example, |
1021 | |
1022 | %p |
1023 | :markdown |
1024 | Textile |
1025 | ======= |
1026 | |
1027 | Hello, *World* |
1028 | |
1029 | is compiled to |
1030 | |
1031 | <p> |
1032 | <h1>Textile</h1> |
1033 | |
1034 | <p>Hello, <em>World</em></p> |
1035 | </p> |
1036 | |
1037 | Filters can have Ruby code interpolated with `#{}`. |
1038 | For example, |
1039 | |
1040 | - flavor = "raspberry" |
1041 | #content |
1042 | :textile |
1043 | I *really* prefer _#{h flavor}_ jam. |
1044 | |
1045 | is compiled to |
1046 | |
1047 | <div id='content'> |
1048 | <p>I <strong>really</strong> prefer <em>raspberry</em> jam.</p> |
1049 | </div> |
1050 | |
1051 | Currently, filters ignore the [`:escape_html`](#escape_html-option) option. |
1052 | This means that `#{}` interpolation within filters is never HTML-escaped. |
1053 | |
1054 | Haml has the following filters defined: |
1055 | |
1056 | {#plain-filter} |
1057 | ### `:plain` |
1058 | Does not parse the filtered text. |
1059 | This is useful for large blocks of text without HTML tags, |
1060 | when you don't want lines starting with `.` or `-` to be parsed. |
1061 | |
1062 | {#javascript-filter} |
1063 | ### `:javascript` |
1064 | Surrounds the filtered text with `<script>` and CDATA tags. |
1065 | Useful for including inline Javascript. |
1066 | |
1067 | {#cdata-filter} |
1068 | ### `:cdata` |
1069 | Surrounds the filtered text with CDATA tags. |
1070 | |
1071 | {#escaped-filter} |
1072 | ### `:escaped` |
1073 | Works the same as plain, but HTML-escapes the text |
1074 | before placing it in the document. |
1075 | |
1076 | {#ruby-filter} |
1077 | ### `:ruby` |
1078 | Parses the filtered text with the normal Ruby interpreter. |
1079 | All output sent to `$stdout`, like with `puts`, |
1080 | is output into the Haml document. |
1081 | Not available if the [`:suppress_eval`](#suppress_eval-option) option is set to true. |
1082 | The Ruby code is evaluated in the same context as the Haml template. |
1083 | |
1084 | {#preserve-filter} |
1085 | ### `:preserve` |
1086 | Inserts the filtered text into the template with whitespace preserved. |
1087 | `preserve`d blocks of text aren't indented, |
1088 | and newlines are replaced with the HTML escape code for newlines, |
1089 | to preserve nice-looking output. |
1090 | See also [Whitespace Preservation](#whitespace_preservation). |
1091 | |
1092 | {#erb-filter} |
1093 | ### `:erb` |
1094 | Parses the filtered text with ERB, like an RHTML template. |
1095 | Not available if the [`:suppress_eval`](#suppress_eval-option) option is set to true. |
1096 | Embedded Ruby code is evaluated in the same context as the Haml template. |
1097 | |
1098 | {#sass-filter} |
1099 | ### `:sass` |
1100 | Parses the filtered text with Sass to produce CSS output. |
1101 | |
1102 | {#textile-filter} |
1103 | ### `:textile` |
1104 | Parses the filtered text with [Textile](http://www.textism.com/tools/textile). |
1105 | Only works if [RedCloth](http://redcloth.org) is installed. |
1106 | |
1107 | {#markdown-filter} |
1108 | ### `:markdown` |
1109 | Parses the filtered text with [Markdown](http://daringfireball.net/projects/markdown). |
1110 | Only works if [RDiscount](http://github.com/rtomayko/rdiscount), |
1111 | [RPeg-Markdown](http://github.com/rtomayko/rpeg-markdown), |
1112 | [Maruku](http://maruku.rubyforge.org), |
1113 | or [BlueCloth](www.deveiate.org/projects/BlueCloth) are installed. |
1114 | |
1115 | {#maruku-filter} |
1116 | ### `:maruku` |
1117 | Parses the filtered text with [Maruku](http://maruku.rubyforge.org), |
1118 | which has some non-standard extensions to Markdown. |
1119 | |
1120 | ### Custom Filters |
1121 | |
1122 | You can also define your own filters. See {Haml::Filters} for details. |
1123 | |
1124 | ## Multiline: `|` {#multiline} |
1125 | |
1126 | The pipe character designates a multiline string. |
1127 | It's placed at the end of a line (after some whitespace) |
1128 | and means that all following lines that end with `|` |
1129 | will be evaluated as though they were on the same line. |
1130 | **Note that even the last line in the multiline block |
1131 | should end wit `|`.** |
1132 | For example: |
1133 | |
1134 | %whoo |
1135 | %hoo= h( | |
1136 | "I think this might get " + | |
1137 | "pretty long so I should " + | |
1138 | "probably make it " + | |
1139 | "multiline so it doesn't " + | |
1140 | "look awful.") | |
1141 | %p This is short. |
1142 | |
1143 | is compiled to: |
1144 | |
1145 | <whoo> |
1146 | <hoo>I think this might get pretty long so I should probably make it multiline so it doesn't look awful.</hoo> |
1147 | <p>This is short</p> |
1148 | </whoo> |
1149 | |
1150 | Using multiline declarations in Haml is intentionally awkward. |
1151 | This is designed to discourage people from putting lots and lots of Ruby code |
1152 | in their Haml templates. |
1153 | If you find yourself using multiline declarations, stop and think: |
1154 | could I do this better with a helper? |
1155 | |
1156 | Note that there is one case where it's useful to allow |
1157 | something to flow over onto multiple lines in a non-awkward manner: attributes. |
1158 | Some elements just have lots of attributes, |
1159 | so you can wrap attributes without using `|` (see [Attributes](#attributes)). |
1160 | |
1161 | ## Whitespace Preservation |
1162 | |
1163 | Sometimes you don't want Haml to indent all your text. |
1164 | For example, tags like `pre` and `textarea` are whitespace-sensitive; |
1165 | indenting the text makes them render wrong. |
1166 | |
1167 | Haml deals with this by "preserving" newlines before they're put into the document -- |
1168 | converting them to the XHTML whitespace escape code, `
`. |
1169 | Then Haml won't try to re-format the indentation. |
1170 | |
1171 | Literal `textarea` and `pre` tags automatically preserve content given through `=`. |
1172 | Dynamically-generated `textarea`s and `pre`s can't be preserved automatically, |
1173 | and so should be passed through {Haml::Helpers#find\_and\_preserve} or the [`~` command](#tilde), |
1174 | which has the same effect. |
1175 | |
1176 | Blocks of literal text can be preserved using the [`:preserve` filter](#preserve-filter). |
1177 | |
1178 | ## Helpers |
1179 | |
1180 | Haml offers a bunch of helpers that are useful |
1181 | for doing stuff like preserving whitespace, |
1182 | creating nicely indented output for user-defined helpers, |
1183 | and other useful things. |
1184 | The helpers are all documented in the {Haml::Helpers} and {Haml::Helpers::ActionViewExtensions} modules. |