zerosum dirt(nap)

evolution through a series of accidents

zerosum dirt(nap)

Markaby vs Haml vs ERB for Page Templates

January 25, 2007 by nap · Comments

I’ve been spending some time lately looking at different templating packages for Rails, in hopes of finding something cleaner and sexier than the standard ERB (rhtml) recipe, that also helps avoid common HTML pitfalls that cause pages not to validate.

My search has pretty much boiled down to two candidates at this point. The first is Markaby, which has been around for a while now and lets us represent our XHTML in Ruby code. The other candidate is the new kid on the block, Haml, which just reached a 1.0 last week and has it’s own proprietary CSS-ish syntax. Let’s take a look at brief look at both of them…

Here’s some ERB:

<div class="column" id="content">
  <h2 class="entry_title"><%= h @thing.name %></h2>
  <div class="entry_link"><%= link_to('link', @thing.link) %></div>
</div>

This is probably what we’re all used to and there’s no arguing that it works well enough, but… Well, it’s kind of ugly, isn’t it? To represent this same thing in Markaby, we install the plugin and create a template with a .mab extension and stick this in it:

div.column.content! {
  h2.entry_title @thing.name
  div.entry_link link_to 'link', @thing.link
}

That sure looks better to me. Nice and compact, clean. The best part is that Markaby is actually valid Ruby syntax. This buys us a couple things: first of all, it means that our view won’t run at all if we end up with a syntax error in it, which in turn means that it’s valid XHTML. Slick.

The downside is, of course, performance. It requires rendering for every single tag and property, which makes it slow in comparison to ERB, since just the inline Ruby snippets in the rhtml file have to be processed and inserted into a mostly pre-rendered HTML template. I also have some minor gripes about the use of bang instead of pound for representing element IDs, and the fact that it blows up when I put a yield in my Markaby layout code (I have to use @content_for_layout, which is deprecated now).

Anyway, enough about that. Let’s talk about Haml for a second. Install the plugin, and create a view with a .haml extension. Here’s the same chunk of code we saw before written in Haml:

.column#content
  %h2.entry_title= @thing.name
  .entry_link= link_to('link', @thing.link)

Haml defines it’s own syntax, which borrows from familiar CSS markup, and takes advantage of whitespace sensitivity for nesting. This latter bit is great news if you’re one of those undercover Python people hiding amongst us (I’m not one of you, now go away). It generates really nice clean appropriately nested HTML for output too.

Although it’s fairly easy to read and satisfies our cleanliness criteria, there are some immediate downsides to the fact that the markup is proprietary. Firstly, it means the files still have to be parsed and re-rendered by Rails, for a performance hit — same as we’d get with Markaby or any other higher-level template language for that matter. It also means that your editor isn’t going to be able to help you with syntax highlighting unless it has explicit support through a plugin.

I can see why people like Haml, it’s compact and kind of fun (see the tutorial for more). But all things considered, I really can’t see any reason I’d use it instead of Markaby, which feels much more natural to me and has the added benefit of Ruby syntax validation. Perhaps if it were to represent a significant performance increase — this seems doubtful — but I haven’t seen any real benchmarks. In any case, I don’t think I’ll be using it any time soon.

If I were to choose one of these two, I’d have to go with Markaby. I’m quite smitten by the idea of writing template code in pure Ruby, and the syntax validation enforcement is extremely desirable. As bizarre as it may seem, I love the idea of a page failing to run because of a syntax error in my “HTML” markup. Still, the performance issues give me pause. An even bigger issue is that of fragment caching, which sadly seems to be currently busted in Markaby. So, all things considered, I guess I’m sticking with ERB in my view templates, coupled with assert_valid_markup for my validation testing needs. At least for now. Even thought it makes me cringe a bit.

If I’ve missed anything worth considering about either of these templates, or if there are other options, please drop me a line. I’d love to hear what the rest of the community is using for their high-volume web apps…

blog comments powered by Disqus