Topic: Haml -- A Great Alternative to RHTML

Is your head is swimming and your eyes blurring from <%= and %> tags? Are you having trouble picking out your document structure among all the markup? Lucky for us, Rails allows for alternate template languages. One that is gaining traction right now is Haml. The reason is that it generates beautiful XHTML every time and your source reflects your document structure.

This all seems good, but what's the catch? Well the answer is pretty much: There is no catch. But, it's a work-style change. First let's look at what an RHTML file and its corresponding Haml file might look like:

The RHTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
    </meta>
    <%= stylesheet_link_tag('application') %>
    <%= javascript_include_tag(:defaults) %>
    <title><%= yield :header %></title>
  </head>
  <body>
    <div id='banner'>
      <img alt="Banner_l" height="135" src="/images/banner_l.gif?1170462461" width="263" />
    </div>
    <div id='menu'>
      <div id='menu-container'>
        <%= render :partial => '/layouts/shared/nav_links' %>
      </div>
    </div>
    <div id='content'>
      <%= yield %>
      <div id='footer'>
        <p>
          copyright &copy;  <%= "#{Date.today.year}." -%> all rights reserved
        </p>
      </div>
    </div>
  </body>
</html>

Now, the Haml:

!!!
%html
  %head
    %meta{"http-equiv"=>"Content-Type", :content=>"text/html; charset=utf-8"}
    = stylesheet_link_tag('application')
    = javascript_include_tag(:defaults)
    %title= yield :title
  %body
    #banner= image_tag('banner_l.gif', :size => '263x135')
    #menu
      #menu-container
        = render :partial => '/layouts/shared/nav_links'
    #content
      = yield
      #footer
        %p
          copyright &copy;
          = "#{Date.today.year}."
          all rights reserved
        %p= footer_links

If you're like me, you will find the Haml much more concise, and reflective of the structure of the XHTML document. Coincidentally, that makes it easier to associate CSS styles with elements without doing a ton of visual parsing of your code. In Haml's trunk (if you like to live on the edge) is Sass, which is to CSS as Haml is to Rhtml. Sass is best left for a different tutorial.

So, how to get started with Haml? Install the plugin as follows:

script/plugin install http://svn.hamptoncatlin.com/haml/trunk haml

Rails will keep rendering your Rhtml files just fine, but when you write a view file with the .haml extension, Haml kicks in.

Rules of the road:

Haml is space-sensitive! All blocks in Haml are denoted by a two-space increase in indentation. Don't use tabs.

Normal HTML tags are prefixed with the % character. So:

%p now is the time

is the same as

%p
  now is
  the time

Classes are denoted by a preceding period, so an emphasized paragraph might read:

%p.reallyimportant Listen Up!

IDs are similarly identified by a preceding hash mark:

#menu.item= @menus[:name]

Note in the above, there is an equal-sign right after the tag? That means what follows is Erb! Just like in Rhtml.

If you want to set options, use a hash, as follows:

#menu{:background => "#ffeeee"} I have bad taste in background colors

Finally there is the much-debated issue of silent code in views. Here's the Haml take on that:

- for line_item in @line_items
  you have
  = line_item[:quantity]
  things in your shopping cart.

Notice that there was no need to close the block with an explicit "end". Haml figured that out from the indentation.

I hope this has been a useful introduction to what I find an enormous productivity tool. For further reading, see:

http://unspace.ca/discover/haml

Enjoy!

Re: Haml -- A Great Alternative to RHTML

My next project I'm going to tackel haml. I think I'd find it easier writing it.

--

Re: Haml -- A Great Alternative to RHTML

Hmmm, not sure I like the syntax, I find it dense to read.

But this intrigues me a lot

Haml automatically adjusts rendered output to the proper indentation level

Re: Haml -- A Great Alternative to RHTML

I'm not too fond of the syntax, but I might give it a try. Thanks for the tutorial cwd!

Do you know if it works well with form_for which uses ruby blocks to wrap the output?

Railscasts - Free Ruby on Rails Screencasts

Re: Haml -- A Great Alternative to RHTML

form_for always worked:

- form_for(:foo) do |f|
  %p
    name
    = f.text_field :name
  %p
    address
    ~ f.text_area :address

but it used to have a problem with a trailing <p> after the form tag. It wasn't a problem that affected the function, but the output HTML is otherwise so perfect, everyone screamed. It has since, I believe, been fixed as a special case.

The reason for the inconsistency is that the form_for helper concats directly onto the Erb stream and is written with that run-in formatting.

Re: Haml -- A Great Alternative to RHTML

I have to say I don't care much for the syntax either but it still looks like a good way to save a lot of time.

One thing I'd like to know is can haml strip newlines from a line, like Rails' -%>?

If I were to write:

<%= image_tag 'bla1' -%>
<%= image_tag 'bla2' -%>

the output would be:
<img src="bla1"><img src="bla2">

This is necessary to avoid stupid formatting mistakes made by IE some times. Is there a way to do this in haml?

Re: Haml -- A Great Alternative to RHTML

Sorry about the long delay ansering this one. My best advice on this is something like:

= image_tag('foo') + image_tag('bar')

That's certain to work. However, the vertical pipe at line end is supposed to mean line continuation, so while I haven't tried it, you may be able to write:

= image_tag('foo') |
  image_tag('bar')

Re: Haml -- A Great Alternative to RHTML

There is one catch.. HAML's author himself admits that performance-wise it still is not as fast as ERB.

Personally I installed erubis and never looked back

Re: Haml -- A Great Alternative to RHTML

cwd wrote:

Sorry about the long delay ansering this one. My best advice on this is something like:

= image_tag('foo') + image_tag('bar')

That's certain to work. However, the vertical pipe at line end is supposed to mean line continuation, so while I haven't tried it, you may be able to write:

= image_tag('foo') |
  image_tag('bar')

Hi cwd, I just saw your reply. That's good for the image tags themselves but here's what happens. I write this in haml:

  #test= image_tag('foo') + image_tag('bar')

And this is the result:
<div id="test">
  <img src="foo"><img src="bar">
</div>

This is great from a readability perspective but Explorer tends to mess up certain layout styles if there's any whitespace between the divs at all.

Really haml isn't doing anything wrong but it's making it inconvenient to use :\

10

Re: Haml -- A Great Alternative to RHTML

Not sure what you're trying to accomplish here, but your haml does say "wrap this in a div." If you leave the #test out, the images will be contained in the parent surrounding block.

Re: Haml -- A Great Alternative to RHTML

Well yes I understand..Which is why I'm thinking what I need isn't possible in haml..
Here's the result I'd need:

<div><img><img></div>

So no whitespace or newlines at all.

12

Re: Haml -- A Great Alternative to RHTML

What does the .haml look like?

Re: Haml -- A Great Alternative to RHTML

Well, as you said it'd have to look like this no?

 #mydiv= image_tag('foo') + image_tag('bar')

14

Re: Haml -- A Great Alternative to RHTML

Strange... I pasted that exact code into one of my haml templates and got:

    <div id='mydiv'>
      <img alt="Foo" src="/images/foo.png" /><img alt="Bar" src="/images/bar.png" />
    </div>

Try freshening your copy of the plugin and see if things improve...

Re: Haml -- A Great Alternative to RHTML

hehe C dude you're missing what I'm trying to say wink

That's exactly what I'm getting too, but I want this:

<div id='mydiv'><img alt="Foo" src="/images/foo.png" /><img alt="Bar" src="/images/bar.png" /></div>

Notice no whitespace or newlines.. That's because if you fit some images to a <div> with a specific width (to fit exactly) Explorer tends put a space between the div and the first image breaking your layout..

Last edited by marsvin (2007-03-06 19:16:04)

16

Re: Haml -- A Great Alternative to RHTML

Is this a pervasive issue or only for some table-based IE layouts. If the latter, then a simple helper will give you exactly what you want. One thing Haml is big on is yanking stuff out into helpers and partials. Dunno if this is a good answer for you. I recommend you post a q on the Haml Google group. They're extremely helpful and quick to respond.

Re: Haml -- A Great Alternative to RHTML

Ah I hadn't thought of just adding a helper.. It's not a huge issue really, I'm trying to avoid layouts that break so easily these days anyway.

One of the reasons I asked is because I don't understand why one image_tag doesn't create newlines and two image tags do..

I.e. if I only use #test= image_tag("hmm") this happens:

<div id='test'><img alt="Hmm" src="/images/hmm.png" /></div>

But if I ever really need it I'll check out the group, thanks for giving it a go smile

Re: Haml -- A Great Alternative to RHTML

Not a big fan of the syntax either.  Hobo with DRYML is really outstanding; perhaps that might make folks looking at this as an alternative a little happier.  Also, cwd, thanks for this and please feel free to add to the Hobo information.  I know Tom over at HoboCentral is struggling getting documentation and such out and it would be great to see more folks involved in terms of bolstering the efforts to get folks trained up.

Last edited by ylon (2007-05-12 17:08:45)

Re: Haml -- A Great Alternative to RHTML

I will try to use HAML later,i think i really like it```

Last edited by mathsfan (2007-07-31 21:29:39)

Posts [ 19 ]

Pages 1