[Zope-CMF] Re: Add forms and menus

Martin Aspeli optilude at gmx.net
Tue Jul 15 03:53:11 EDT 2008


Hi Robert,

>>> imo its a bad idea to depend on static zcml configuration for factory
>>> types. martin did a nice approach in his portlets engine with a name
>>> traverser when calling a generic adding view. 
>> I'm not quite sure I follow here. The portlets machinery just looks up 
>> the add view in a utility that stores its name, and then invokes it. 
>> There's a custom analog to IAdding called "+portlet" to keep the 
>> namespace separate.
> 
> you post i.e. /++contextportlets++plone.rightcolumn/+/portlets.Login as
> action for adding a portlet and let your ITraversable implementations
> perform what to do in plone.app.portlets.browser.traversal.py.
> 
> thats imo a nice approach

Ah, I get you. Actually, the ++contextportlets++plone.rightcolumn bit is 
a namespace traversal adapter that addresses a particular portlet 
manager (which is basically an ordered container); + is an IAdding view 
(actually, an IPortletAdding view) registered for the portlet manager 
container. portlets.Login is the name of the add view for a particular 
portlet.

So, this approach is identical to (and borrowed from) the "old" Zope 
3/ZMI approach that you have an add view that is a statically registered 
view for IAdding. The adding view is *not* generic. Each portlet 
registers its own add view. We have a formlib-based base class though.

Now, I think this is fine for portlets, since it's relatively easy to 
register this add view (there's a single ZCML directive to register all 
portlet-related information), and portlets are not like portal types 
(there's no persistent FTI that can be cloned).

>>> i took this idea and the
>>> adding mechanism of devilstick works this way as well and depends on the
>>> fti too. so a call of foo/add/portal_type returns an add view for
>>> requested type.
>> How's that different to foo/+/<factory-name> ?
> 
> not that much. i only wanted to say that there might be no need to
> register a seperate addview/form for every portal type. having the type
> name it should be possible to get the schema interface of the requested
> type, so it's possible to provide a generic addview/form.

Right. That's probably a reasonable default (and is, in effect, what 
Dexterity does as well, although it registers add views as local adapter 
factories that "know" their portal_type).

> this interface lookup, and addview/form instanciation might be done then
> in a traverser, that's the most 'zopeish' solution imo.

This is quite an interesting approach, actually. After traversal, what 
is self.context in the add form? Is it the form, or the 'addview' 
traverser thing?

>> Having the add view be a view for a view (i.e. the context of the real 
>> add view is not a content object) is sometimes quite painful.
> 
> until someone got the clue :). yes you're right here, constructs like
> ``aq_inner(self.context.context)`` and similar simply look ugly. but on
> the other hand, if you kick this construct, you have to provide another
> mechanism which is responsible to finally add what has to be added. if
> this is more elegant then...?

The final 'add' operation can be done by a base class for the view. 
That's how Yuppie's formlib thing works, and how z3c.form prefers to work.

self.context.context can be majorly painful, though. For example, look 
at 
http://dev.plone.org/plone/browser/plone.app.vocabularies/trunk/plone/app/vocabularies/workflow.py.

Here, we need to acquire something, but since the context may be the 
IAdding view, we have to do this everywhere:

  context = getattr(context, 'context', context)

Yuck!

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 Zope-CMF mailing list