[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