Any line that is not interpreted as something else will be taken as plain text and outputted unmodified. For example:
%gee
%whiz
Wow this is cool!
is compiled to:
<gee>
<whiz>
Wow this is cool!
</whiz>
</gee>
You can specify a specific doctype after the !!! The following doctypes are supported:
!!!
: XHTML 1.0 Transitional!!! Strict
: XHTML 1.0 Strict!!! Frameset
: XHTML 1.0 Frameset!!! 5
: XHTML 5!!! 1.1
: XHTML 1.1!!! XML
: XML prolog
The percent character placed at the beginning of the line will then be followed by the name of the element, then optionally 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 and an opening and closing tag will automatically be generated.
Haml has three different styles for attributes which are all supported. For example:
%html{:xmlns => 'http://www.w3.org/1999/xhtml', :lang => 'en'}
%html{'xmlns': 'http://www.w3.org/1999/xhtml', 'lang': 'en'}
%html(xmlns='http://www.w3.org/1999/xhtml' lang='en')
are all compiled to:
<html xmlns='http://www.w3.org/1999/xhtml' lang='en'></html>
Long attribute dictionaries can be separated into multiple lines:
%script(type='text/javascript' charset='utf-8'
href='/long/url/to/javascript/resource.js')
Attributes without values can be specified using singe variable. For example:
%input(type='checkbox' value='Test' checked)
is compiled to:
<input type="checkbox" value="Test" checked />
Alternatively the values can be specified using Python's None
keyword (without quotes). For example:
%input(type='checkbox' value='Test' checked=None)
is compiled to:
<input type="checkbox" value="Test" checked />
The 'class' and 'id' attributes can also be specified as a Python tuple whose elements will be joined together. A 'class' tuple will be joined with " " and an 'id' tuple is joined with "_". For example:
%div{'id': ('article', '3'), 'class': ('newest', 'urgent')} Content
is compiled to:
<div id='article_3' class='newest urgent'>Content</div>
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 by chaining class names together with periods. They are placed immediately after a tag and before an attribute dictionary. For example:
%div#things
%span#rice Chicken Fried
%p.beans{'food':'true'} The magical fruit
%h1#id.class.otherclass La La La
is compiled to:
<div id='things'>
<span id='rice'>Chiken Fried</span>
<p class='beans' food='true'>The magical fruit</p>
<h1 id='id' class='class otherclass'>La La La</h1>
</div>
And,
%div#content
%div.articles
%div.article.title Doogie Howser Comes Out
%div.article.date 2006-11-05
%div.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>
These shortcuts can be combined with the attribute dictionary and they will be combined as if they were all put inside a list. For example:
%div#Article.article.entry{'id':'1', 'class':'visible'} Booyaka
is equivalent to:
%div{'id':['Article','1'], 'class':['article','entry','visible']} Booyaka
and would compile to:
<div id='Article_1' class='article entry visible'>Booyaka</div>
Because divs are used so often, they are the default element. If you only define a class and/or id using .
or #
then the %div will be implied. For example:
#collection
.item
.description What a cool item!
will compile to:
<div id='collection'>
<div class='item'>
<div class='description'>What a cool item!</div>
</div>
</div>
The forward slash character, when placed at the end of a tag definition, causes the tag to be self-closed. For example:
%br/
%meta{'http-equiv':'Content-Type', 'content':'text/html'}/
will compile to:
<br />
<meta http-quiv='Content-Type' content='text/html' />
Some tags are automatically closed, as long as they have no content. meta, img, link, script, br
and hr
tags are automatically closed. For example:
%br
%meta{'http-equiv':'Content-Type', 'content':'text/html'}
will compile to:
<br />
<meta http-quiv='Content-Type' content='text/html' />
There are two types of comments supported: those that show up in the HTML and those that don't.
The forward slash character, when placed at the beginning of a line, wraps all the 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>
-->
You can use Internet Explorer conditional comments by enclosing the condition in square brackets after the /. For example:
/[if IE]
%h1 Get a better browser
is compiled to:
<!--[if IE]>
<h1>Get a better browser</h1>
<![endif]-->
The hyphen followed immediately by the pound sign signifies a silent comment. Any text following this isn't rendered during compilation at all. For example:
%p foo
-# Some comment
%p bar
is compiled to:
<p>foo</p>
<p>bar</p>
The key difference in HamlPy from Haml is the support for Django elements. The syntax for ruby evaluation is borrowed from Haml and instead outputs Django tags and variables.
A line starting with an equal sign followed by a space and then content is evaluated as a Django variable. For example:
.article
.preview
= story.teaser
is compiled to:
<div class='article'>
<div class='preview'>
{{ story.teaser }}
</div>
</div>
A Django variable can also be used as content for any HTML element by placing an equals sign as the last character before the space and content. For example:
%h2
%a{'href':'stories/1'}= story.teaser
is compiled to:
<h2>
<a href='stories/1'>{{ story.teaser }}</a>
</h2>
You can also use inline variables using the #{...}
syntax. For example:
Hello #{name}, how are you today?
is compiled to
Hello {{ name }}, how are you today?
Inline variables can also be used in an element's attribute values. For example:
%a{'title':'Hello #{name}, how are you?'} Hello
is compiled to:
<a title='Hello {{ name }}, how are you?'>Hello</a>
Inline variables can be escaped by placing a \
before them. For example:
Hello \#{name}
is compiled to:
Hello #{name}
Django style ={...}
syntax is also optionally supported. If you are using the template loader
then ensure HAMLPY_DJANGO_INLINE_STYLE
is True
, and the two syntaxes can then be used interchangeably.
The hypen character at the start of the line followed by a space and a Django tag will be inserted as a Django tag. For example:
- block content
%h1= section.title
- for dog in dog_list
%h2
= dog.name
is compiled to:
{% block content %}
<h1>{{ section.title }}</h1>
{% for dog in dog_list %}
<h2>
{{ dog.name }}
</h2>
{% endfor %}
{% endblock %}
Notice that block, for, if and else, as well as ifequal, ifnotequal, ifchanged and 'with' are all automatically closed. Using endfor, endif, endifequal, endifnotequal, endifchanged or endblock will throw an exception.
This is not yet supported: %div{'attr':"- firstof var1 var2 var3"}
will not insert the {% ... %}
.
The workaround is to insert actual django template tag code into the haml. For example:
%a{'href': "{% url socialauth_begin 'github' %}"} Login with Github
is compiled to:
<a href="{% url socialauth_begin 'github' %}">Login with Github</a>
Sometimes we want to remove whitespace inside or around an element, usually to fix the spacing problem with inline-block elements (see "The Enormous Drawback" section of this article for more details).
To remove leading and trailing spaces inside a node ("inner whitespace removal"), use the <
character after an element. For example, this:
%div
%pre<
= Foo
is compiled to:
<div>
<pre>{{ Foo }}</pre>
</div>
To remove leading and trailing spaces around a node ("outer whitespace removal"), use the >
character after an element. For example, this:
%li Item one
%li> Item two
%li Item three
is compiled to:
<li>Item one</li><li>Item two</li><li>Item three</li>
Does not parse the filtered text. This is useful for large blocks of text without HTML tags, when you don’t want lines starting with . or - to be parsed.
Surrounds the filtered text with <script type="text/javascript"> and CDATA tags. Useful for including inline Javascript.
Surrounds the filtered text with <script type="text/coffeescript"> and CDATA tags. Useful for including inline Coffeescript.
Surrounds the filtered text with CDATA tags.
Surrounds the filtered text with <style type="text/css"> and CDATA tags. Useful for including inline CSS.
Surrounds the filtered text with <style type="text/stylus"> and CDATA tags. Useful for including inline Stylus.
Converts the filter text from Markdown to HTML, using the Python Markdown library.
You can also specify the enabled extensions using the setting HAMLPY_MARKDOWN_EXTENSIONS and assigning a list of valid extensions to it. See Markdown library extensions documentation for available extensions. For example:
HAMLPY_MARKDOWN_EXTENSIONS = ['extras']
This will output the filtered text with syntax highlighting using Pygments.
For syntax highlighting to work correctly, you will also need to generate or include a Pygments CSS file. See the section "Generating styles" in the Pygments documentation for more information.
Execute the filtered text as python and output the result in the file. For example:
:python
for i in range(0, 5):
print "<p>item %s</p>" % i
is compiled to:
<p>item 0</p>
<p>item 1</p>
<p>item 2</p>
<p>item 3</p>
<p>item 4</p>