[Grok-dev] template association - suboptimal magic?

Martijn Faassen faassen at startifact.com
Thu Sep 11 07:50:47 EDT 2008


Hi there,

Jan-Wijbrand Kolman wrote:
[snip]
> *except* that in the first and second case the view component is *not*
> allowed to have a render() method where in the last case it is allowed.

True. I think we'll have to live with this for backwards compatibility's 
sake. Also for convenience's sake. Also for Grok's philosophy's sake: if 
we can possibly get away with it, we'll have default behavior if the 
directive is not there.

> I was looking for a way to make this difference more
> explicit/predictable for the app. developer, indeed at the "cost" of
> possibly having more grok.template() directives throughout the app's
> codebase. It could be we have a different idea of how "high" this "cost"
> actually is in practice.

Given that template-driven view classes can be very short:

class Foo(grok.View):
     pass

it'll mean going from 2 lines to 3 lines. That's a significant relative 
increase. Since the common case for views is to use templates, it's 
going to happen a lot, and I'd like 'grok.View' already to signal 
template usage. Since 'render' is right there in your face to signal 
non-template usage, that's quite obvious to the reader.

> There's a bit of a difficulty implementation-wise too (although that
> should not be the primary deciding factor in this discussion of course):

> The default of a directive - i.e. when the directive is not explicitly
> used on a component - cannot be computed. One can only have computed
> defaults on directive-binding time (i.e. in the grokker). By then it is
> very difficult to decide what classname to use for finding a template -
> is it the classname of the view component being grokked? Or maybe of one
> of its possible baseclasses?

Good question.

I think the rule should be the same as for grok.template(). This means 
that if grok.template() is left out everywhere, the system should act as 
if grok.template() is everywhere. This means that for a view that 
subclasses another view, it should walk up the class chain (using mro? 
we should look at our local utility code as we do something like this 
there), and go to the deepest view class that's not grok.View itself, 
and act like there's a grok.template() there. If a subclass wants to 
override the template that's associated with the view they will have to 
use grok.template() explicitly.

Another subtle behavior arises when 'render' is used on a view subclass 
but 'grok.template' (or its absence and thus the default) was used on a 
base class. In this case I think the use of 'render' should override the 
behavior of base classes, the same way an explicit 'grok.template' 
overrides the base class behavior.

Similarly, if 'render' is encountered when walking up the base class 
chain, this is treated as the behavior the subclass will get, not 
template association.

If 'render' is encountered in a base class but grok.template in a 
subclass, what should happen? Error or grok.template overriding? I'm 
tending towards the latter.

Thinking about the subtlety of interactions, one way we could get rid of 
this whole render/template mess is to introduce grok.PythonView or 
something like that, and to tell people to use these if they want to 
have non-template views, instead of having the special 'render' rule. 
This might make life a lot cleaner, at the cost of relatively easy 
backwards compatibility breakage and documentation updates. Opinions?

Regards,

Martijn



More information about the Grok-dev mailing list