[Grok-dev] Re: implements() works, alsoProvides() breaks
Philipp von Weitershausen
philipp at weitershausen.de
Thu Aug 30 11:48:04 EDT 2007
Brandon Craig Rhodes wrote:
> /myapp/Model_object/index ... worked
> /myapp/Model_object ... worked
> /myapp/Plain_object/index ... worked
> /myapp/Plain_object ... broke completely :-)
> The solution was to introduce the following code into my application,
> assuming that the class I am trying to View instead of a grok.Model is
> class "Plain":
> adapts=(Plain, IBrowserRequest),
> I swiped this code from the bootstrap() code of grok._grok, where it
> is run twice to provide a default View name of 'index' to grok.Model
> and grok.Container.
I do recommend doing this declaration in ZCML:
<browser:defaultView for="Plain" name="index" />
Doing setup at import time isn't such a good idea. Alternatively, grok
could grow a directive that would allow you to set the default view name
> Oh: and it only seems to work if my class
> implements the interface IContained. But I can live with that.
Please be more specific. What's the actual error?
If this is about __parent__, grok should take care of it. If the object
returned by the traverser provides ILocation (IContained is a
subinterface of that), __parent__ and __name__ will automatically be
assigned to the object. If not, grok will wrap it in a LocationProxy
that adds __parent__ and __name__ without altering the object itself.
> I have now found (don't ask how many experiments it took until I
> determined this!) that running provideAdapter() this way on one of my
> own classes only results in a truly functioning default View name if
> my *class itself* provides IContained, but does *not* work if it is
> only the object *instance* returned by traverse() that provides
Again, please be more specific about the error message.
> This is terribly disappointing, because my actual plan had been to
> write traverse() methods that returned arbitrary objects, and that
> used alsoProvides() to slap an IContained interface decorator on each
> object before returning it to the framework.
That's not really what IContained was intended for. The idea is that
implementations should be free to decide themselves whether they are
contained/locatable or not. They signal this by implementing ILocation
or IContained intrinsically. Slapping the interface on as a marker
interface defeats the purpose of the ILocation and IContained interfaces.
The canonical way is to check for ILocation and set the attributes if
the object provides them. If not, wrap the object in a LocationProxy:
zope.location.locate(obj, parent, name)
return zope.location.LocationProxy(obj, parent, name)
> This is deeply mystifying to me; my impression from The Book had been
> that Zope 3 would treat as equivalent (at least for these purposes)
> the three above methods for declaring that an instance provides an
From your code:
> zope.interface.alsoProvides(WorkingObject2, IContained)
alsoProvides takes an *object* as a first parameter. Not a class. This
is where your problem is.
http://worldcookery.com -- Professional Zope documentation and training
More information about the Grok-dev