f l a m e . o r g

organized flames

Experiments with HAML

Posted on November 05, 2009

I decided to try HAML today, rather than the standard ERB templates. The jury is still out on if it is better or worse, but like many things Rails, it is better to just dive in and try it.

I have a little project (not yet released) which I’m converting over to use HAML. Since I also use rspec for testing, along with Cucumber and Webrat, I thought I had a long day ahead of me.

It turns out most of it can be made close to automatic, with just a little cleanup afterwards.

Using the rake task below, you can issue these two commands to convert your existing .html.erb views into.html.haml. The second target will convert the rspec view tests to expect haml. Renaming the spec tests is not required, but I like sanity.

  $ rake haml:convert:html
  $ rake haml:convert:spec

If you use a SCM (I still like Subversion best) you’ll want to remove the old files and add the new ones. For Subversion, I do:

  $ svn rm app/views/*/*.html.erb spec/views/*/*.html.erb_spec.rb
  $ svn add app/views/*/*.html.haml spec/views/*/*.html.haml_spec.rb

The main problems were that not all of the templates were properly indented, and “- end” lines appeared in the HAML templates. Fixing this was fast, as I really don’t have much in my templates yet as this is a new project. This step too could probably be done in an automated way. However, the indentation is probably going to require a bit of manual work.

While there, I also fixed up multi-line constructs generated with a much nicer compact format:

1   %h1
2     Title
3   %tr
4     %th
5       Heading
6     %th
7       Heading
8 ...

Compare with this:

1   %h1 Title
3   %tr
4     %th Heading
5     %th Heading
6 ...

And now for the rake task:

 1 # RAILS_ROOT/lib/tasks/haml_convert.rake
 3 require 'haml'
 4 require 'haml/exec'
 6 namespace :haml do
 7   namespace :convert do
 8     desc "Convert all *.html.erb files to *.html.haml"
 9     task :html do
10       Dir.glob("app/views/**/*.html.erb").each do |html|
11         puts html + "..."
12         Haml::Exec::HTML2Haml.new([html, html.gsub(".html.erb", ".html.haml")]).process_result
13         File.delete(html)
14       end
15     end
17     desc "Convert all *.html.erb_spec.rb files to *.html.haml_spec.rb"
18     task :spec do
19       Dir.glob("spec/views/**/*.html.erb_spec.rb").each do |oldname|
20         puts oldname + "..."
21         newname = oldname.gsub(".html.erb", ".html.haml")
22         nf = File.open(newname, "w")
23         File.open(oldname) do |of|
24           of.each_line do |line|
25             nf.puts line.gsub(".html.erb", ".html.haml")
26           end
27         end
28         nf.close
29         #File.delete(oldname)
30       end
31     end
32   end
33 end