evoque - managed eval-based freeform templating

Evoque is a full-featured and generic text templating system for python using a simple $-substitution syntax and providing support for flow control, nested templates, overlays, inter-template addressing and invocation, cache management, arbitrary python expressions, advanced python % operator string formatting, restricted execution, automatic cross-site scripting protection, advanced encoding guessing algorithm, and more.

Allowing only python expressions and a managed evaluation namespace, Evoque offers a surprising level of simplicity, versatility and performance.

Buzz

  • Full-featured pure python templating engine / 957 SLOC
  • Automatic input quoting / XSS protection
  • Restricted execution
  • Every text file is a template
  • Unicode
  • Simplicity
  • Speed

Snapshot

$overlay{site_base} $begin{table_row} $for{ col in row } <td>${col}</td>\ $else <td class="empty" colspan="7">empty row</td> $rof $end{table_row} <table> $for{ i, row in enumerate(table) } <tr$if{ i%2 } class="odd"$fi> #[ styled blueish ]# $evoque{#table_row} </tr> $rof </table> $evoque{table_legend, collection="tech_docs"} $evoque{data_disclaimer} $test{ table=[("a","b",3.0,"d","<escape-me/>","i","j")] }

Usage from within an application

Templates are always part of a Collection in a Domain, i.e. the Domain and default Collection instances are always created, be it explicitly or implicitly. The preferred way to load/retrieve a Template is via a Domain instance (if necessary this implicitly creates a default Collection instance):

domain = Domain("/home/user/templates") t = domain.get_template("snap.html") print t.evoque(vars())

It may sometimes be more convenient to instantiate directly (if necessary this implicitly creates both Domain and default Collection instances):

t = Template("/home/user/templates", "snap.html") print t.evoque(vars())

Basic benchmark

A small template, doing a variety of standard templating tasks such as looping, calling sub-templates, escaping of data, etc. Time is averaged over 2000 renderings.

EngineTimeQuotingVersionRemark
qpy0.86 msautomatic1.6automatic safe quoting, h8
evoque2.50 msautomatic
evoque_mq2.26 msmanualmanual quoting, no qpy
evoque_r3.09 msautomaticrestricted execution
mako2.73 msmanual0.1.10
genshi_text6.54 msmanual0.4.4
genshi15.03 msautomatic0.4.4xml mode