An Introduction to Haml

Ian Oxley
Ian Oxley
Share

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" "https://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> 
    <title>Our 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> 
      <h1>Our Awesome Haml Template</h1> 
    </header> 
    <div id="main"> 
      Abstracting HTML since 2006 
    </div> 
    <footer> 
      <address>Ian 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 an id 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:
  1. HTML comments
  2. Conditional comments
  3. 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> 
  <p>Roads? Where we're going we don't need roads</p> 
</blockquote> 

<!-- 
  Now the whole block will be commented out 
  <blockquote> 
    <p>Roads? 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:
<p>The line below won't appear in the HTML</p> 
<p>The 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

tags like so:
<p>Sat 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

Frequently Asked Questions about HAML

What is the main difference between HAML and HTML?

HAML (HTML Abstraction Markup Language) is a lightweight markup language that is used to describe the HTML of a web document without using traditional inline coding. It’s a more abstract way of working with webpage elements. The main difference between HAML and HTML is that HAML avoids the use of inline code and instead uses indentation to represent nested elements and attributes. This makes the code cleaner and easier to read.

How do I convert my HTML code to HAML?

Converting HTML to HAML is quite straightforward. There are several online tools available that can convert your HTML code to HAML instantly. You just need to paste your HTML code into the converter and it will output the equivalent HAML code. However, it’s important to understand the structure and syntax of HAML to ensure the conversion is accurate.

Can I use Ruby code in HAML?

Yes, one of the key features of HAML is its seamless integration with Ruby. You can embed Ruby code into your HAML document using hyphen (-) and equals (=) signs. The hyphen is used for executing Ruby code, while the equals sign is used for outputting the result of Ruby code.

How do I comment in HAML?

Commenting in HAML is done by using the forward slash (/) followed by the comment. This will create an HTML comment that will be visible in the HTML source code. If you want to create a HAML comment that won’t be visible in the HTML source, you can use the hyphen (-) followed by a pound sign (#).

What are filters in HAML and how do I use them?

Filters in HAML are used to process blocks of text within a HAML document. They are prefixed with a colon (:). Some of the commonly used filters include :javascript, :css, :plain, :cdata, etc. To use a filter, you simply need to follow it with a block of indented text.

How do I create a list in HAML?

Creating a list in HAML is similar to creating any other HTML element. You just need to use the % symbol followed by the element name. For example, to create an unordered list with list items, you would use %ul for the unordered list and %li for each list item.

How do I include an image in HAML?

Including an image in HAML is done using the %img tag followed by the image source and alternative text in curly braces. For example, %img{src: “image.jpg”, alt: “Image Description”}.

How do I link to another page in HAML?

Linking to another page in HAML is done using the %a tag followed by the href attribute in curly braces. For example, %a{href: “page.html”} Link Text.

How do I use variables in HAML?

Variables in HAML can be used by embedding Ruby code. You can define a variable using a hyphen (-) and then use it later in your HAML document by using an equals sign (=). For example, – name = “John” and then = name will output John.

How do I use loops in HAML?

Loops in HAML can be created by embedding Ruby code. For example, to create a loop that outputs numbers 1 to 5, you could use – (1..5).each do |i| followed by = i on the next line.