[Zope3-dev] Re: View lookup changes in Zope 3.2?

Jeff Shell eucci.group at gmail.com
Fri Dec 16 03:44:33 EST 2005


On 12/15/05, Martijn Faassen <faassen at infrae.com> wrote:
> Jim Fulton wrote:
> > Martijn Faassen wrote:
> [snip]
> >  > Or am I wrong in even imagining this would be desirable?
> >
> > I think so.  If there are custom views for more specific interfaces,
> > it is likely those custom views provide features that your generic
> > view doesn't.  It would be a bit unkind for your view to override
> > those.
>
> I can see that...
>
> I have to consider what this means in practice -- with a skin you often
> want complete control over what users see. If suddenly bits of Zope 3
> pop up for your end user, that'll be very disconcerting; often I really
> don't want that to happen.
>
> Then again, in practice this might not happen, as your end user may not
> be capable of creating such objects anyway in an application; if they
> could you would've skinned them... Not sure...
>
> One troublesome scenario I can imagine is that if I make my total skin
> in Zope 3.n, it works, and then Zope 3.n + 1 is released and it has a
> more specific view registered for some content object that I'm using. I
> was relying on having skinned the more general interface, but suddenly
> in Zope 3.n + 1 I get the Zope 3 view. That'd be bad.
>
> So, I'm not sure whether or not this ability is compromised in practice
> with this bugfix...

If it is compromised, it may be bad design on your part? That's the
decision that I came to. I made a slightly modified
'EditMetaData.html' view for our CMS system that added a 'keywords'
field, made the form look nicer in our interface, and then mapped
'keywords' to IZopeDublinCore.subject (subjects? I can't recall right
now). I bound the view to one of our core interfaces,
'IManagedContent', used to distinguish CMS objects from other content
objects. Anyways, after installing Zope 3.2b1 I was getting the
default EditMetaData.html view instead of ours.

I wrote a little helper module for me to 'debug' this situation -
basically I took the internal
zope.interface.adapters.AdapterLookup.lookup code that did the
multi-adapter lookup and compiled a list of the multi-adapters it
chose from instead of having it choose the best. For this
'EditMetaData.html' situation, I got the following results for one of
my objects:

        [(((3, <InterfaceClass zope.app.annotation.interfaces.IAnnotatable>),
           (4, <InterfaceClass zope...IDefaultBrowserLayer>)),
          <class 'zope.app.pagetemplate.simpleviewclass...>),
         (((5, <InterfaceClass ex.cms.interfaces.IManagedContent>),
           (2, <InterfaceClass ex.cms.skin.CMS>)),
          <class 'zope.app.pagetemplate.simpleviewclass...>)]

The integers are the ranks used, mapping to (view for, layer). This
particular case shows me that the IAnnotatable, IDefaultBrowserLayer
combination is ranked (3,4) which wins out over my IManagedContent,
CMS view, ranked (5,2). The solution here was for me to re-declare
what my view was for and make it for IAnnotatable. I run my debug
function again and get the following results:

        [(((3, <InterfaceClass zope.app.annotation.interfaces.IAnnotatable>),
           (4, <InterfaceClass zope...IDefaultBrowserLayer>)),
          <class 'zope.app.pagetemplate.simpleviewclass...>),
         (((3, <InterfaceClass zope.app.annotation.interfaces.IAnnotatable>),
           (2, <InterfaceClass ex.cms.skin.CMS>)),
          <class 'zope.app.pagetemplate.simpleviewclass...>)]

Now my custom view is ranked (3,2) and wins out over the default one.

I'm still unsure about how I feel about this situation in my gut. The
Zope 3.1 way felt strangely intuitive, but I recognize why it was
incorrect and why the 3.2 implementation does what it does.

I decided to make a special branch of our CMS to deal with Zope 3.2
beta testing, and it's turned into a big refactoring / mild
restructuring branch. I'm re-evaluating a lot of the blind
'implements' declarations I was making. I'm re-evaluating some of my
core interfaces and decided what ones belong to concrete objects and
which ones are or can be abstract notions ('marker' interfaces). This
is a task that's been in the back of my head for a while. I have a
pair of core content objects and corresponding interfaces that we've
used interchangeably and I really needed to come down hard with a
policy. For us at Bottlerocket, these core objects have bitten us in
the past. So for me - and I'm not saying it applies for you or anyone
else - this change to the 'correct' behavior for multi-adapter lookup
has highlighted some design flaws in our code and way of thinking. If
this issue didn't show itself now, a different issue may have shown up
in the future.

I'm attaching the little 'debug' module I whipped up. Using it, along
with statements like pprint(providedBy(myfolder).__iro__) helped me
realize that I had some bad implements declarations in my base classes
/ ZCML.

So for me, this helps because it should make my code tighter. Where it
doesn't sit well with me is just that for me (and you too Martijn), it
seems like it's more intuitive for the skin layers to have precedence.
Whether that intuitive feel comes from the Zope 3.1 behavior, or
whether it may be the 'right' way people expect things to behave, I
don't know.

But now that I understand multi-adapters and how they're used to do
browser views, I have to admit that I'm very impressed with how the
very core component architecture is used for *everything*, especially
after the 'Simplify Component Architecture' proposal was implemented.
I'll gladly break with what Zope 3.1 let me get away with in favor of
a "works-as-advertised" multi-adapter lookup with a sensible and
predictable ranking algorithm.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: debug.py
Type: text/x-python-script
Size: 5589 bytes
Desc: not available
Url : http://mail.zope.org/pipermail/zope3-dev/attachments/20051216/8c9b90c3/debug.bin


More information about the Zope3-dev mailing list