Skip to content

startling/PyHAML

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pythonic HAML

This is an implementation of HAML for Python (2.5 through 2.7).

I have kept as much of the same syntax as I could, but there are some Rubyisms built into HAML that I simply cannot replicate. I have tried to stay true to the original features while adapting them to be Pythonic.

This package essentially cross-compiles PyHAML code into a Mako template. Ergo, all of your standard Mako syntax also applies to content which does not match any of the HAML syntax.

Markup Example

A simple PyHAML template:

#profile
  .left.column
    #date= print_date
    #address= current_user.address
  .right.column
    #email= current_user.email
    #bio= current_user.bio

A Mako template to do the same thing:

<div id="profile">
	<div class="left column">
		<div id="date">${print_date}</div>
		<div id="address">${current_user.address}</div>
	</div>
	<div class="right column">
		<div id="email">${current_user.email}</div>
		<div id="bio">${current_user.bio}</div>
	</div>
</div>

API Example

import haml
import mako.template

if your_templates_are_in_a_directory:

    # Build the template lookup.
    lookup = mako.lookup.TemplateLookup(["various", "template", "paths"],
        preprocessor=haml.preprocessor
    )
    
    # Retrieve a template.
    template = lookup.get_template('example_template.haml')

else: # You have some strings...

    # Write your HAML.
    haml_source = '.content Hello, World!'

    # Build your template.
    template = mako.template.Template(haml_source,
        preprocessor=haml.preprocessor
    )

# Render!
print template.render()

Reference

Herein lies our differences to the HAML reference.

Python syntax must be used as if calling a function that takes keyword arguments. Eg.:

%ul
    - for i in range(5):
        %li(id=['item', str(i)]) ITEM ${i}

renders to:

<ul>
    <li id="item_0">ITEM 0</li>
    <li id="item_1">ITEM 1</li>
    <li id="item_2">ITEM 2</li>
    <li id="item_3">ITEM 3</li>
    <li id="item_4">ITEM 4</li>
</ul>

If you want to pass in a class, use the keyword "class_". If you want to use attribute names with dashes, use camel case instead and it will be converted for you:

%meta(httpEquiv="Content-Type", content="text/html;charset=UTF-8")

renders to:

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

If you want to pass in any other non-identifier attribute names, you can expand a mapping in place. Eg.:

%div(class_='content', **{'not-valid-python': 'value'}) content

renders to:

<div class='content', not-valid-python="value">content</div>

You can also pass in mapping objects as positional objects. Eg.:

- attrs = dict(a='one', b='two')
%a(attrs)/

renders to:

<a a="one" b="two" />

We only output the XHTML style attribute. Eg.:

%input(type='checkbox', checked=True)

to

<input type="checkbox" checked="checked" />

Clearly this is now evaluating Python. It is evaluated in the Mako runtime context.

We are using Mako to do the heavy lifting here.

We don't supply any filters, but the mechanism is there to take callables from the runtime globals to use as a filter. Eg.:

-! def to_upper(x):
    return x.upper()
:to_upper
    %p The syntaxes, they do nothing!
    #id x
    .class x
    - statement
    / comment

Haven't gotten around to these yet...

About

Pythonic implementation of HAML, cross compiling to Mako template syntax.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 100.0%