Occasionally I have the need to generate some static HTML files. They may be for a static site or just as examples of how something will look. If the HTML is simple, I don’t mind typing it out by hand. But if there’s more to it, the repetitiveness of HTML tags starts to get to me. When I’m doing a Rails or Sinatra site, I use Haml for the HTML. So I wanted to be able to use Haml for generating static HTML as well.
The main entry point to using Haml from a command line is the Haml::Engine class. The documentation on using Haml directly like this is a little light, so I’ve created an example using it and made it available on Github.
In addition to just generating HTML from a Haml file, I also wanted to use some of the conveniences that are available when using Haml in a web setting. For me, this meant being able to use a layout file as a “wrapper” around content and being able to use partials to pull out repeated code.
Generation
The generate.rb file in my example has a fair number of comments, so I’ll just hit some of the high points here.
1 2 3 4 5 6 |
|
The first step is to instantiate an instance of Haml::Engine
pointing to the layout template. Then we need an instance of the Context
class to provide data to the templates as well as functions that can be called from within the templates. Next is a call to render
on the engine instance. We pass in the context object and a block - the block will be called when a yield
statement is encountered in the layout template. This is the core of what enables the use of a layout.
Inside the render block, a new Haml::Engine
instance is instantiated pointing to the “main” template being rendered. Then it’s just a call to render
on that instance, passing along the same Context
instance.
Partials
A quick word about the way I’m using partials. I wanted the ability to render common markup on multiple pages (or render page-specific markup in the layout); the same way you would use partials on the web.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
The implementation here is pretty simple and uses just a few conventions. Partials live in the partials
subfolder of the views
folder. The default filename for a partial is just the name of the partial. We also check for a file prefixed with the name of the enclosing template and use that if found. That allows us to use different content depending on the “main” template that’s being rendered (check out the “title” partials in the example). If neither the template-specific nor default partial is found, nil
is returned and nothing is rendered in the enclosing template.
1 2 3 4 5 |
|
Calling the partials from a template is straightforward. One thing to note is that the name of the function (render_partial
) is arbitrary - as long as the function exists on the Context
object that get passed to the render
method it can be called from within a template.
My example certainly doesn’t cover everything that could be done using Haml from the command line. But hopefully it’s enough of a start to give you some ideas.