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

Philipp von Weitershausen philipp at weitershausen.de
Mon Aug 4 03:23:05 EDT 2008

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 ;).

> 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.

> 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.

More information about the Grok-dev mailing list