Haml is an XHTML Abstraction Markup Language that, according to haml-lang.com:
functions as a replacement for inline page templating systems such as PHP, ASP, and ERB
It can be used in many Ruby frameworks, such as Rails and Sinatra, in Node.js, PHP and .NET.
This article is going to introduce you to writing your HTML as Haml. As such it’s not going to contain much Ruby code. But if you’d like a more in-depth look at how Haml works under the covers, have a read of Xavier Shay’s excellent Code Safari articles on Haml: Getting Started in Haml and Haml, Compiling to Completion.
Installing Haml
To use Haml you’ll first need to install it. This shouldn’t be any harder than opening up your command line and typing:
gem install haml
Now, lets look at how we can write some HTML using Haml.
!DOCTYPE
By default Haml usually defaults to the XHTML DOCTYPE. I say usually because if you’re using Rails 3 then Haml defaults to HTML5. You can change the default DOCTYPE using the :format
option but, as this article is dealing with standalone Haml, we’ll look at how to write the DOCTYPE manually in our template:
-
HTML5 DOCTYPE
!!! 5
Will produce:
!DOCTYPE html
-
XHTML Strict DOCTYPE
!!! Strict
This gives us:
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
-
XML DOCTYPE
!!! XML
Will output:
?xml version="1.0" encoding="utf-8" ?
Tags and Attributes
Now we’ve taken care of the DOCTYPE, let’s look at how we can construct our HTML. We’ll start the basic template of a HTML document which in Haml looks like this:
%html
%head
%title Our Awesome Haml Template
%body
Abstracting HTML since 2006
When the above is compiled it will give us the following HTML:
html
head
titleOur Awesome Haml Template/title
/head
body
Abstracting HTML since 2006 /body /html
You may have noticed that:
- Haml uses whitespace and indenting to format the HTML.
- Tags are prefixed with a
%
. Closing tags aren’t required.
So far, so good. But we’ll need to add a bit more content to our page and, with it, some more structure and semantics:
%body
#container
%header
%h1 Our Awesome Haml Template
#main Abstracting HTML since 2006
%footer
%address Ian Oxley
This gives us the following HTML:
body
div id="container"
header
h1Our Awesome Haml Template/h1
/header
div id="main"
Abstracting HTML since 2006
/div
footer
addressIan Oxley/address
/footer
/div
/body
With more tags being added it should become more apparent how Haml uses whitespace and indentation to work out the structure of your HTML. But did you notice anything about how we got our div id="container"
and div id="main"
tags on to the page?
- Haml assumes you are outputting a
div
tag unless you specify otherwise id
attributes are specified in the same way you write anid
rule in CSS i.e.#container
You can also add class
attributes to an element the same way you add an id
attribute:
%footer
%address
.hcard
.fn Ian Oxley
.adr
.locality Newcastle-upon-Tyne
.country-name England
If you’ve been paying attention, you’ll have probably guessed that this will compile to:
footer
address
div class="hcard"
div class="fn"Ian Oxley/div
div class="adr"
div class="locality"Newcastle-upon-Tyne/div
div class="country-name"England/div
/div
/div
/address
/footer
But what about other attributes that we will need to add to our markup? Things like lang
, src
, rel
and href
? Well that’s easily done using one of two methods:
-
You can use curly braces and specify your attributes with a Ruby hash. For example:
%img{ :src = "/path/to/image", :alt = "Description of image" }
-
Or you can use parentheses and use a more HTML-like foo=”bar” approach:
%img ( src="/path/to/image", alt="Description of image")
Both of these will output the following HTML:
img src="/path/to/image" alt="Description of image"
Using this approach we can easily add CSS, JavaScript and any meta tags we need to our templates:
%meta{ :charset = "utf-8" }
%link{ :rel = "stylesheet", :href = "/css/master.css" }
Will give us:
meta charset="utf-8"
link rel="stylesheet" href="/css/master.css"
And:
%script{ :src = "/js/site.js" }
Will give us:
script src="/js/site.js"/script
Comments
Haml lets you add three types of comments to your markup:
- HTML comments
- Conditional comments
- Haml comments
HTML comments can be added using a forward slash ‘/’ but depending on where you place it will affect what gets wrapped in comments:
/ A forward slash at the start of a line wraps that line in a comment
%blockquote
%p Roads? Where we're going we don't need roads
/
A forward slash at the start of a nested block wraps the whole block in a comment
%blockquote
%p Roads? Where we're going we don't need roads
Once compiled our output will be:
!-- Only this line will be wrapped in a comment --
blockquote
pRoads? Where we're going we don't need roads/p
/blockquote
!--
Now the whole block will be commented out
blockquote
pRoads? Where we're going we don't need roads/p
/blockquote
--
Conditional comments can be added by placing the condition in square brackets after the ‘/’:
/[if IE] %link { :rel = "stylesheet", :href = "/css/ie.css" }
This gives us the following HTML:
!--[if IE] link href="/css/ie.css" rel="stylesheet" ![endif]--
Haml comments are comments that included in the template file but not rendered in the final output. You specify them with -# and the same rules that applied to HTML comments apply here too:
%p The line below won't appear in the HTML
-# The rest of this line is a comment
%p The line above won't appear in the HTML, nor will the lines underneath
-#
None of this nested text will appear
in our rendered output either
This produces:
pThe line below won't appear in the HTML/p
pThe line above won't appear in the HTML, nor will the lines underneath/p
Adding Some Ruby Code
Whilst this article has focused on how you can write HTML using Haml, we couldn’t finish it without a brief bit on how to get some Ruby code into your template.
To insert some Ruby code, just add the '='
sign followed by the code. For example:
%p= Time.now
The code will be evaluated and output into the markup wrapped in p
tags like so:
pSat Aug 06 15:06:09 +0100 2011/p
Running Haml from the Command Line
A great way to experiment with Haml is to run it from the command line. Just bung all your Haml code in one file and you can output the compiled template into another file like so:
haml input.html.haml output.html
So, that was a quick look at how you can use Haml when writing your HTML. If you’ve not used Haml yet hopefully it’ll encourage you to give it a try. Don’t forget to check out the Haml website at http://haml-lang.com where you can find loads more info, a complete language reference and can even take Haml for a test drive.
Update: I’ve put all the Haml snippets from the article into a Gist on GitHub. Feel free to fork away: https://gist.github.com/1147666