Kajiki si an XML/HTML template engine born as a replacement for Genshi with specific improvements for speed and an easier inheritance system based on blocks.
PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for
1. KAJIKI
THE FAST AND VALIDATED TEMPLATE
ENGINE YOU WERE LOOKING FOR
Alessandro Molina
@__amol__
amol@turbogears.org
2. Who am I
● Passionate Python Developer
● TurboGears2 core team member
● Beaker caching/session framework
current maintainer
● Author of DukPy js env for Python and
DEPOT file storage framework
● Contributor to Ming, ToscaWidgets2,
Formencode, WebOb, Kajiki, ...
3. Why?
● There are tens of template engines out
there, but people often only know the
default one of their web framework.
● Different template engines can differ in
important features, not just syntax.
● Working on one has been fun and
interesting.
4. Template Engines
TYPE NAME URL
Markup + Streamed Genshi http://genshi.edgewall.org/
Text + Compiled Mako http://www.makotemplates.org/
Text + Compiled Jinja http://jinja.pocoo.org/
Markup + Compiled Kajiki http://kajiki.readthedocs.io/
5. One more Template Engine?
● We loved the fact that Genshi templates
could by opened with any HTML editor
● We loved Genshi syntax, concise and
reflecting the output itself.
● We loved Genshi so much TG2.2 included
it in all projects, to make it available for
pluggable apps and extensions.
8. Well...
● Genshi was pretty complex. We didn’t
want to maintain such complexity.
● Streaming was powerful but hard to use,
very few people understood genshi
inheritance. And it was really slow.
● A TG team member was experimenting
with the idea of a similar engine.
11. How It Works
● Your template is parsed and converted to
Python code.
● Whenever the template is rendered the
generated python code is executed.
● The python code is yielded by a generator
that resembles the DOM of the document.
13. Compiled Kajiki
class template:
@kajiki.expose
def __main__():
yield u'<html>n <head>n <title>'
yield self.__kj__.escape(title)
yield u'</title>n </head>n <body>n <p>'
yield local.__kj__.gettext(u'These are some fruits:')
yield u'</p>n <ul>n '
for fruit in fruits:
yield u'<li>'
yield local.__kj__.gettext(u'n I like ')
yield self.__kj__.escape(fruit)
yield local.__kj__.gettext(u'sn ')
yield u'</li>'
yield u'n </ul>n </body>n</html>'
14. Rendered Kajiki
<html>
<head>
<title>A Kajiki Template</title>
</head>
<body>
<p>These are some fruits:</p>
<ul>
<li>
I like oranges
</li><li>
I like apples
</li>
</ul>
</body>
</html>
15. That makes it pretty Fast
● Mako
○ Rendered 1M mako templates in 22.217651844
● Kajiki
○ Rendered 1M Kajiki templates in 11.8710489273
%for user in users:
<span>Hello {{ user }}!</span>
%endfor
<span py:for="user in users">
Hello ${user}!
</span>
17. Don’t try this at home
● Huge hack, but theoretically it can work.
With minor tweaks Kajiki itself could
generate cython compatible code.
● Rendering python 11.86215686798
● Rederning cython 9.07893800735
20. Python Syntax Checking
kajiki.template.KajikiSyntaxError: [<string>:9]
invalid syntax
yield local.__kj__.gettext(u'These are some of
my favorite fruits:')
yield u'</p>n <ul>n '
--> for fruit on fuits:
yield u'<li>'
yield local.__kj__.gettext(u'n I like ')
21. Validated Templates
● As Kajiki understands the document you
are writing (it’s not just text) it can take
steps specific to HTML generation:
○ Error Reporting
○ Escaping
○ Automatic i18n
○ Minification
23. Escaping handled for us
<li py:for="fruit in fruits">
I like ${fruit}s
</li>
template(dict(
fruits=['<apple>'],
title='A Kajiki Template'
)).render()
<li>
I like <apple>s
</li>
24. Easy Translations
<li py:for="fruit in fruits">
I like ${fruit}s
</li>
for fruit on fuits:
yield u'<li>'
yield local.__kj__.gettext(u'n I like ')
25. Minification
tmpl = loader.load('plain.kajiki', strip_text=False)
<ul>
<li>
I like oranges
</li><li>
I like apple
</li><li>
I like kiwis
</li>
</ul>
tmpl = loader.load('plain.kajiki', strip_text=True)
<ul><li>I like oranges</li><li>I like apple</li><li>I like
kiwis</li></ul>
26. Text engine available too
>>> Template = kajiki.TextTemplate('''
... {%if foo %}
... bar
... {%else%}
... baz
... {%end%}
... ''')
>>> print(Template(dict(foo=True)).render())
bar
>>> print(Template(dict(foo=False)).render())
baz
27. Feel free to try it!
● Python 2.6, 2.7, 3.2, 3.3, 3.4 and 3.5
● pip install kajiki
● Come and try it!
https://github.com/nandoflorestan/kajiki
● Still young! Feel free to open issues, send
pull requests, suggest features!