Tonnikala is the latest reincarnation among the Python templating languages that feed on Kid-inspired XML syntax. It rejects the Kid and Genshi notions of tagstreams and trees, and follows in footsteps of Chameleon and Kajiki in making the template to compile into Python bytecode directly. The syntax is very close to that of Kajiki, but the internals are very different: Tonnikala writes code as Abstract Syntax Trees and optimizes the resulting trees extensively. In addition, there is an optional speed-up module (currently Python 3 only), that provides a specialized class used for output buffering.
from tonnikala.loader import Loader
template_source = u"""
<table>
<tr py:for="row in table">
<py:for each="key, value in row.items()"
><td>${key}</td><td>${literal(value)}</td></py:for>
</tr>
</table>
"""
template = Loader().load_string(template_source)
ctx = {
'table': [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10)
for x in range(1000)]
}
print(template.render(ctx))
<html>
<title><py:block name="title_block">I am ${title}</py:block></title>
<h1>${title_block()}</h1>
</html>
<py:extends href="base.tk">
<py:block name="title_block">But I am ${title} instead</py:block>
</py:extends>
To load templates from files, use the tonnikala.FileLoader
class:
loader = FileLoader(paths=['/path/to/templates'])
template = loader.load('child.tk')
A FileLoader
currently implicitly caches all loaded templates in memory.
To render the template:
result = template.render(ctx)
You can specify a block, or no-argument def to render explicitly:
result = template.render(ctx, funcname='title_block')
Alpha, working features are
- Structural elements
py:if
,py:unless
,py:def
,py:for
,py:replace
,py:content
- Basic template inheritance:
py:extends
andpy:block
; the child template also inherits top level function declarations from the parent template, and the child can override global functions that the parent defines and uses. - Expression interpolation using
$simple_identifier
and${complex + python + "expression"}
- Boolean attributes:
<tag attr="${False}">
,<tag attr="$True">
- Implicit escaping
- Disabling implicit escaping (
literal()
) - C speedups for both Python 2 and Python 3
Upcoming features:
- Structural elements:
py:vars
,py:switch
,py:case
;py:else
forfor
,if
andswitch
. - Overriding attributes, setting attrs from dictionary:
py:attrs
- Custom tags mapping to
py:def
- I18N with optional in-parse-tree localization
- Javascript as the target language
- Pluggable frontend syntax engines (partially done)
- METAL-like macros
- Pluggable expression languages akin to Chameleon
- Even better template inheritance
- Importing def blocks from another template:
py:import
- Documentation (started)
- Pyramid integration
Antti Haapala