Right now the process for creating and rendering templates lumps too
many things together and needlessly splits concerns. Much of this is
due to Breve trying to follow the Buffet spec. Because of the
limitations imposed by this pattern and because Buffet will likely be
deprecated by most of the frameworks at some point in the near future
(Pylons 0.9.7 and most likely TurboGears 2.0, leaving only CherryPy),
I'm going to rework the template creation process.
Here's the current pattern:
from breve import Template
from breve.tags.html import tags
vars = { }
t = Template ( tags )
t.render ( 'index', vars )
On the surface this seems fairly sane and straightforward but here's the
problem:
1) Needless separation of instantiation and render arguments. Since a
Template object can only safely be used once, there's little reason to
not pass all the arguments at instantiation time.
2) Unfortunate grouping of what should be a sequence of calls. Because
template evaluation and flattening occur within the render call, it's
not possible to get the evaluated but unflattened template (which could
be of interest if you wanted to use Tag.walk to do further processing on
it prior to flattening).
I'm still working out the details, but here's what I'm envisioning as a
replacement API:
t = Template ( 'index', tags, vars, args, kw ) # plus any other options
# at this point "t" is index.b, fully evaluated, but unflattened
def callback ( tag, is_tag ):
print tag
t.walk ( callback )
print t.render ( ) # basically just a wrapper around flatten with doctype and xml info prepended
This is the meat of the matter, but I'm sure this will cause collateral
changes in other parts of the API.
I'd be interested in hearing any feedback on this. Clearly
backwards-compatibility is a concern (hence the 2.0 version jump), but
I'm unwilling to hold back progress because of being anchored to a
limiting (and obsolete) API, so I'd rather have some other way to help
people manage version issues.
Regards,
Cliff
That sounds like a good idea. Maybe the easiest way to do this is with
a class derived from Template and then just set the values as a class
attribute on the new class? All the Template class would need to do at
this point is refer to that new attribute.
Cliff
Okay, so maybe a base class that looked something like this?
class TemplateSettings ( object ):
def __init__ ( self, *args, **kw ):
self.args = args
self.kw = kw
def __call__ ( self, template, vars ):
return Template ( template, vars, self.args, self.kw )
Then you could do this:
from breve import Template
from breve.tags.html import tags
template_with_defaults = TemplateSettings ( tags = tags )
myvars = { 'foo': 1 }
t = template_with_defaults ( 'index', myvars )
Cliff