Write Clean and Elegant Views Haml

For the past few weeks I’ve been experimenting with Haml.

Haml is a templating language that is used to create the HTML in Sinatra apps, just like Embedded Ruby (ERB), which is basically HTML, with ruby inside these tags - <% %>. Haml takes things further and allows you to write HTML (and XML) much more elegantly and in with significantly less code.

You don’t have to do anything to start using Haml - it is included in Tilt, the templating engine that comes with Sinatra. All you need to do is replace erb :view with haml :view in your handlers (Don’t forget to save the view file with the .haml extension too).

Here’s an example that shows the difference between ERB adn Haml:

#ERB
<h1>I Did It My Way</h1>
<h2><%= @post.title %></h1>
<div id="content">
<p class="post">Welcome to my website</p>
</div>
<div id="footer">
<p>Made by DAZ</p>
</div>

#Haml
%h1 I Did It My Way
%h2= @post.title
#content
  %p.post Welcome to my website
#footer
  %p Made by DAZ

This example shows a few characteristics of Haml:

  • Tags start with %, you don’t need to close them
  • Hierarchy is shown by indentation (like in Python)
  • You specify ids and classes using # and . respectively, just like in CSS
  • You don’t even need to mention a div tag if it has an id or class

I think there are a few advantages with the Haml markup over the ERB:

  • It is 2 lines shorter
  • It is 62 characters shorter
  • You don’t have to type the annoying angled brackets
  • You can clearly see ids and classes, with the CSS-style syntax
  • The structure of the document can clearly be seen
  • The actual content is not cluttered with all the closing tags

There’s much more to it and you can find more info and examples in the official Haml tutorial.

Haml does have a few problems though. The biggest one is dealing with inline elements. For example, if you wanted to write a paragraph with a line, this is erb:

<p>Click <a href="http://microsoft.com">here</a> for a good time</p>

But in Haml it looks like this:

%p Click
  %a(href="http://microsoft.com")
    here
  for a good time

Which, quite frankly, looks horrible and totally spoils Haml’s reputation for clean-looking code. You can read more about this in Chris Eppstein’s post. Chris does propose a few solutions in his post. In this case the easiest thing to do would probably be to put some plain old HTML in with the Haml:

%p Click <a href="http://microsoft.com">here</a> for a good time

Very similar to erb, but at least you don’t need the closing tag. The main thrust of Chris’ post is that Haml shouldn’t really be used for large amounts of content, more for creating the templates that the content is put into. A language like Markdown would be much more suited for content entry.

I have to say that after a few days of using Haml I loved it and will probably do all my future work in it (including the tutorials on here). It’s just so much quicker than ERB and cleaner to look at. Haml also has a younger sister language - SASS which is used to create stylesheets (and also included in Tilt). I have to say that I’m even more excited about using SASS - It sorts out many of the problems with standard CSS, such as variables and class extensions … but that’s for another post.

I’d highly recommend giving Haml a try if you haven’t done so already. And if you don’t like Haml, I’d like to know why and what do you use instead?

If you want to get started using Haml, here’s a nice HTML 5 layout file to get you started. Hope you find it useful.

!!! 5
%html
  %head
    %meta(charset="utf-8")
    %title= @title || settings.name

    %meta(name="description" content="#{settings.description}")
    %meta(name="author" content="#{settings.author}")
    %meta(name="copyright" content="Copyright #{settings.author} #{Time.now.year}. All Rights Reserved.")
    
    %link(rel="shortcut icon" href="/images/favicon.png")    
    %link(rel="apple-touch-icon" href="/images/touchfavicon.png")    
    
    %link(rel="stylesheet" media="screen, projection" href="/stylesheets/main.css")
    
    /[if lt IE 9]
      %script(src="http://html5shiv.googlecode.com/svn/trunk/html5.js")
      
    
  %body
    %header
      %h1
        %a(title="home" href="/")= settings.name
    
    = yield
    
    %footer
      %small & Copyright #{settings.author} #{Time.now.year}. All Rights Reserved.
blog comments powered by Disqus