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.

This site is a digital habitat of Sameer Borate, a freelance web developer working in PHP, MySQL and WordPress. I also provide web scraping services, website design and development and integration of various Open Source API's. Contact me at metapix[at]gmail.com for any new project requirements and price quotes.

6 Responses

1

huarong

September 9th, 2010 at 6:34 pm

not a good template engine.
I prefer smarty.

2

nexik

September 10th, 2010 at 1:29 am

I prefer php

3

LG

September 10th, 2010 at 3:22 am

If you are familiar with xml/xslt than TAL http://phptal.org/ is the way to go. Always valid xhtml, pure xml syntax, damn fast.

4

Johnish

January 26th, 2011 at 10:37 am

How do you have the haml select an option? ie. 1

sameer

January 26th, 2011 at 9:16 pm

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.

6

Marc Weber

March 29th, 2011 at 4:06 pm

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).

Your thoughts