pyconie 2016 - kajiki, the fast and validated template engine your were looking for
TRANSCRIPT
![Page 1: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/1.jpg)
KAJIKITHE FAST AND VALIDATED TEMPLATE
ENGINE YOU WERE LOOKING FOR
Alessandro Molina@__amol__
![Page 2: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/2.jpg)
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, ...
![Page 3: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/3.jpg)
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.
![Page 4: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/4.jpg)
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/
![Page 5: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/5.jpg)
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.
![Page 6: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/6.jpg)
Right Timing...
![Page 7: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/7.jpg)
How I felt...
![Page 8: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/8.jpg)
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.
![Page 9: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/9.jpg)
Kajiki<html>
<head>
<title py:content="title">This is replaced.</title>
</head>
<body>
<p>These are some fruits:</p>
<ul>
<li py:for="fruit in fruits">
I like ${fruit}s
</li>
</ul>
</body>
</html>
![Page 10: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/10.jpg)
Directives● py:if & py:else● py:switch & py:case & py:else● py:for● py:def● py:strip● py:with● py:attrs● py:block & py:extends● ...
![Page 11: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/11.jpg)
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.
![Page 12: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/12.jpg)
Architecture
PARSER
COMPILER
INTERMEDIATE REPRESENTATION
PYTHON
READ XML AND GENERATE DOM OUT OF IT WITH SAX
NAVIGATE DOM AND CREATE IR FOR ITS NODES
ITERATE THE IR NODES TO GENERATE PYTHON CODE
RUN PYTHON CODE TO RENDER TEMPLATE
![Page 13: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/13.jpg)
Compiled Kajikiclass 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's\n ')
yield u'</li>'
yield u'\n </ul>\n </body>\n</html>'
![Page 14: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/14.jpg)
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>
![Page 15: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/15.jpg)
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>
![Page 16: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/16.jpg)
It’s really just python! Mad science included!import kajiki
loader = kajiki.FileLoader('.', force_mode='xml')
tmpl = loader.load('mypage.kajiki')
with open('cython_test.pyx', 'wb') as pyx:
py_text = tmpl.py_text.replace('@kajiki.expose', '@staticmethod')
py_text = py_text.replace('__main__():', '__main__(self, local, users):')
py_text = py_text.replace('template = kajiki.Template(template)', '')
pyx.write(py_text)
import pyximport; pyximport.install()
import cython_test
class template:
@kajiki.expose
def __main__():
return cytmpl.__main__(self, local, users)
template = kajiki.Template(template)
print template(dict(cytmpl=cython_test.template, users=range(100000))).render()
![Page 17: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/17.jpg)
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
![Page 18: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/18.jpg)
But being Python is easy to debug
![Page 19: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/19.jpg)
Integrates with Python debuggers
![Page 20: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/20.jpg)
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 ')
![Page 21: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/21.jpg)
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
![Page 22: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/22.jpg)
Malformed HTML Detection
kajiki.xml_template.XMLTemplateParseError:
[./plain.kajiki:10] mismatched tag
<li py:for="fruit in fruits">
I like ${fruit}s
--> </span>
</ul>
</body>
![Page 23: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/23.jpg)
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>
![Page 24: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/24.jpg)
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 ')
![Page 25: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/25.jpg)
Minificationtmpl = 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>
![Page 26: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/26.jpg)
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
![Page 27: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/27.jpg)
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!
![Page 28: PyconIE 2016 - Kajiki, the fast and validated template engine your were looking for](https://reader031.vdocuments.us/reader031/viewer/2022030312/58ede73a1a28abab538b4727/html5/thumbnails/28.jpg)
Questions?