[Grok-dev] Re: Making an interface the default module context

Martin Aspeli optilude at gmx.net
Mon Aug 4 04:00:38 EDT 2008


Philipp von Weitershausen wrote:
> Martin Aspeli wrote:
>> Let's say I have a module like:
>>
>>  ...
>>
>>  class IFoo(Schema):
>>      pass
>>
>>  class FooView(grok.View):
>>      grok.require('hello')
>>
>> Here, Schema is imported from elsewhere, and is just a marker interface, 
>> i.e.:
>>
>>  class Schema(Interface):
>>     pass
>>
>> Schema exists purely to make IFoo above grokkable with some optional 
>> directives.
>>
>> In the example above, I'd hoped that the context for FooView would 
>> default to IFoo if there was no other obvious context (e.g. a model). 
> 
> Despite popular belief, grok doesn't actually use magic ;).

Do you prefer to be called "illusionists"? :)

I'm not sure if this is borderline magic or not... I figured it was 
analogous to "the IContext-implementing class is the context".

>> IFoo could be a marker interface, for example, which espouses a new view.
>>
>> However, FooView does not know its context, so I have to use 
>> grok.context(). I tried to let Schema provide IContext, and also to let 
>> IFoo provide IContext explicitly via alsoProvides(). Neither seems to 
>> stick.
> 
> If grok.context() isn't present it looks for something that *implements* 
> IContext, not provides.

Yes, I figured.

>> Is it possible to infer that the context for FooView should be IFoo in 
>> this case?
> 
> If you can somehow find a rule by which this interface is found, then 
> yes, it's possible. You'll have to override grokcore.component's 
> ContextGrokker which looks at the module, determines the implicit module 
> context and then uses the grok.context() directive to store this 
> implicit context so that it'll look to subsequent grokkers as if 
> grok.context() was used.
> 
> So what you can do is write something like that:
> 
>    from grokcore.component.meta import ContextGrokker
> 
>    class MyContextGrokker(martian.GlobalGrokker):
>        # execute this grokker before grokcore.component's ContextGrokker
>        martian.priority(martian.priority.bind().get(ContextGrokker) + 1)
> 
>        def grok(self, name, module, module_info, config, **kw):
>            context = grok.context.bind().get(module=module)
>            if context is None:
>                # grok.context() wasn't used explicitly so let's try
>                # to find an implicit context by our rules and then
>                # set it
>                implicit_context = somehow_determine_from(module)
>                grok.context.set(module, implicit_context)
> 
> All you now have to do is write this 'somehow_determine_from(module)' 
> algorithm that looks at a module and finds your IFoo.

Maybe scan for something that provides IContext, if nothing implements it?

I'm sure it can be done. My question is whether it's a good idea and 
something worth having in Grok itself.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book



More information about the Grok-dev mailing list