[Zope3-Users] ForbiddenAttribute when adding to a folder

Tom Dossis td at yoma.com.au
Fri Nov 24 18:09:56 EST 2006


Dominique Lederer wrote:
> Darryl Cousins schrieb:
>> Hi Tim,
>>
>> On Sat, 2006-10-21 at 12:18 +0200, Tim Terlegård wrote:
>>> Is there a way to add content without having @@+ in the URL? For
>>> instance I'd like the url for adding events to be /addEvent.
>>>
>>> I get security problems when not having @@+ in the URL. I have this view:
>>>
>>>   <browser:page
>>>       for="zope.app.container.interfaces.IWriteContainer"
>>>       name="addEvent"
>>>       class=".eventforms.EventAddForm"
>>>       permission="zope.ManageContent"
>>>       />
>>>
>>> When I hit the submit button in this add form I get an error:
>>> ForbiddenAttribute: ('add', <zope.app.folder.folder.Folder object at
>>> 0xb6e65d2c>)
>> Forbidden here in the sense that Folder does not have an 'add'
>> attribute.
>>
>>> I realize IWriteContainer might not be the right interface, it doesn't
>>> have any add method.
>>>
>>> Should I have for="zope.app.container.interfaces.IAdding" instead and
>>> somehow add an adapter from IFolder to IAdding or how would I do this?
>>>
>>> Tim
>> As you point out formlib.BaseAddForm calls the add method of the
>> context:
>>
>>     _finished_add = False
>>
>>     def add(self, object):
>>         ob = self.context.add(object)
>>         self._finished_add = True
>>         return ob
>>
>> I (also a novice) always use formlib for adding. But I use my own base
>> adding sub-class of BaseAddForm which has this add method:
>>
>>     def add(self, obj):
>>         try:
>>             ob = self.container.add(obj)
>>         except:
>>             self.container.__setitem__(obj.__name__, obj)
>>             ob = self.container[obj.__name__]
>>         self._finished_add = True
>>         return ob
>>
>> I almost always use a NameChooser to choose the name for the object. So
>> I can trust using __name__ as the dict key.
>>
>> I use self.container here that usually resolves to self.context but on
>> some occassions the context is not the container I want to be adding to.
>>
>> Hopes this helps.
>>
>> Darryl
> 
> yes, thanks, it helped me
> 
> but what are we doing wrong here, that the base methods wont work?
> 
> why should my container know about the add method?

The context for AddForm normally isn't the container, it's the IAdding
namespace adapter.  This object implements the add method.  The IAdding
object interacts with the container (and name chooser).

All this presumes you've registered your add form page accordingly:
e.g.
<addMenuItem
  view="Addform.html"
  ...
<page
  name=Addform.html
  for="zope.app.container.interfaces.IAdding"
  ..

When wiring in a form directly against an IContainer I guess it's
reasonable to simply presume the context is the container.

In the case above you could make the AddForm work both ways somewhat
more explicit, e.g.

  if IAdding.providedBy(context):
     self.context.add(ob)  # the context IAdding does the name handling.
  else:
     #assert IWriteContainer.providedBy(ob)
     name = ..
     self.context[name] = ob

HTH
-Tom



More information about the Zope3-users mailing list