Hi Martin!

Martin Aspeli wrote:
Martin Aspeli wrote:
It's also worth noting that z3c.form (via plone.z3cform, which should be plain CMF compatible, though you may want a different default template) has support for such views in quite a generic way. The "CMF" version of that looks like this:


z3c.form is generally nicer to work with than formlib.

Maybe we should discuss this in a different thread. Here a short reply: My code for the AddForm would look quite different, especially for CMF trunk,

I'm curious how it would look different. Now is the time to get the correct base class behavior in plone.z3cform, before we release a new version of it.

Ok. I added some comments to the 'add' method of plone.z3cform:

    def add(self, object):
container = aq_inner(self.context)
        content = object
name = self.contentName
        chooser = INameChooser(container)

        # Ensure that construction is allowed

        portal_types = getToolByName(container, 'portal_types')
        fti = portal_types.getTypeInfo(content)

        if fti is not None:
            # Check add permission
            if not fti.isConstructionAllowed(container):
                raise Unauthorized(u"You are not allowed to create a %d here" % 

Inside an add form this should always be true. If it isn't true, we'll get an error anyway. So this check is redundant and can be removed.

            # Check allowable content types
            if  getattr(aq_base(container), 'allowedContentTypes', None) is not 
None and \
                    not fti.getId() in container.allowedContentTypes():
                raise Unauthorized(u"You are not allowed to create a %d here" % 

allowedContentTypes is quite expensive. I use this code instead:

  #check container constraints
  container_ti = portal_types.getTypeInfo(container)
  portal_type = content.getPortalTypeName()
  if container_ti is not None and \
          not container_ti.allowType(portal_type):
      raise ValueError('Disallowed subobject type: %s' % portal_type)

        # check preconditions
        checkObject(container, name, content)

I doubt constraints based on __setitem__ and __parent__ work in Zope 2.

        if IContainerNamesContainer.providedBy(container):
            # The container picks it's own names.
            # We need to ask it to pick one.
            name = chooser.chooseName(self.contentName or '', content)
            request = self.request
            name = request.get('add_input_name', name)

            if name is None:
                name = chooser.chooseName(self.contentName or '', content)
            elif name == '':
                name = chooser.chooseName('', content)
                # Invoke the name chooser even when we have a
                # name. It'll do useful things with it like converting
                # the incoming unicode to an ASCII string.
                name = chooser.chooseName(name, container)
if not name:
            raise ValueError("Cannot add content: name chooser did not provide a 

All that name handling is copied from an old version of Five's BasicAdding, which in turn is copied from old Zope 3 code. I think we should use our own code here to make sure we understand the code and it reflects our policy.

Creating the content I set a provisional id. In the 'add' method I just use this line:

  name = chooser.chooseName(content.getId(), content)

        content.id = name
        container._setObject(name, content)
        content = container._getOb(name)
if fti is not None:

CMF trunk uses events instead of _finishConstruction.

        self.contentName = name

but in general that's the way to go. Since z3c.form became the standard in the Zope 3 world I'd like to see Zope 2 and CMF moving in the same direction. Unfortunately using plone.z3cform is no option for CMF because it has a different license and repository. *If* Plone wants to donate that code to the Zope Foundation or someone writes something similar (maybe five.z3cform), I'd be happy to help with CMF integration.

Bah, I hate these discussions. I'm sure Daniel Nouri would be happy to relicense. Re-invention for the sake of a license is just too dumb.

I'd prefer to keep the name to avoid breaking existing packages, though.

Another option is to factor out a few things to a five.z3cform and have plone.z3cform import from it as appropriate.


plone.z3cform seems to contain Plone specific stuff. Factoring out the generic stuff to a five.z3cform package sounds good to me.

But I don't know if everybody agrees that CMF 2.2 should depend on z3c.form.

How about we use a naming convention that's linked to the factory that's persisted in the FTI, i.e. we look for a view called "add-<factory_name>" and link to that if it's available.

The idea is that the factory name is unique and specific to the content type.

I sometimes use different factories for one content type, but a 1:1 relationship doesn't seem to be necessary for your proposal.

Different portal types that use the same factory would almost by necessity have the same add view.

This is the required 1:1 relationship. But if different portal types use the same add view, we have to pass the portal type name to the add view. (addFile currently accepts portal_type as argument to override the default portal type if necessary.)

We could make this overrideable as well, with another FTI property.

I guess I'd rather have a flexible explicit URL than an implicit URL ruled by convention.



Zope-CMF maillist  -  Zope-CMF@lists.zope.org

See http://collector.zope.org/CMF for bug reports and feature requests

Reply via email to