# Haml (XHTML Abstraction Markup Language) * Table of contents {:toc} Haml is a markup language that's used to cleanly and simply describe the XHTML of any web document, without the use of inline code. Haml functions as a replacement for inline page templating systems such as PHP, ERB, and ASP. However, Haml avoids the need for explicitly coding XHTML into the template, because it is actually an abstract description of the XHTML, with some code to generate dynamic content. ## Features * Whitespace active * Well-formatted markup * DRY * Follows CSS conventions * Integrates Ruby code * Implements Rails templates with the .haml extension ## Using Haml Haml can be used in three ways: as a plugin for Ruby on Rails, as a standalone Ruby module, and as a command-line tool. The first step for all of these is to install the Haml gem: gem install haml To enable it as a Rails plugin, then run haml --rails path/to/rails/app Once it's installed, all view files with the `".html.haml"` extension will be compiled using Haml. To run Haml from the command line, just use haml input.haml output.html Use `haml --help` for full documentation. You can access instance variables in Haml templates the same way you do in ERB templates. Helper methods are also available in Haml templates. For example (this example uses Rails, but the principle for Merb is the same): # file: app/controllers/movies_controller.rb class MoviesController < ApplicationController def index @title = "Teen Wolf" end end -# file: app/views/movies/index.haml #content .title %h1= @title = link_to 'Home', home_url may be compiled to:
Haml code!
\n" ### Options Options can be set by setting the {Haml::Template#options Haml::Template.options} hash in `environment.rb` in Rails... Haml::Template.options[:format] = :html5 ...or by setting the `Merb::Plugin.config[:haml]` hash in `init.rb` in Merb... Merb::Plugin.config[:haml][:format] = :html5 ...or by passing an options hash to {Haml::Engine#initialize}. Available options are: {#format-option} `:format` : Determines the output format. The default is `:xhtml`. Other options are `:html4` and `:html5`, which are identical to `:xhtml` except there are no self-closing tags, the XML prolog is ignored and correct DOCTYPEs are generated. {#escape_html-option} `:escape_html` : Sets whether or not to escape HTML-sensitive characters in script. If this is true, `=` behaves like `&=`; otherwise, it behaves like `!=`. Note that if this is set, `!=` should be used for yielding to subtemplates and rendering partials. Defaults to false. {#suppress_eval-option} `:suppress_eval` : Whether or not attribute hashes and Ruby scripts designated by `=` or `~` should be evaluated. If this is `true`, said scripts are rendered as empty strings. Defaults to `false`. {#attr_wrapper-option} `:attr_wrapper` : The character that should wrap element attributes. This defaults to `'` (an apostrophe). Characters of this type within the attributes will be escaped (e.g. by replacing them with `'`) if the character is an apostrophe or a quotation mark. {#filename-option} `:filename` : The name of the Haml file being parsed. This is only used as information when exceptions are raised. This is automatically assigned when working through ActionView, so it's really only useful for the user to assign when dealing with Haml programatically. {#line-option} `:line` : The line offset of the Haml template being parsed. This is useful for inline templates, similar to the last argument to `Kernel#eval`. {#autoclose-option} `:autoclose` : A list of tag names that should be automatically self-closed if they have no content. Defaults to `['meta', 'img', 'link', 'br', 'hr', 'input', 'area', 'param', 'col', 'base']`. {#preserve-option} `:preserve` : A list of tag names that should automatically have their newlines preserved using the {Haml::Helpers#preserve} helper. This means that any content given on the same line as the tag will be preserved. For example, `%textarea= "Foo\nBar"` compiles to ``. Defaults to `['textarea', 'pre']`. See also [Whitespace Preservation](#whitespace_preservation). ## Plain Text A substantial portion of any HTML document is its content, which is plain old text. Any Haml line that's not interpreted as something else is taken to be plain text, and passed through unmodified. For example: %gee %whiz Wow this is cool! is compiled to:
The magical fruit
And: %img %img> %img is compiled to: And: %p<= "Foo\nBar" is compiled to:Foo!
Foo Bar
And finally: %img %pre>< foo bar %img is compiled to:foo bar### Object Reference: `[]` Square brackets follow a tag definition and contain a Ruby object that is used to set the class and id of that tag. The class is set to the object's class (transformed to use underlines rather than camel case) and the id is set to the object's class, followed by its id. Because the id of an object is normally an obscure implementation detail, this is most useful for elements that represent instances of Models. Additionally, the second argument (if present) will be used as a prefix for both the id and class attributes. For example: # file: app/controllers/users_controller.rb def show @user = CrazyUser.find(15) end -# file: app/views/users/show.haml %div[@user, :greeting] %bar[290]/ Hello! is compiled to:
Sign my guestbook
You can also specify the version and type of XHTML after the `!!!`. XHTML 1.0 Strict, Transitional, and Frameset and XHTML 1.1 are supported. The default version is 1.0 and the default type is Transitional. For example: !!! 1.1 is compiled to: and !!! Strict is compiled to: while !!! Basic is compiled to: and !!! Mobile is compiled to: If you're not using the UTF-8 character set for your document, you can specify which encoding should appear in the XML prolog in a similar way. For example: !!! XML iso-8859-1 is compiled to: ## Comments Haml supports two sorts of comments: those that show up in the HTML output and those that don't. ### HTML Comments: `/` The forward slash character, when placed at the beginning of a line, wraps all text after it in an HTML comment. For example: %peanutbutterjelly / This is the peanutbutterjelly element I like sandwiches! is compiled to:foo
bar
You can also nest text beneath a silent comment. None of this text will be rendered. For example: %p foo -# This won't be displayed Nor will this %p bar is compiled to:foo
bar
## Ruby Evaluation ### Inserting Ruby: `=` The equals character is followed by Ruby code. This code is evaluated and the output is inserted into the document. For example: %p = ['hi', 'there', 'reader!'].join " " = "yo" is compiled to:hi there reader! yo
If the [`:escape_html`](#escape_html-option) option is set, `=` will sanitize any HTML-sensitive characters generated by the script. For example: = '' would be compiled to <script>alert("I'm evil!");</script> `=` can also be used at the end of a tag to insert Ruby code within that tag. For example: %p= "hello" would be compiled tohello
Note that it's illegal to nest code within a tag that ends with `=`. ### Running Ruby: `-` The hyphen character is also followed by Ruby code. This code is evaluated but *not* inserted into the document. **It is not recommended that you use this widely; almost all processing code and logic should be restricted to the Controller, the Helper, or partials.** For example: - foo = "hello" - foo << " there" - foo << " you!" %p= foo is compiled to:hello there you!
#### Ruby Blocks Ruby blocks, like XHTML tags, don't need to be explicitly closed in Haml. Rather, they're automatically closed, based on indentation. A block begins whenever the indentation is increased after a Ruby evaluation command. It ends when the indentation decreases (as long as it's not an `else` clause or something similar). For example: - (42...47).each do |i| %p= i %p See, I can count! is compiled to:42
43
44
45
46
Another example: %p - case 2 - when 1 = "1!" - when 2 = "2?" - when 3 = "3." is compiled to:2?
### Whitespace Preservation: `~` {#tilde} `~` works just like `=`, except that it runs {Haml::Helpers#find\_and\_preserve} on its input. For example, ~ "Foo\nBar\nBaz" is the same as: = find_and_preserve("Foo\n
Bar\nBaz") and is compiled to: Foo
Bar BazSee also [Whitespace Preservation](#whitespace_preservation). ### Ruby Interpolation: `#{}` Ruby code can also be interpolated within plain text using `#{}`, similarly to Ruby string interpolation. For example, %p This is #{h quality} cake! is the same as %p= "This is the #{h quality} cake!" and might compile to
This is scrumptious cake!
Backslashes can be used to escape `#{` strings, but they don't act as escapes anywhere else in the string. For example: %p Look at \\#{h word} lack of backslash: \#{foo} And yon presence thereof: \{foo} might compile toLook at \yon lack of backslash: #{foo} And yon presence thereof: \{foo}
Interpolation can also be used within [filters](#filters). For example: :javascript $(document).ready(function() { alert(#{@message.to_json}); }); might compile to ### Escaping HTML: `&=` An ampersand followed by one or two equals characters evaluates Ruby code just like the equals without the ampersand, but sanitizes any HTML-sensitive characters in the result of the code. For example: &= "I like cheese & crackers" compiles to I like cheese & crackers If the [`:escape_html`](#escape_html-option) option is set, `&=` behaves identically to `=`. `&` can also be used on its own so that `#{}` interpolation is escaped. For example, & I like #{"cheese & crackers"} compiles to I like cheese & crackers ### Unescpaing HTML: `!=` An exclamation mark followed by one or two equals characters evaluates Ruby code just like the equals would, but never sanitizes the HTML. By default, the single equals doesn't sanitize HTML either. However, if the [`:escape_html`](#escape_html-option) option is set, `=` will sanitize the HTML, but `!=` still won't. For example, if `:escape_html` is set: = "I feel !" != "I feel !" compiles to I feel <strong>! I feel ! `!` can also be used on its own so that `#{}` interpolation is unescaped. For example, ! I feel #{""}! compiles to I feel ! ## Filters: `:` {#filters} The colon character designates a filter. This allows you to pass an indented block of text as input to another filtering program and add the result to the output of Haml. The syntax is simply a colon followed by the name of the filter. For example, %p :markdown Textile ======= Hello, *World* is compiled to
Hello, World
Filters can have Ruby code interpolated with `#{}`. For example, - flavor = "raspberry" #content :textile I *really* prefer _#{h flavor}_ jam. is compiled toI really prefer raspberry jam.