[Web-SIG] A trivial template API counter-proposal

Ian Bicking ianb at colorstudy.com
Tue Feb 7 03:16:03 CET 2006

Michael Bayer wrote:
> Ian Bicking wrote:
>>>I would say that
>>>the argument or arguments passed to  find_template() need to be pretty
>>>open ended, since you cant predict  what kinds of things might be
>>>meaningful to a template finder, such  as in myghty's case, the resolver
>>>wants to know if you are asking for  this template to be used in a
>>>request, or an "embedded" template  call, since there may be rules set
>>>up to return different components  based on that context.
>>Do these need to be arguments, or can the context be instance variables
>>of a find_template callable?  That is, you might do:
>>def myghty_entry_point(environ, start_response):
>>     find_template = MyghtyTemplateFinder(environ)
>>     ...
> Well this is the question- say im using an implementation of "the spec",
> whatever it is.  I say, OK, I want to use the PylonsResolver with the
> KidCompiler with the DjangoCodeCache with the MyghtyInterpreter, and we
> snap those together.  We fire it up, send a request for template "xxxxx",
> PylonsResolver calls it up and sends it off to the
> KidCompiler/DjangoCodeCache to get a template object, then off to
> MyghtyInterpreter to run it.
> Then , inside the template, we print out some html, then we say,
> "include_template('xxxx')", meaning the template wants to call another
> one.   Does the "include_template" call the resolver that is internal to
> the MyghtyInterpreter ?  Or does it have to use the Resolver that was sent
> into the beginning of the request ?  (id say definitely the latter).

It should use the resolver passed in.  Getting it to do so is the hard 
part to implement ;)

> My instinct in this kind of situation is, cant we just add a **kwargs to
> find_template() ?   :)  Im guessing not (but why not ?).  But some kind of
> dictionary where the template's runtime environment can pass messages
> through to the resolver would be handy...else, Mygthy would have to hack
> something together, like serializing arguments in a string or something
> inefficient like that.  Also, since this kind of call will happen on the
> order of N based on the complexity of the template, it would be nice if
> there wasnt too much (or really any) "create object" overhead to
> that...since it shouldnt have to use up a lot of resources for a very
> frequent operation.

What things do you pass through?  What things can you ignore?  Should 
the template pass through kwargs unless it knows better for some reason?

If these are state held in find_template, then this isn't a problem. 
And potentially find_template can have other (non-standard) methods on 
it, which the template could try to use.  This seems clearer in terms of 
what is an extension, and what is a core method.

The WSGI environment does offer an advantage here, because it is easier 
to put extra items in the environment -- keys get namespaces, where 
attributes are flatter, and there are easier techniques for 
introspecting a dictionary, and easier ways to filter, copy, or recreate 
a dictionary.  So... maybe that's an argument for WSGIness.  I do 
appreciate these aspects of the WSGI dictionary for web requests.

>>At least in my spec, find_template is not meant to be a global value.
>>(However, I believe this complicates caching substantially, unless we
>>leave it up to the find_template callable to handle that).
> it should be local to some specific template-lookup object that was
> specified to the context of this particular template call.  there might be
> lots of template-lookup implementations happening within the same thread
> even.

In the spec I give, it is assumed that the template object keeps a 
reference to the name it was fetched with, and the find_template it was 
found with.  And so it gets passed through that way.  Maybe it should be 
more explicit.

Hrm... I'm feeling myself coming back around to WSGI thoughts.  Oh 
irony!  (What about WSGI-like, but not WSGI?)

>>One substantial one that I think comes up in Myghty is that you get a
>>template, and then you get all its implicit parents (I'm not sure what
>>the term is in Myghty).  I don't even know what to call that, and
>>certainly not how to deal with it in find_template.
> This is not just in Myghty (its called "inheritance" in the general sense,
> and the "implicit" parent is just called an "autohandler" which is
> basically just, "the default parent").  Spyce and Django templates also
> support inheritance....and it is my opinion (a former version of me would
> say "i can guarantee you") that once you use template inheritance, you'll
> never go back.  From a find_template() perspective, its not different from
> a template embedding another - its just that the executional relationship
> of those templates is reversed (or turned inside-out, depending on how you
> look at it).

The inversion of control is the tricky part.  In something like Cheetah, 
Kid, or ZPT the template (as represented solely by the file contents) 
gets control first, and then explicitly hands it off to whatever it is 
"inheriting" from (they each have substantially different notions of how 
to compose templates).  This implies another call to find_template, 
which gives control back to the framework, which is what we want.

But that doesn't seem to work for Myghty.

>>One possible workaround for that would be for the plugin's load_template
>>to return an object that encompasses all the implicit parents.  But that
>>takes some functionality from find_template that seems like it should be
>>in find_template.  Unless there was some really simple rule, like:
> I dont think find_template has to be organized differently for inheritance
> vs. embedded components...the only thing that I would say is needed is the
> ability for find_template to get passed that "context" of, "i need this
> component to use as my parent"/ "i need to use this component as an
> 'include'", since its nice to enable your resolution to look in different
> places for those two things.  The four built-in contexts in myghty are
> "request", "subrequest", "component", and "inherit".
> Plus you can define your own contexts, such as in one demo I build a
> "front" controller which then forwards onto a secondary controller, and it
> uses different contexts to indicate different search paths (therefore
> nobody can hit a secondary file directly from the outside).  although
> those arent even templates, those are controller functions.  are we
> considering the finder being able to return arbitrary callables and not
> just "templates"   (since I like that) ?

Hmm... I'm going to think about the dictionary/callable WSGI-ish 
approach, because maybe that will make this easier.  Umm... circles...

Ian Bicking  |  ianb at colorstudy.com  |  http://blog.ianbicking.org

More information about the Web-SIG mailing list