Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python Web Templating Battle

ivanteoh
August 18, 2012

Python Web Templating Battle

Talk in PyCon Australia 2012. Head to head - popular templating engines using in the Python world will be compared and contrasted. Increasingly, frameworks allow many different choices in templating engines. In this talk I’ll discuss the different approaches, demo and pros and cons to help you decide if there is a better templating engine for you.

ivanteoh

August 18, 2012
Tweet

Other Decks in Programming

Transcript

  1. • Introduction • 5 Web Templates ◦ Features ◦ Template

    Syntax ◦ Template Loader • Summary Content
  2. PretaWeb specialises in the provision and support of high availability,

    dedicated and SaaS CMS solutions for government Pretaweb
  3. The opinions expressed herein are my own personal opinions and

    do not represent my employer's view in any way. Disclaimer
  4. Web Template A web template is a tool used to

    separate content from presentation in web design. It is a basic component of a web template system. A Web template system describes the software and methodologies used to produce web pages. Such systems process web templates, using a template engine. - Wikipedia
  5. Templates • Django Template Language (http://www. djangoproject.com/) • Chameleon (http://chameleon.repoze.org/)

    • Jinja2 (http://jinja.pocoo.org/) • Diazo and XSLT (http://docs.diazo.org/) • Mako (http://www.makotemplates.org/)
  6. Django Template Language • text based template language • define

    variables and basic control logic • used in Django web framework • custom tag and filter in Python code
  7. Django - Template Syntax {% extends "base_generic.html" %} {% block

    title %}{{ section.title }}{% endblock %} {% block content %} <h1>{{ section.title }}</h1> {% for story in story_list %} <h2> <a href="{{ story.get_absolute_url }}"> {{ story.headline|upper }} </a> </h2> <p>{{ story.tease|truncatewords:"100" }}</p> {% endfor %} {% endblock %}
  8. Django - Custom Filter def lower(value): # Only one argument.

    """Converts a string into all lowercase""" return value.lower() register.filter('lower', lower) {{ somevariable|lower }}
  9. Django - Template loader from django.template import Context, Template t

    = Template("My name is {{ my_name }}.") c = Context({"my_name": "Ivan"}) t.render(c) def some_view(request): # ... return render_to_response('my_template.html', my_data_dictionary, context_instance=RequestContext(request))
  10. Chameleon • HTML/XML template engine • compiles into Python bytecode

    • the language used is page templates, originally a Zope invention • uses Python as the default expression language • used by Pyramid, Zope, Plone and Grok projects
  11. Chameleon - Template Syntax <html xmlns="http://www.w3.org/1999/xhtml"> <body> <!--! This comment

    will be dropped from output --> <div tal:repeat="item range(10)"> <p tal:condition="repeat.item.even">Even</p> <p tal:condition="repeat.item.odd">Odd</p> </div> <!--? This comment will be included verbatim --> <div> <?python import pdb; pdb.set_trace() ?> <ul tal:switch="len(items) % 2"> <li tal:case="True">odd</li> <li tal:case="False">even</li> </ul> </div> </body> </html>
  12. Chameleon - Switch and case <ul tal:switch="len(items) % 2"> <li

    tal:case="True">odd</li> <li tal:case="False">even</li> </ul>
  13. Chameleon - Comment statement <!--! This comment will be dropped

    from output --> <!--? This comment will be included verbatim -->
  14. Chameleon - Extension import ast def uppercase_expression(string): def compiler(target, engine):

    uppercased = self.string. uppercase() value = ast.Str(uppercased) return [ast.Assign(targets= [target], value=value)] return compiler from chameleon import PageTemplate PageTemplate.expression_types ['upper'] = uppercase_expression <div tal:content="upper: hello, world" />
  15. Chameleon - Template loader import os path = os.path.dirname(__file__) from

    chameleon import PageTemplateLoader templates = PageTemplateLoader(os.path.join(path, "templates")) template = templates['hello.pt'] >>> template(name='John') '<div>Hello, John.</div>'
  16. Jinja2 • function/macros • text based template language • compiles

    down to the python bytecode • heavily inspired by Django and Python • general purpose template language
  17. Jinja2 - Template Syntax <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

    <html lang="en"> <head> <title>My Webpage</title> </head> <body> <ul id="navigation"> {% for user in users if not user.hidden %} <li>{{ user.username|e }}</li> {% endfor %} </ul> {# this is comment #} <h1>My Webpage</h1> {{ my_variable }} </body> </html>
  18. Jinja2 - Control Structures {% for user in users if

    not user.hidden %} <li>{{ user.username|e }}</li> {% endfor %}
  19. Jinja2 - Call {% macro render_dialog(title, class=’dialog’) -%} <div class="{{

    class }}"> <h2>{{ title }}</h2> <div class="contents"> {{ caller() }} </div> </div> {%- endmacro %} {% call render_dialog(’Hello World’) %} This is a simple dialog rendered by using a macro and a call block. {% endcall %}
  20. Jinja2 - Template Loader from jinja2 import Environment, PackageLoader env

    = Environment(loader=PackageLoader('yourapplication', 'templates')) template = env.get_template('mytemplate.html') print template.render(the='variables', go='here')
  21. Diazo - theme.html <html> <head> <title>My own Diazo</title> </head> <body>

    <h1 id="title">My own Diazo home page</h1> <div id="content"> <!-- Placeholder --> Lorem ipsum ... </div> </body> </html>
  22. Diazo - rules.xml <rules xmlns="http://namespaces.plone.org/diazo" xmlns:css="http://namespaces.plone.org/diazo/css" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <theme href="theme.html" />

    <drop theme="/html/head/title" /> <drop css:theme="#title" css:if-content="#content.wide" /> <replace css:theme-children="#content" css:content-children=".content" /> </rules>
  23. Diazo - Directives <theme /> <notheme /> <replace /> <before

    /> <after /> <drop /> <strip /> <merge /> <copy />
  24. Diazo and XSLT <replace css:theme="#details"> <dl id="details"> <xsl:for-each css:select="ul#details >

    li"> <dt><xsl:copy-of select="a" /></dt> <dd><xsl:copy-of select="img" /></dd> </xsl:for-each> </dl> </replace>
  25. Mako • is an embedded Python (i.e. Python Server Page)

    language • text based template language • compiles down to the python byte-code • function/macros • control structures constructed from real Python code (i. e. loops, conditionals) • straight Python blocks, inline or at the module-level
  26. Mako - Template Syntax <%inherit file="base.html"/> <% rows = [[v

    for v in range(0,10)] for row in range(0,10)] %> <table> % for row in rows: ${makerow(row)} % endfor </table> ## this is a comment. <%def name="makerow(row)"> <tr> % for name in row: <td>${name}</td> % endfor </tr> </%def>
  27. Mako - Module-level Blocks <%! import mylib import re def

    filter(text): return re.sub(r'^@', '', text) %>
  28. Mako - Template Loader from mako.template import Template mytemplate =

    Template(filename='/docs/mytmpl.txt') print mytemplate.render() from mako.template import Template mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules') print mytemplate.render()