If you are using haml as the template language in a Rails project, it can be
very annoying if some Rails plugin generator creates a bunch of erb files.
Or you have an existing Rails project where you want to migrate from erb to
haml. For converting between these languages, there is the excellent
html2haml
tool, which used to be bundled with the
haml gem but has
just been moved
to its own gem called html2haml.
With this tool, you can convert a single erb file to haml like this:
html2haml app/views/layout/application.html.erb app/views/layout/application.html.haml
While this works great for single files, it sucks when you have many templates that you want to convert many templates. Many blog posts suggest you to add a task to your Rakefile like this (untested):
require 'find'
desc "Convert all erb templates to haml"
task :html2haml do
Find.find('app/views').select { |f| f =~ /\.html\.erb$/ }.each do |filename|
sh "bundle exec html2haml #{filename} #{filename.sub(/erb$/, 'haml')}"
end
end
But if you are using zsh, you can do this even easier:
for f (**/*.html.erb) html2haml $f $f:r.haml
That could not be shorter. Zsh has advanced globbing where you can use **
to
match the current and all subdirectories. So **/*.html.erb
searches
recursively through all subdirectories for files that end in .html.erb
. With
the for loop for f (**/*.html.erb)
, we can execute a command for every file
matching that pattern using $f
for the filename. Now comes the best part:
zsh has build in
modifiers
which you can append to a variable. We use the r
modifier, which removes
the last extension from a filename. If $f
is set to foo.html.erb
, $f:r
is evaluated to foo.html
. Now we can append .haml
to get your target
filename. $f:r.haml
thus evaluates the the filename with the last extension
(which is .erb
) replaced by .haml
. Once you understand the zsh modifiers,
you can do a lot of tricks with your shell.
If don't mind loosing the original erb files, you can delete them in one go:
for f (**/*.html.erb) { html2haml $f $f:r.haml; rm $f }