Skip to content
This repository has been archived by the owner on Jul 7, 2020. It is now read-only.

Documentation

dxw edited this page Sep 13, 2010 · 3 revisions

Lots of the stuff on this page is borrowed from the original HAML Reference. Hopefully they won’t mind.

What’s HAML?

From the HAML Reference:

Haml is a markup language that’s used to cleanly and simply describe the XHTML of any web document, without the use of inline code. Haml functions as a replacement for inline page templating systems such as PHP, ERB, and ASP. However, Haml avoids the need for explicitly coding XHTML into the template, because it is actually an abstract description of the XHTML, with some code to generate dynamic content.

Features

  • Whitespace active
  • Well-formatted markup
  • DRY
  • Follows CSS conventions
  • Integrates PHP code

Using Fammel

  1. Check this repository out somewhere sensible
  2. Include “fammel.php” in your application
  3. For example use, see the fammel script, which you can also use to compile haml on the command line

We’re currently working on a Wordpress plugin that we’ll be using to write Wordpress themes in HAML. If you’d like to make available some code that integrates Fammel into your framework of choice, we’d be very happy to list it here.

Fammel Reference

Plain Text

A substantial portion of any HTML document is its content, which is plain old text. Any Haml line that’s not interpreted as something else is taken to be plain text, and passed through unmodified. For example:

%gee
  %whiz
    Wow this is cool!

is compiled to:

<gee>
  <whiz>
    Wow this is cool!
  </whiz>
</gee>

Note that HTML tags are passed through unmodified as well. If you have some HTML you don’t want to convert to Haml, or you’re converting a file line-by-line, you can just include it as-is. For example:

%p
  <div id="blah">Blah!</div>

is compiled to:

<p>
  <div id="blah">Blah!</div>
</p>

Escaping: \

The backslash character escapes the first character of a line, allowing use of otherwise interpreted characters as plain text. For example:

%title
  = $title
  \= $title

is compiled to:

<title>
  <?php echo htmlentities($title, ENT_COMPAT); ?>
  = $title
</title>

There’s some more stuff going on there that we’ll come back to later.

HTML Elements

Element Name: %

The percent character is placed at the beginning of a line. It’s followed immediately by the name of an element, then optionally by modifiers (see below), a space, and text to be rendered inside the element. It creates an element in the form of . For example:

%one
  %two
    %three Hey there

is compiled to:

<one>
  <two>
    <three>Hey there</three>
  </two>
</one>

Any string is a valid element name. Fammel will automatically generate opening and closing tags for any element.

Attributes: {}

Brackets enclose a list of names and values that is used for specifying the attributes of an element.

The list is placed after the tag is defined. For example:

%html{:xmlns => "http://www.w3.org/1999/xhtml", :xml:lang => "en", :lang => "en"}

is compiled to:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
</html>

Important note:

Attribute lists aren’t quite finished yet. They can currently only contain literal, static values. You can only use double quotes, and there’s no escaping. You also can’t spread attribute values over multiple lines, and there are no shortcuts for silly attributes like selected="selected". We aim to fix all this soon.

Class and ID: . and #

The period and pound sign are borrowed from CSS. They are used as shortcuts to specify the class and id attributes of an element, respectively. Multiple class names can be specified in a similar way to CSS, by chaining the class names together with periods. They are placed immediately after the tag and before an attributes hash. For example:

%div#things
  %span#rice Chicken Fried
  %p.beans{ :food => "true" } The magical fruit
  %h1.class.otherclass#id La La La

is compiled to:

<div id='things'>
  <span id='rice'>
    Chicken Fried
  </span>
  <p class='beans' food='true'>
    The magical fruit
  </p>
  <h1 class='class otherclass' id='id'>
    La La La
  </h1>
</div>

And,

#content
  .articles
    .article.title Doogie Howser Comes Out
    .article.date 2006-11-05
    .article.entry
      Neil Patrick Harris would like to dispel any rumors that he is straight

is compiled to:

<div id='content'>
  <div class='articles'>
    <div class='article title'>
      Doogie Howser Comes Out
    </div>
    <div class='article date'>
      2006-11-05
    </div>
    <div class='article entry'>
      Neil Patrick Harris would like to dispel any rumors that he is straight
    </div>
  </div>
</div>

Implicit Div Elements

Because divs are used so often, they’re the default elements. If you only define a class and/or id using . or #, a div is automatically used. For example:

#collection
  .item
    .description What a cool item!

is the same as:

%div#collection
  %div.item
    %div.description What a cool item!

and is compiled to:

<div id='collection'>
  <div class='item'>
    <div class='description'>
      What a cool item!
    </div>
  </div>
</div>

Doctype: !!!

When describing HTML documents with Haml, you can have a document type or XML prolog generated automatically by including the characters !!!. For example:

!!! XML
!!!
%html
  %head
    %title Myspace
  %body
    %h1 I am the international space station
    %p Sign my guestbook

is compiled to:

<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE html>
<html>
  <head>
    <title>
      Myspace
    </title>
  </head>
  <body>
    <h1>
      I am the international space station
    </h1>
    <p>
      Sign my guestbook
    </p>
  </body>
</html>

You can also specify the specific doctype after the !!!

!!!
!!! 5

<!DOCTYPE html>

!!! Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

!!! Frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

!!! 1.1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

!!! Basic

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"> 

!!! Mobile

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">

!!! 4.01 Transitional

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

!!! 4.01 Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

!!! 4.01 Frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

If you’re not using the UTF-8 character set for your document, you can specify which encoding should appear in the XML prolog in a similar way. For example:

!!! XML iso-8859-1

<?xml version='1.0' encoding='iso-8859-1' ?>

Comments

Haml supports two sorts of comments: those that show up in the HTML output and those that don’t.

HTML Comments: /

The forward slash character, when placed at the beginning of a line, wraps all text after it in an HTML comment. For example:

%peanutbutterjelly
  / This is the peanutbutterjelly element
  I like sandwiches!

is compiled to:

<peanutbutterjelly>
  <!-- This is the peanutbutterjelly element -->
  I like sandwiches!
</peanutbutterjelly>

The forward slash can also wrap indented sections of code. For example:

/
  %p This doesn't render...
  %div
    %h1 Because it's commented out!

is compiled to:

<!--
  <p>This doesn't render...</p>
  <div>
    <h1>
      Because it's commented out!
    </h1>
  </div>
-->

Haml Comments: -#

The hyphen followed immediately by the pound sign signifies a silent comment. Any text following this isn’t rendered in the resulting document at all.

For example:

%p foo
-# This is a comment
%p bar

is compiled to:

<p>
  foo
</p>
<p>
  bar
</p>

PHP Evaluation

Inserting PHP: =

The equals character is followed by PHP code. This code is evaluated and the output is inserted into the document. For example:

%p
  = implode(' ', array('hi', 'there', 'reader!'))
  = "Yo!"

is compiled to:

<p>
  <?php echo htmlentities(implode(' ', array('hi', 'there', 'reader!')), ENT_COMPAT); ?>
  <?php echo htmlentities("Yo!", ENT_COMPAT); ?>
</p>

= will sanitize any HTML-sensitive characters generated by the script by passing them through htmlentities.

= can also be used at the end of a tag to insert PHP code within that tag. For example:

%p= "hello"

would be compiled to

<p>
  hello
</p>

Running PHP: -

The hyphen character is also followed by PHP code. This code is evaluated but not inserted into the document.

It is not recommended that you use this widely. You should treat your HAML files as views. They should contain the least possible logic.

For example:

- $foo = "hello"
- $foo .= " there"
- $foo .= " you!"
%p= $foo

is compiled to:

<?php $foo = "hello" ?>
<?php $foo .= " there" ?>
<?php $foo .= " you!\n" ?>
<p>
  <?php echo htmlentities($foo, ENT_COMPAT); ?>
</p>

PHP Blocks

PHP blocks, like XHTML tags, don’t need to be explicitly closed. Rather, they’re automatically closed, based on indentation. A block begins whenever the indentation is increased after a PHP evaluation command. It ends when the indentation decreases (as long as it’s not an else clause or something similar). For example:

- foreach($things as $thing)
  %p= $thing
%p Those were some things.

is compiled to:

<?php foreach($things as $thing) { ?>
  <p>
    <?php echo htmlentities($thing, ENT_COMPAT); ?>
  </p>
<?php } ?>
<p>
  Those were some things.
</p>

Another example:

- if(true)
  %p True
- else
  %p False

is compiled to:

<?php if(true) { ?>
  <p>
    True
  </p>
<?php } else { ?>
  <p>
    False
  </p>
<?php }  ?>

Unescaping HTML: !=

An exclamation mark followed by an equals character evaluates PHP code just like the equals would, but never sanitizes the HTML.

!= "I feel <strong>!"
= "I feel <strong>!"

compiles to

<?php echo htmlentities("I feel <strong>!", ENT_COMPAT);  ?>
<?php echo "I feel <strong>!" ?>

Conclusion

Hopefully that’s been useful. Send us a message if you think there’s something missing.