skip to navigation
skip to content

piglet 0.4.4

Piglet templates: fast, HTML aware templating engine

Piglet Templates
================

Piglet is a text and HTML templating language in the kid/genshi/kajiki family.

The Piglet template engine offers:

- Template inhertitance through py:extends/py:block (similar to Jinja2)
- Compiles templates to fast python byte code.
- HTML aware templating: output is well formed and content is
escaped, preventing XSS attacks.
- Reusable template functions, deep nesting of template inheritance,
flexible translations and embedded python expressions

`Documentation <http: ollycope.com="" software="" piglet=""/>`_
\| `Bitbucket repository <https: bitbucket.org="" ollyc="" piglet="">`_

This is what a piglet template looks like:

.. code:: html

<py:extends href="layout.html">

<py:block name="content">
<h1>This is the content block.</h1>
<p>
Hello $user.firstnames $user.lastname!
</p>


<p i18n:message="">
Today is <span i18n:name="day">${date.strftime('%a')}</span>.
</p>

<p py:choose="today.weekday()">
<py:when test="0">
I don't like Mondays
</py:when>
<py:when test="day == 4">
I never could get the hang of Thursdays
</py:when>
<py:otherwise>Is it the weekend yet?</py:otherwise>
</p>

<p py:for="verse in in poem">
<py:for each="line in verse">$line
</py:for>
</p>

</py:block>


There's a text templating mode too:

.. code::

Hello $user.firstnames $user.lastname!

{% trans %}
Today is {% transname "day" %}${date.strftime('%a')}{% end %}
{% end %}.

{% for verse in poem %}
{% for line in verse %}$line
{% end %}
{% end %}


Installation
------------

To install the latest release using pip (recommended):

.. code:: sh

pip install piglet


To install the latest source:

.. code:: sh

hg clone https://bitbucket.org/ollyc/piglet
cd piglet
python setup.py install



Using Piglet templates from the Python API
------------------------------------------

A simple example of rendering a python string to a template:

.. code:: python

from piglet import HTMLTemplate

template = HTMLTemplate('<p>$greeting</p)')<br> print(template.render({'greeting': 'Bonjour!'}))


Loading templates from disk:

.. code:: python

from piglet import TemplateLoader

loader = TemplateLoader(['./templates/'])
template = loader.load('mytemplate.html')
print(template.render({'greeting': 'Hello!'})


A fully loaded example:

.. code:: python

from piglet import TemplateLoader
import gettext

loader = TemplateLoader(
# List of directories to search for template files
['./templates/'],

# Auto reload templates when files are modified? Defaults to False,
# use True for development
auto_reload=True,

# The template class to use - either HTMLTemplate or TextTemplate
template_cls=HTMLTemplate,

# File encoding to use by default
default_encoding='UTF-8',

# A persistent on disk cache for piglet templates
cache_dir='.cache/piglet'

# A factory function returning a gettext Translations instance
# or compatible object. For example Django users could plug in
# `lambda: django.utils.translation`. If your app isn't translated
# omit this argument.
translations_factory=lambda: gettext.translation(...),

)
template = loader.load('mytemplate.html', encoding='UTF-8')

Templates can also be rendered as a stream. This might be useful for generating
long documents that you don't want to hold in memory all at once:

.. code:: python

template = loader.load('huge.html', encoding='UTF-8')
for s in template({'data': load_massive_dataset()}):
sys.stdout.write(s)



Inheritance
-----------

The layout template should be marked up with `<py:block>` tags
to indicate customization points:

.. code:: html


<html>
<head>
<title py:block="title">Default title</title>
</head>
<body>
<py:block name="content">
Content goes here
</py:block>
</body>
</html>


Child templates then use ``<py:extends href="...">`` to pull in the parent's
layout.


You can also define template functions:

.. code:: html


<py:def function="modal(content, title='hello')">
<div class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" data-dismiss="modal">X</button>
<h4 class="modal-title">$title</h4>
</div>
<div class="modal-body">
${content() if callable(content) else content}
</div>
<div class="modal-footer">
<button type="button">Close</button>
<button type="button">Save changes</button>
</div>
</div>
</div>
</div>
</py:def>


Template functions can be imported into other templates:

.. code:: html

<py:import href="widgets.html" alias="widgets"/>
<p>
${widgets.modal(content="Hello world!")}
</p>


Did you notice the ``${content() if callable content else content}``
interpolation in the function body? That's to support ``py:call``, which can
pass chunks of template code as keyword arguments:

.. code:: html

<py:call function="widgets.modal(fullpage=True)">
<py:keyword name="content">
This is the modal content. You can include
<a href="#">markup here</a> too!
</py:keyword>
</py:call>


License
-------

Piglet is licensed under the Apache license version 2.0.


0.4.4 (released 2017-01-08)
---------------------------

- py:extends: allow the 'href' attribute to contain interpolations, eg
``<py:extends href="${template}.html&gt;" ``<br="">- i18n: added a babel extractor plugin for text templates
- Bugfix: whitespace in translated strings is now correctly normalized
- Bugfix: fixed crash in text templates when using
``{% if %}...{% else %}...{% end %}`` blocks

0.4.3 (released 2016-11-29)
---------------------------

- Loader: an ``extension_map`` argument can be given, mapping file extensions
to template classes. By default ``.txt`` is mapped to
:class:`piglet.template.TextTemplate` and ``.html`` to
:class:`piglet.template.HTMLTemplate`.
- Bugfix: unicode symbols no longer cause an exception when used in template
expressions in Python 2.
- Bugfix: fixed multiple scoping issue with variable names used in
the argument lists of ``<py:def>`` template function directives.

0.4.2 (released 2016-11-08)
---------------------------

- Added <py:comment> directive
- Exceptions are now reraised, ensuring the originating traceback is shown.
- ``<py:call>`` Now passes its inner HTML as a positional argument, unless it
is whitespace.
- ``<py:call>`` is now an inner directive, meaning that
``<p py:call="foo()"></p>``
will now fill the ``<p>`` element rather than replacing it.
- The loader cache directory may be specified via the ``PIGLET_CACHE``
environment variable.
- Added i18n:comment directive

0.4.1 (released 2016-10-17)
---------------------------

- Added ``{% def %}`` and ``{% for %}`` text template directives
- Added ``allow_absolute_paths`` option to TemplateLoader

0.4 (released 2016-10-16)
-------------------------

- Bugfix: ensure ``<py:else>`` directives are always attached to the correct
``<py:if>``
- Added ``i18n:trans`` as an alias for i18n:translate
- ``i18n:name`` directives now have a shorter alias
(``i18n:s``, for substitution) and can take an optional expr attribute,
eg ``<i18n:s name="foo" expr="calculate_foo()"/>``
- Interpolations in translated strings are now extracted using the
interpolation text as a placeholder in the absence of a
``i18n:name`` directive
- ``py:whitespace="strip"`` no longer strips whitespace between tags
on the same line.
- Text template directives now include ``{% with %}``,
``{% extends %}`` and ``{% block %}``
- <py:extend> can now be used to load a template of the same name elsewhere
on the template search path.
- The search algorithm used by TemplateLoader is improved
- Bugfix: fix for duplicate rendering when super() is used in the middle of the
inheritance chain
- Generated code uses ``yield from`` where it supported by the python version.
- The caching code has been simplified, caching .py files to disk containing
the compiled python source.
- Bugfix: ``py:attrs`` no longer raises an exception
- Bugfix: interpolations can now contain entity references


0.3 (released 2016-10-03)
-------------------------

- The translation code now normalizes whitespace in i18n:messages
- Bugfix: fixed extraction of translations within ``<py:else>`` blocks
- Added translation support in text templates

0.2 (released 2016-10-02)
-------------------------

- Bugfix: ensure that grammar files are included in binary distributions
- Bugfix: fix for undefined variable error when using py:with to reassign
a variable

0.1 (released 2016-10-01)
-------------------------

- initial release
 
File Type Py Version Uploaded on Size
piglet-0.4.4.tar.gz (md5) Source 2017-01-08 51KB