[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