You are on page 1of 26

Haml

XHTML Abstraction Markup Language

“Any sufficiently complicated rhtml partial contains an


ad hoc, informally-specified, bug-ridden, implementation
of half of Haml.”
Dan Grigsby of railspikes.com
What is Haml?
• Haml is based on one primary principal.
Markup should be beautiful.
• ...it was created for use in highly productive
environments. The beauty makes you faster.
• Stop using the slow, repetitive, and annoying
templates that you don’t even know how
much you hate yet.
Recreating Haml
• Original HTML document
<div class="product">
<div class="name">
Foo
</div>
<div class="price">
$100.00
</div>
<div class="updated_at">
9 Jan 15:13
</div>
<div class="actions">
<a href="/products/foo/purchases/new">buy</a>
</div>
</div>
Recreating Haml
• RHTML version of the page
<div class="product">
<div class="name">
<%= product.name %>
</div>
<div class="price">
<%= number_to_currency product.price %>
</div>
<div class="updated_at">
<%= product.to_s(:short) %>
</div>
<div class="actions">
<%= link_to 'buy', new_purchase_product_url(product) %>
<% if product.owners.find_by_user_id(session[:user_id]) -%>
<%= link_to 'sell', new_sale_product_url(product) %>
<% end -%>
</div>
</div>
Recreating Haml
• Dropping closing tags and block “end”
<div class="product">
<div class="name">
<%= product.name %>
<div class="price">
<%= number_to_currency product.price %>
<div class="updated_at">
<%= product.to_s(:short) %>
<div class="actions">
<%= link_to 'buy', new_purchase_product_url(product) %>
<% if product.owners.find_by_user_id(session[:user_id]) -%>
<%= link_to 'sell', new_sale_product_url(product) %>
Recreating Haml
• Removing <> Brackets
div class="product"
div class="name"
= product.name
div class="price"
= number_to_currency product.price
div class="updated_at"
= product.to_s(:short)
div class="actions"
= link_to 'buy', new_purchase_product_url(product)
- if product.owners.find_by_user_id(session[:user_id])
= link_to 'sell', new_sale_product_url(product)
Recreating Haml
• CSS shortcuts
div.product
div.name
= product.name
div.price
= number_to_currency product.price
div.updated_at
= product.to_s(:short)
div.actions
= link_to 'buy', new_purchase_product_url(product)
- if product.owners.find_by_user_id(session[:user_id])
= link_to 'sell', new_sale_product_url(product)
Recreating Haml
• Drop the div tags (this is valid Haml)
.product
.name
= product.name
.price
= number_to_currency product.price
.updated_at
= product.to_s(:short)
.actions
= link_to 'buy', new_purchase_product_url(product)
- if product.owners.find_by_user_id(session[:user_id])
= link_to 'sell', new_sale_product_url(product)
Comparison
<div class="product"> .product
<div class="name"> .name
<%= product.name %> = product.name
</div> .price
<div class="price"> = number_to_currency product.price
<%= number_to_currency product.price %> .updated_at
</div> = product.to_s(:short)
<div class="updated_at"> .actions
<%= product.to_s(:short) %> = link_to 'buy', new_purchase_product_url(product)
</div> - if product.owners.find_by_user_id(session[:user_id])
<div class="actions"> = link_to 'sell', new_sale_product_url(product)
<%= link_to 'buy', new_purchase_product_url(product) %>
<% if product.owners.find_by_user_id(session[:user_id]) -%>
<%= link_to 'sell', new_sale_product_url(product) %> Alternative syntax:
<% end -%>
.product
</div>
.name= product.name
</div>
.price= number_to_currency product.price
.updated_at= product.to_s(:short)
.actions
= link_to 'buy', new_purchase_product_url(product)
- if product.owners.find_by_user_id(session[:user_id])
= link_to 'sell', new_sale_product_url(product)
Haml Features
• Whitespace active

• Well-formatted markup

• DRY

• Follows CSS conventions

• Integrates with Ruby code

• Implements Rails templates with the .haml


extension
Using Haml

• Haml 1.8.0 was released on January 6, 2008


• gem install haml

• haml --rails path/to/app

• echo '.message Hello, World' | haml


# => “<div class='message'>Hello, World</div>”
Using Haml
• XML tags are specified with a %tagname
%one
%two
%three Hello, World

<one>
<two>
<three>Hello, World</three>
</two>
</one>
Using Haml
• Brackets {} represent a Ruby hash that is used for
specifying the attributes of an element.

%head{ :name => 'document_head' }


%script{ 'type' => "text/" + "javascript", :src => "javascripts/script_#{2 + 7}.js" }

<head name='document_head'>
<script src='javascripts/script_9.js' type='text/javascript'></script>
</head>
Using Haml
• Square brackets [] use the dom_id and
dom_class methods to tag the element.
%div[@user]
%div[290] Hello!

<div class='user' id='user_15'>


<div class='fixnum' id='fixnum_581'>Hello!</div>
</div>
Using Haml
• . and # assign classes and ids, respectively.

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

<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>
Using Haml
• = is a shortcut for inserting Ruby code into an
element.
#hello_1= "<span>Hello</span>"
#hello_2=h "<span>Hello</span>"

<div id='hello_1'><span>Hello</span></div>
<div id='hello_2'>&lt;span&gt;Hello&lt;/span&gt;</div>
Using Haml
• - designates a Ruby block that should not be outputted.
(notice no need for end)
- (12...14).each do |i|
%p= i
%p See, I can count!
%p.array
- if [].blank?
%span.blank The array was blank.
- else
%span.notblank The array was not blank.

<p>12</p>
<p>13</p>
<p>See, I can count!</p>
<p class='array'>
<span class='blank'>The array was blank.</span>
</p>
Sass
Syntactically Awesome StyleSheets

• Basically just another way of writing CSS.


• Like Haml, it is designed to be very DRY
and help you write CSS faster.
• Supports nested selectors, constants, and
simple arithmetic.
Using Sass
• Basic example of nested rules
#main p #main p {
:color #0f0 color: #0f0;
:width 97% width: 97%; }
.redbox #main p .redbox {
:background-color #f00 background-color: #f00;
:color #000 color: #000; }
Using Sass
• Simple Sass can equal complex CSS
#main #main {
:width 97% width: 97%; }
p, div #main p, #main div {
:font-size 2em font-size: 2em; }
a #main p a, #main div a {
:font-weight bold font-weight: bold; }
pre #main pre {
:font-size 3em font-size: 3em; }
Using Sass
• Constants and simple arithmetic
!bg_color = #0f0 #container {
!main_width = 700px width: 800px; }
!side_width = 100px #container #main {
background-color: #00ff00;
#container color: #20ff20;
:width = !main_width + !side_width width: 700px; }
#main #container #side {
:background-color = !bg_color width: 100px; }
:color = !bg_color + 32
:width = !main_width
#side
:width = !side_width
Using Sass
• Advanced Sass with parent selectors
a {
a
color: #00f; }
:color #00f
a.disabled {
&.disabled
color: #999 !important; }
:color #999 !important
a:link, a:active, a:visited {
&:link, &:active, &:visited
text-decoration: none; }
:text-decoration none
a:link span.hidden, a:active
span.hidden
span.hidden, a:visited span.hidden {
:display none
display: none; }
&:visited
a:visited {
:color #00c
color: #00c; }
&:hover
a:hover {
:text-decoration underline
text-decoration: underline; }
Performance

Haml 1.7.2
ERB
Performance

Haml
ERB
Erubis
Markaby
Performance

Haml
ERB
Erubis
Haml in the Wild

• MyStock mystock.com
• Rails 2 with Haml trunk

• Grand Harmony Spa grandharmonyspa.com


or 029a630.netsolhost.com (until DNS fixed)
• Generated with StaticMatic using Haml 1.7.2

You might also like