[Checkins] SVN: five.pt/trunk/ Add somewhat evil method to hook into grok. Unfortunately grok makes it extremely hard to do this more cleanly.

Wichert Akkerman wichert at wiggy.net
Wed Apr 14 10:36:21 EDT 2010


On 4/14/10 16:27 , Vincent Fretin wrote:
> On Wed, Apr 14, 2010 at 12:06 PM, Wichert Akkerman<wichert at wiggy.net>  wrote:
>> Log message for revision 110841:
>>   Add somewhat evil method to hook into grok. Unfortunately grok makes it extremely hard to do this more cleanly.
>>
>> Changed:
>>   U   five.pt/trunk/CHANGES.txt
>>   U   five.pt/trunk/src/five/pt/patches.py
>>
>> -=-
>> Modified: five.pt/trunk/CHANGES.txt
>> ===================================================================
>> --- five.pt/trunk/CHANGES.txt   2010-04-14 09:48:30 UTC (rev 110840)
>> +++ five.pt/trunk/CHANGES.txt   2010-04-14 10:06:30 UTC (rev 110841)
>> @@ -1,6 +1,11 @@
>>   Changelog
>>   =========
>>
>> +?.? - unreleased
>> +~~~~~~~~~~~~~~~~
>> +
>> +- Basic support for five.grok templates. [wichert]
>> +
>>   0.8 - 2010-01-05
>>   ~~~~~~~~~~~~~~~~
>>
>>
>> Modified: five.pt/trunk/src/five/pt/patches.py
>> ===================================================================
>> --- five.pt/trunk/src/five/pt/patches.py        2010-04-14 09:48:30 UTC (rev 110840)
>> +++ five.pt/trunk/src/five/pt/patches.py        2010-04-14 10:06:30 UTC (rev 110841)
>> @@ -81,3 +81,26 @@
>>   ZopeViewPageTemplateFile.__get__ = get_bound_template
>>   PageTemplateFile.__call__ = call_template
>>   PageTemplateFile.macros = property(get_macros)
>> +
>> +try:
>> +    from five.grok.components import ZopeTwoPageTemplate
>> +
>> +    _tpf  = FiveViewPageTemplateFile(__file__)
>> +    class GrokViewAwarePageTemplateFile(ViewPageTemplateFile):
>> +        def pt_getContext(self, *args, **kw):
>> +            global _tpf
>> +            return _tpf.pt_getContext(*args, **kw)
>> +        def pt_render(self, namespace, **kw):
>> +            if "args" in namespace:
>> +                del namespace["args"]
>> +            context=namespace.pop("context")
>> +            request=namespace.pop("request")
>> +            view=namespace["view"]
>> +            return self.__call__(_ob=view, context=context, request=request, **namespace)
>> +
>> +    def setFromFilename(self, filename, _prefix=None):
>> +        self._template = GrokViewAwarePageTemplateFile(filename, _prefix)
>> +    ZopeTwoPageTemplate.setFromFilename = setFromFilename
>> +except ImportError:
>> +    pass
>> +
>
> Hi Wichert,
>
> It's great you are fixing five.grok+chameleon.
>
> I think with the change you did, you don't have the "static" variable
> in the namespace, Am I wrong?

Could be. I've never used 'static', and I have no idea if it makes sense 
in a Zope 2 context. I know this works for a basic grok.View instance to 
render templates, but I'm not making any further guarantees.

> because you don't call pt_grokContext which call actually getNamespace
> which call view.default_namespace (where static is defined), and
> view.namespace (where you can give special variable to the template)

I have no idea what pt_grokContext is or where it comes from. grok 
obfuscates the standard code paths by inserting its own PageTemplate 
class (see grokcore.view.components.PageTemplate) in the middle of the
standard call chain for views. In other words: on a grok.View instance 
the template instance variable is not the template at all, but some 
man-in-the-middle thing grok invented. I am not sure why that extra 
class is needed; it looks like everything it does could be done in 
grok.View.render itself. It did make figuring this out and debugging it 
quite hard - there are half a dozen *PageTemplate* classes involved, 
each of which is a little bit different.

The special grok PageTemplate thing has a render method which looks like 
this:

     def render(self, view):
         namespace = self.getNamespace(view)
         template = self._template
         namespace.update(template.pt_getContext())
         return template.pt_render(namespace)

Note that there is no mention of pt_grokContext there, or anywhere else 
in grokcore.view.

Now I know that in the five.grok case the namespace parameter for 
pt_render is essentially ignored; somewhere else in the five.pt stack it 
does its own pt_getContext and uses that. Since I personally did not 
have any need for that to work I haven't tried to fix that. I already 
spent several hours to get this working and there are limits to how much 
time I can spend on this :)

> But more I read the code, more I'm lost. Is the pt_render and
> pt_getContext really executed here ? because the
> ViewPageTemplateFile.__call__  doesn't use these methods AFAICS
> I'm not sure. Maybe the code should only be:

You missed the magic PageTemplate man-in-the-middle attack from grok :)

Wichert.


More information about the checkins mailing list