Idea for pure-python templates using AST.
paul.wray at det.nsw.edu.au
Tue Aug 16 13:33:29 CEST 2011
Ive had what I think is a great idea for pure-python templates (I can almost
hear the groans, bear with me...)
For the impatient, proof of concept is at http://pastie.org/2379978
demonstrating simple substitution, balanced tags using context manager,
subtemplates, and template inheritance.
I'm posting here to get opinions on:
* the merits of the idea, (or otherwise!)
* whether there are any established/mature templating systems that use this
approach, or whether its come up before,
* ideas for improvements and advice on other aspects such as sandboxing
* of course, to share the idea in case others want to use it
Background: Ive been working on an application that recursively renders
html/xml documents from heterogenoeus trees, with separate classes for each
document component. First I built my own renderer but was dissatisfied with
the repetitive code. Then looked at Mako and Jinja, and used Jinja but was
still disatisfied, because I still needed a render method in each class to
do preparation, and also the template which was centrally managed by the
Jinja loader and environment. I found a way to call templates recursively
via Jinja filters, but was not sure that it wouldnt blow up in my face, so I
also had separate calls to render the children of each node, and then feed
the value to the parent template. I kept thinking that there must be a way
to get the brevity and clarity of declarative templates, plus the simplicity
of pure python loops, tests and function calls.
Python syntax allows a statement to be a bare literal or identifier. These
have no effect on the program.
So the function below is legal python:
x = 45
'b'; 'c'; x
So is this (within the appropriate class context of course):
def body(self, r):
'<h1>'; self.heading; '</h1>'
for itm in self.items:
'<li>'; itm; '</li>'
The idea is simply to use python ASTs to transform this code so that it
accumulates the values of the bare expressions.
I think this give the best of both worlds - declarative syntax for the
template literals, but in a pure python context, giving you all the power of
python control statements, classes etc.
For application contexts outside pure python code (ie user-created
templates) , it would be simple to extend the technique to creating template
functions from strings, and insert the resulting methods into a namespace
I think, given the technique is already working with the AST, that
sandboxing should not be too hard either - advice on this aspect would be
More information about the Python-list