# Haml (XHTML Abstraction Markup Language) 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 command-line tool, as a plugin for Ruby on Rails, and as a standalone Ruby module. The first step for all of these is to install the Haml gem: gem install haml To run Haml from the command line, just use haml input.haml output.html Use `haml --help` for full documentation. ### Rails/Merb Plugin {#plugin} To enable Haml in Rails versions before Rails 3, add the following line to `environment.rb`: config.gem "haml" For Rails 3, instead add the following line to the Gemfile: gem "haml" Once it's installed, all view files with the `".html.haml"` extension will be compiled using Haml. Haml is enabled by default in Merb. 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. Normally the default is `:xhtml`, although under Rails 3 it's `:html5`, since that's the Rails 3's default format. 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.
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 the value of its `#to_key` or `#id` method (in that order). 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 specific doctype after the `!!!` When the [`:format`](#format-option) is set to `:xhtml` (the default except in Rails 3), the following doctypes are supported: `!!!` : XHTML 1.0 Transitionalfoo
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 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
A line of Ruby code can be stretched over multiple lines as long as each line but the last ends with a comma. For example: = link_to_remote "Add to cart", :url => { :action => "add", :id => product.id }, :update => { :success => "cart", :failure => "error" } 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!
A line of Ruby code can be stretched over multiple lines as long as each line but the last ends with a comma. For example: - links = {:home => "/", :docs => "/docs", :about => "/about"} #### 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
See, I can count!
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: `&=` {#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 ### Unescaping HTML: `!=` {#unescaping_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.