Templating with Haml

It has been a while since I’ve used a template engine during development, the last one I used was Smarty. Now there are a plethora of template systems, but most are a rehash of Smarty. Readers may beg to differ, but Smarty gets the work done, which is all that matters. The one that I found really interesting is Haml.

Haml

Haml (HTML Abstraction Markup Language) is a lightweight markup language (or a meta markup language) which lets you create views for your Rails applications. But it can also be quite helpful for generating xhtml pages when used outside Rails. As I’m not a ROR developer my sole interest in Haml lies in using it to quickly create well formatted HTML files. Below is a short haml markup and its output. Haml comes with a standalone tool that lets you quickly convert haml markup to xhtml.

!!!
%html
   %head
      %title codediesel
   %body
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>codediesel</title>
  </head>
  <body></body>
</html>

A more involved example using a bit of Ruby code.

!!!
%html
   %head
      %title codediesel
   %body
      %h1 HAML
      / Demo of haml
      %div#main Lots of paragraphs
      %div#paras.list
         - (1...5).each do |i|
            %p= i
 
      / Lots of classes
      %div.myclasses
         - (1...4).each do |i|
            %div{:class => i}
 
      / a select element
      %select#color
         - ['red', 'blue', 'yellow', 'green'].each do |i|
            %option{:value => i}= i
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>codediesel</title>
  </head>
  <body>
    <h1>HAML</h1>
    <!-- Demo of haml -->
    <div id='main'>Lots of paragraphs</div>
    <div class='list' id='paras'>
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
    </div>
    <!-- Lots of classes -->
    <div class='myclasses'>
      <div class='1'></div>
      <div class='2'></div>
      <div class='3'></div>
    </div>
    <!-- a select element -->
    <select id='color'>
      <option value='red'>red</option>
      <option value='blue'>blue</option>
      <option value='yellow'>yellow</option>
      <option value='green'>green</option>
    </select>
  </body>
</html>

The useful thing about Haml for me is that I can use it to quickly generate xhtml skeleton files using a few haml markup files and a dash of shell scripting. Editing the haml markup is easier and quicker then editing the xhtml file, especially if the html happens to be a big one. Note that indenting is extremely important in the haml markup, so if you are just trying out haml, be prepared to encounter a bit of errors in the beginning. If you are new to Ruby and are interested in trying haml, I suggest you install the rubyinstaller environment. It works right of the box with many other required components pre-installed.

phpHaml

If you get interested in haml there is a php port of of the same called phpHaml and phamlp. Here we will take a look at phpHaml. phpHaml has nearly the same syntax as haml. So if you are tired of verbose templating codes then phphaml can be an interesting solution for php users. So instead of writing something like the following ( I always hated mixing markup and php):

.
.
    <div id="content">
      <table class="config list">
        <tr><th>ID</th><th>Name</th><th>Value</th></tr>
        <?php foreach ($config as $c) { ?>
          <tr class="<?php echo ($class = forClassName($c)); ?>"
                 id="<?php echo "$class_{$c->ID}"; ?>">
            <td><?php echo $c->ID; ?></td>
            <td><?php echo $c->name; ?></td>
            <td><?php echo $c->value; ?></td>
          </tr>
        <?php } ?>
      </table>
    </div>
.
.

You can write it in phphaml as below. Now that’s really some clean code. Not perfect, but better than the above.

#content
      %table.config.list
        %tr
          %th ID
          %th Name
          %th Value
        - foreach ($config as $c)
          %tr[$c]
            %td= $c->ID
            %td= $c->name
            %td= $c->value

An example

Below is a short example on using the phpHaml template. First we define the phpHaml markup. Let us call the file markup.haml and store it in a ‘tpl’ directory. Note: Make sure you keep the indentation at 2 spaces.

!!!
%html
  %head
    %title= $title
  %body
    %h1= $title
    %p= $text
    %select#colors.general
      - foreach ($colors as $c)
        %option{:value => $c}= $c

Update: 27th Jan 2011
If you need to select a particular element in the drop-down you can use the code below.

!!!
%html
  %head
    %title= $title
  %body
    %h1= $title
    %p= $text
    %select#colors.general
      - foreach ($colors as $c)
        - if($c == 'red')
          %option{:value => $c, :selected => 'selected'}= $c
        - else
          %option{:value => $c}= $c

We then call the above template from our php code, passing along some variables.

<?php
 
require_once './includes/haml/HamlParser.class.php';
 
$title = 'phpHaml Demo';
$text =  'A short example of the markup';
$colors = array("blue", "red", "green");
 
display_haml('./tpl/example3.haml', array());
 
?>

The following is what we get after rendering.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
  <head>
    <title>phpHaml Demo</title>
  </head>
  <body>
    <h1>phpHaml Demo</h1>
    <p>A short example of the markup</p>
 
    <select class="general" id="colors">
      <option value="blue">blue</option>
      <option value="red">red</option>
      <option value="green">green</option>
    </select>
  </body>
</html>

Although it looks good, there are some major drawbacks. First, the stringent rules for indention, mess that up and it can be quite frustrating to indent everything back again, and second the inability to easily breakup the markup into multiple files.



6 thoughts on “Templating with Haml

  1. Taking the example given above you can select a drop-down element as below:

    !!!
    %html
    %head
    %title= $title
    %body
    %h1= $title
    %p= $text
    %select#colors.general
    – foreach ($colors as $c)
    – if($c == ‘red’)
    %option{:value => $c, :selected => ‘selected’}= $c
    – else
    %option{:value => $c}= $c

    Keep an eye on the indention’s, or check the updated code above in the post.

  2. Read haml-lang.com and you’ll find that you can write it much nicer:

    – foreach ($colors as $c)
    %option{:value => $c, :selected => $c == ‘red’}= $c

    haml-to-php.com will get this support soon. phamlp is not strong enough to parse HAML like that. Also pay attention to quoting! haml-lang talks about != (no quoting) and = (html escaping takes place).

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>