Haml 1.8.0

Posted January 7, 2008

Haml 1.8.0, Zippy Zoe, was released at about 9:05 Pacific Time on January 6th. It should have hit all the RubyGems mirrors by now.

Getting It

First Time?

If you’re new to Haml, I’d reccommend first reading the tutorial and maybe the overview. Then you can install it by running

gem install haml --no-ri

Then to install it on a Rails app, run

haml --rails path/to/app

It’ll just work for Merb.

Old hand?

If you already have an older version of Haml installed, just run

gem update haml --no-ri

and you’re good to go.

If you’re using Haml with Rails and you installed it using haml --rails, this is all you need to do. Otherwise, get rid of any existing Haml plugin directories, and run

haml --rails path/to/app

The Name

This version’s name comes from the substantial speed increase in version 1.8. These come from two sources. First, there’s a bunch more prerendering done, thanks to Tom Bagby.

Haml 1.8 also finally handles caching properly. This means that it has an external caching API that allows calling code to use its knowledge of filenames and modification times to avoid all unnecessary work, even reading in the template file, when re-rendering an already-compiled Haml template.

Of course, support for this is built into the Rails bindings. My benchmarking seems to show that Haml is now only 5% to 12% slower than ERB when run through ActionView. When run outside of actionview, ERB is actually slower than Haml, so we should be able to improve this performance even more. That’s something we’ll work on for 1.9.

Merb version 5, which is due to be released very soon, will also make use of the new caching capabilities.

The name “Zoe” was chosen more or less arbitrarily. It was the first female name beginning with “Z” that the folks on #haml1 came up with, since we appear to be alternating genders (Sam, Sally, Tom, and now Zoe). I also have a cousin named Zoe, so let’s say it’s in honor of her.

Compatibility

We want to get Haml running well with as much stuff as possible. Haml 1.8 adds support for the following platforms and environments:

Ruby 1.9

As a disclaimer, let me say first and foremost Haml 1.8.0 has not been sufficiently tested under 1.9. Several of the testing dependencies, such as Hpricot and ActionPack, weren’t working with Ruby 1.9 last I checked. In addition, it’s a pain to test against multiple Ruby versions, although I’m looking into ZenTest’s multiruby to help out with this.

However, despite that, Haml 1.8 includes various fixes to ensure that neither Haml nor Sass have any immediately obvious fatal errors when running under Ruby 1.9. I’ve even had reports that various people have successfully used it.

JRuby

There appeared to be a minor issue with Haml 1.7.x that caused it to die when run on JRuby. This is fixed in Haml 1.8.0.

Rails 2.0.1+

Rails 2.0.1 introduced a new system for templating engines that gives significantly more power to the engine than the old system. Haml 1.7.x wasn’t compatible with this new system, but Haml 1.8 is.

What’s New?

A ton of stuff. Not only is everything from 1.7.1 and 1.7.2 there, including Sass support for Merb, but a ton of more feature-oriented work was put in while those were being developed. I’ll try to go over as much as I can here.

CSS Directives

All sorts of CSS directives are now supported in Sass. The usage is very intuitive:

@media print
  #sidebar
    display: none
  body
    background-color: white

This renders as

@media print {
  #sidebar {
    display: none; }

  body {
    background-color: white; } }

Sass :compressed Style

Sass supports a new output style: :compressed. This style isn’t meant for human-readability - rather, it’s meant for compression. It adds no characters that aren’t syntactically necessary, other than a Unixy newline at the end of the file.

For example, for this input:

#main
  background-color: red
  p
    color: blue
    opacity: 0.5

#sidebar
  width: 20em
  float: left

The following compressed output is rendered:

#main{background-color:red}#main p{color:blue;opacity:0.5}#sidebar{width:20em;float:left}

would have rendered as

Executables

Ever since we introduced the haml command-line executable in version 1.0.0, the interfaces have gotten progressively better. That pattern continues in 1.8.

For example, both haml and sass read from standard input by default if no input file is provided. While in 1.7 you had to provide a --stdin or --stdio/-s flag, now you can just run

$ echo '%ui.snazzy/' | haml
<ui class='snazzy' />

In addition, both haml and sass provide --check/-c flags similar to Ruby’s. These flags cause the engines not to actually render their templates, but to give output indicating whether or not the templates are syntactically valid.

sass offers a --style/-t option that allows you to set the output style. For example:

$ echo -e '#main\n  :color red' | sass -t compact
#main { color: red; }

Finally, html2haml has a new --xhtml/-x option that causes it to use Hpricot’s stricter XHTML parser to read its input files.

Haml Attributes

Since 1.7.0, you’ve been able to use a Ruby method that returns a hash in place of literal hashes for Haml attributes. For example,

# Defined in some helper file
def hidden_if(cond)
  {:style => cond ? "display: hidden;" : nil}
end
-# Some Haml file
#sidebar{hidden_if(hide_sidebar?)}
  / Sidebar content

However, this required ugly tricks to merge in any additional attributes you might want. Thus, Haml 1.8 allows you to pass in as many hash-returning functions as you want, in addition to a literal hash at the end – just like a Ruby method.

%html{html_attrs, page_class, :style => "background-image: url(/images/eyebleed.gif);"}

(Relatively) Little Stuff

  • There’s a new helper, Haml::Helpers#init_haml_helper, which allows you to set up an environment in which you can run Haml helpers without actually rendering a Haml template.
  • Sass supports multiline selectors.
  • The Sass :attribute_syntax can be used to force either traditional attributes of the form :name value or new-style attributes of the form name: value.
  • Sass supports Rails-like partials: templates beginning with an underscore (like “_colors.sass”) can be included without the underscore and won’t be directly rendered.
  • Sass updates templates whenever any of the templates it includes via @import is updated, not just when the template itself is updated.
  • ActionPack is now not loaded until it’s being used, decreasing memory usage outside of a Rails context.
  • The benchmark Rake task is much nicer and more rigorous.
  • !important can now be used in dynamic Sass attributes.
  • Sass rules can be preceded with a backslash to escape meaningful characters like :.

Thanks!

Tons of people helped out on the way from 1.7 to 1.8. Here’s a list, grepped from the Subversion logs. I may have missed some people, and I know I don’t have some folks real names. If you have a correction, please let me know.

  • Benoit Caccinolo
  • Michael O’Malley
  • Sean Tan
  • manveru
  • Evgeny Zislis
  • Mislav Marohnić
  • Jan Szumiec
  • Ryan T Mulligan
  • Gioele
  • Nick S
  • Max Muermann
  • Toons
  • Polar Humenn
  • Jonah Fox
  • François Beausoleil
  • smok
  • Simon Peter Nicholls
  • Kiril Angov
  • Steven Garcia
  • Thomas Brian
  • Jonathan del Strother
  • JBC
  • Dylan Bruzenak
  • Ingo Weiss
  • Tim Pease
  • James Walker
  • Julien Thewys
  • Bob Aman
  • Rich Morin
  • Hrvoje Marjanovic
  • Brent Beardsley
  • Florian Aßmann
  • Xin
  • Yehuda Katz
  • Tom Bagby
  • Hampton Catlin
  • Nathan Weizenbaum

1 On freenode. Come join us some time, it’s lots of fun.

Hugh said January 08, 2008:

Awesome, a big thanks to everyone listed :)

Geoff said January 08, 2008:

Very nice work, HAML keeps me feeling nice and warm in these cold winter months :-P

Make your comments snazzy with Textile!