[Web-SIG] Standardized template API

Phillip J. Eby pje at telecommunity.com
Wed Feb 1 01:43:25 CET 2006

At 05:01 PM 1/31/2006 -0600, Ian Bicking wrote:
>Phillip J. Eby wrote:
>>At 02:03 PM 1/31/2006 -0500, Clark C. Evans wrote:
>>>I'd stick with the notion of a "template_name" that is neither the
>>>template file nor the template body.  Then you'd want a template factory
>>>method that takes the name and produces the template body (complied if
>>>necessary).  This needs to be once indirect since a template may refer
>>>to other sub-templates. This way your template could be stored
>>>in-memory, on-disk, or in a database, or even remotely using an HTTP
>>>cashe.  The actual storage mechanism for the template source code should
>>>not be part of this interface.
>>I'd go even further than this, to note that frameworks need to be able to 
>>cache "compiled" versions of templates.  The template "engine" should be 
>>able to return a "compiled" template that the framework can use to do 
>>rendering in future.
>The plugin instance itself can manage the caching.  I believe current 
>implementations do that (at least TurboCheetah does).  Is there anything 
>the framework can do for caching that the plugin instance can't?

The plugin doesn't know how long to retain a compiled template if it's 
referenced only via strings.  If the plugin returns a compiled template 
object, then the framework can either hold onto it, or not.

>>Note too that frameworks such as Zope 3 and peak.web have concepts like 
>>localization and "skinning" that require the ability to switch out the 
>>actual provider of a named template or "view", and in at least the case 
>>of peak.web this can be polymorphic.  That is, one "skin" could implement 
>>template "foo" using Kid and another one using ZPT.  So the name of a 
>>template needs to be independent of its implementation language, or the 
>>ability to plug in different engines is moot.
>>(Currently, TurboGears embeds the chosen template language in code, which 
>>means a deployer can't skin the application effectively.)
>I believe that custom find_template implementations could handle these 
>cases.  Maybe there also needs to be a relative_to_template_name argument 
>to find_template, so that it can resolve template names relative to the 
>calling template (so, for instance, you can use relative names to the 
>template you inherit from).

I don't want plugins to affect *where* templates are retrieved from, or how 
their names are interpreted.  A template engine's only job should be to 
turn a string or stream into a template object.

What I was proposing we do was establish a common mechanism for finding 
templates and other resources, taking into account i18n, skinning, 
polymorphism, and eggs.  That would have a much greater impact on the 
Python web world than simply formalizing the Buffet/TurboGears plugin 

Indeed, I'd argue that it'd be better here to create a WSGI-based template 
interface, rather than a specialized template interface.  That is, if the 
"compiled template" returned by a template engine is just a WSGI 
application object, then it provides a maximum of flexibility.  If 
individual frameworks want to supply additional data or features, they can 
do so via additional environ keys.

Combine that with a resource-locating API, and we'd really be getting 
somewhere.  The way I see it, a framework would be responsible for creating 
locale and skin-layer search lists, and identifying a resource.  The API 
would be responsible for locating the resource implementations and 
returning WSGI application objects.

I don't know if it's politically or technically feasible to actually solve 
this, since some template engines bundle a lot of assumptions presently, 
like the idea that a template is a Python module or stuff like that.  Some 
frameworks currently bundle assumptions of their own about such 
things.  Getting to a workable standard might require some compromises.

On the positive side, relatively few frameworks support the full range of 
i18n, skinning, polymorphism, and egg resource options, and so fewer 
conflicts are likely the more you get into the high end.  For example, Zope 
3 supports skins and i18n, but not really eggs and I'm not sure it does 
polymorphism.  peak.web currently does polymorphism, skins, and eggs, but 
doesn't do much w/i18n as yet.  Creating a standard would enhance the 
capabilities and deployability of *all* participating frameworks, however, 
so it seems to me to be worth a go.

The downside, on the other hands, is that since so few frameworks try to 
solve the the high-end problems, there's likely to be less widespread 
understanding of what the problems are or why you'd want to solve 
them.  This is the flip side of the issue Jim Fulton pointed out, which is 
that people who work at the high end of the problem scale don't see much 
benefit in the Turbo/Buffet templating API, because it bakes in way too 
many assumptions to allow you to solve any really interesting problems with it.

More information about the Web-SIG mailing list