Why type:
<div class="left" id="banner">
Greetings!
</div>
when you can just type:
.left#banner
Greetings!
... and do something more fun with all the time you save not typing angle brackets and remembering to close tags?
The syntax above is Haml - a templating language used extensively in the Ruby on Rails community. This library lets Django developers use a Haml like syntax in their templates. It's not a template engine in itself, but simply a compiler which will convert "HamlPy" files into templates that Django can understand.
This project is a fork of the no longer maintained HamlPy. It introduces Python 3 support, support for new Django versions, and a host of new features and bug fixes. Note that the package name is now django-hamlpy.
The latest stable version can be installed using pip:
pip install django-hamlpy
And the latest development version can be installed directly from GitHub:
pip install git+https://github.com/nyaruka/django-hamlpy
NOTE: If you run into build errors, then you may need to install python's development package.
Almost all of the syntax of Haml is preserved.
#profile(style="width: 200px")
.left.column
#date 2010/02/18
#address Toronto, ON
.right.column<
#bio Jesse Miller
turns into:
<div id='profile' style="width: 200px">
<div class='left column'>
<div id='date'>2010/02/18</div>
<div id='address'>Toronto, ON</div>
</div>
<div class='right column'><div id='bio'>Jesse Miller</div></div>
</div>
The main difference is instead of interpreting Ruby, or even Python we instead can create Django tags and variables. For example:
%ul#athletes
- for athlete in athlete_list
%li.athlete{'id': 'athlete_#{ athlete.pk }'}= athlete.name
becomes...
<ul id='athletes'>
{% for athlete in athlete_list %}
<li class='athlete' id='athlete_{{ athlete.pk }}'>{{ athlete.name }}</li>
{% endfor %}
</ul>
There are two different ways to use this library.
These are Django template loaders which will convert any templates with .haml
or .hamlpy
extensions to regular
Django templates whenever they are requested by a Django view. To use them, add them to the list of template loaders in
your Django settings, e.g.
TEMPLATES=[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['./templates'],
'OPTIONS': {
'loaders': (
'hamlpy.template.loaders.HamlPyFilesystemLoader',
'hamlpy.template.loaders.HamlPyAppDirectoriesLoader',
...
),
}
}
]
Ensure they are listed before the standard Django template loaders or these loaders will try to process your Haml templates.
You can use these loaders with template caching - just add django.template.loaders.cached.Loader
to your list of
loaders, e.g.
'loaders': (
('django.template.loaders.cached.Loader', (
'hamlpy.template.loaders.HamlPyFilesystemLoader',
'hamlpy.template.loaders.HamlPyAppDirectoriesLoader',
...
)),
)
You can configure the Haml compiler with the following Django settings:
HAMLPY_ATTR_WRAPPER
-- The character that should wrap element attributes. Defaults to'
(an apostrophe).HAMLPY_DJANGO_INLINE_STYLE
-- Whether to support={...}
syntax for inline variables in addition to#{...}
. Defaults toFalse
.
The library can also be used as a stand-alone program. There is a watcher script which will monitor Haml files in a given directory and convert them to HTML as they are edited.
usage: hamlpy_watcher.py [-h] [-v] [-i EXT [EXT ...]] [-ext EXT] [-r S]
[--tag TAG] [--attr-wrapper {",'}] [--django-inline]
[--jinja] [--once]
input_dir [output_dir]
positional arguments:
input_dir Folder to watch
output_dir Destination folder
optional arguments:
-h, --help show this help message and exit
-v, --verbose Display verbose output
-i EXT [EXT ...], --input-extension EXT [EXT ...]
The file extensions to look for.
-ext EXT, --extension EXT
The output file extension. Default is .html
-r S, --refresh S Refresh interval for files. Default is 3 seconds.
Ignored if the --once flag is set.
--tag TAG Add self closing tag. eg. --tag macro:endmacro
--attr-wrapper {",'} The character that should wrap element attributes.
This defaults to ' (an apostrophe).
--django-inline Whether to support ={...} syntax for inline variables
in addition to #{...}
--jinja Makes the necessary changes to be used with Jinja2.
--once Runs the compiler once and exits on completion.
Returns a non-zero exit code if there were any compile
errors.
HamlPy must first be included in Django's list of apps, i.e.
INSTALLED_APPS = [
...
'hamlpy'
...
]
Then just include your Haml templates along with all the other files which contain translatable strings, e.g.
python manage.py makemessages --extension haml,html,py,txt
Check out the reference file for the complete syntax reference and more examples.
This library also provides the same class based generic views than django with the enhancement that they start by looking for templates endings with *.haml
and *.hamlpy
in addition to their default templates. Apart from that, they are exactly the same class based generic views. For example:
from hamlpy.views.generic import DetailView, ListView
from my_app.models import SomeModel
# will look for the templates `my_app/somemodel_detail.haml`,
# `my_app/somemodel_detail.hamlpy` and `my_app/somemodel_detail.html`
DetailView.as_view(model=SomeModel)
# will look for the templates `my_app/somemodel_list.haml`,
# `my_app/somemodel_list.hamlpy` and `my_app/somemodel_list.html`
ListView.as_view(model=SomeModel)
The available view classes are:
Display views:
Edit views:
Date related views:
- DateDetailView
- ArchiveIndexView
- YearArchiveView
- MonthArchiveView
- WeekArchiveView
- DayArchiveView
- TodayArchiveView
All views are importable from hamlpy.views.generic
and are built using the HamlExtensionTemplateView
mixin which you
can use to create your own custom Haml-using views. For example:
from hamlpy.views.generic import HamlExtensionTemplateView
class MyNewView(HamlExtensionTemplateView, ParentViewType):
pass
Note: HamlExtensionTemplateView
needs to be first in the inheritance list.
We're always happy to have contributions to this project. To get started you'll need to clone the project and install the dependencies:
poetry install
Please write tests for any new features and always ensure the current tests pass. To run the tests, use:
py.test hamlpy
To run the performance test, use:
python -m hamlpy.test.test_templates