Skip to content

ksava/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.

Mixins

We have function delaration/calling syntax similar to SASS-style mixins. E.g.:

@make_ol(*args)
    %ol - for arg in args:
        %li ${arg}

+make_ol(1, 2, 3)

renders to:

<ol>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

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

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

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