[Zope3-Users] sequence of custom widgets

Marco Mariani marco at sferacarta.com
Mon May 15 17:05:50 EDT 2006


Frank Burkhardt wrote:

> some months ago, Phillip von Weitershausen wrote such a widget for
> me. I'm
> not using it anymore and I don't know, if it's still working. But
> maybe it
> will help:

Thank you (and Phil), having a template surely come handy, but I have
another problem.

Even with the default sequence widget, the form appears to work. At the
moment I press Add, however, the following is raised:

> Traceback (innermost last):
>   Module zope.publisher.publish, line 138, in publish
>     result = publication.callObject(request, object)
>   Module zope.app.publication.zopepublication, line 161, in
>   callObject
>     return mapply(ob, request.getPositionalArguments(), request)
>   Module zope.publisher.publish, line 113, in mapply
>     return debug_call(object, args)
>    - __traceback_info__: <security proxied zope.app.publisher.browser.viewmeta.FamilyAdd instance at 0xb57c854c>

[...]

> Module zope.tal.talinterpreter, line 839, in do_loop_tal
>     iterator = self.engine.setRepeat(name, expr)
>   Module zope.tales.tales, line 685, in setRepeat
>     it = self._engine.iteratorFactory(name, expr, self)
>   Module zope.tales.tales, line 110, in __init__
>     self._next = i.next()
>   Module zope.formlib.form, line 749, in error_views
>     zope.app.form.browser.interfaces.IWidgetInputErrorView)
>   Module zope.component, line 157, in getMultiAdapter
>     raise ComponentLookupError(objects, interface, name)
> ComponentLookupError: ((() <type 'list'>, <zope.publisher.browser.BrowserRequest instance URL=http://laptop:8080/++skin++Debug/afaf/+/AddFamily.html%3D>), <InterfaceClass zope.app.form.browser.interfaces.IWidgetInputErrorView>, u'')

where the list is the list of children I've tried to create:

> ComponentLookupError: (((<person.Person object at 0xb578ea6c>,) <type 'list'>, <zope.publisher.browser.BrowserRequest instance URL=http://laptop:8080/++skin++Debug/afaf/+/AddFamily.html%3D>), <InterfaceClass zope.app.form.browser.interfaces.IWidgetInputErrorView>, u'')




I reckon it's trying to display the error, but.. which one?

Do I need to add another view along the lines of this one?

  <!-- Views for Widget Errors -->

  <view
      type="zope.publisher.interfaces.browser.IBrowserRequest"
      for="zope.app.form.interfaces.IWidgetInputError"
      provides="zope.app.form.browser.interfaces.IWidgetInputErrorView"
      factory="zope.app.form.browser.exception.WidgetInputErrorView"
      permission="zope.Public"
      />


I'll try to follow it with the debugger.



> ---------------------
> person/configure.zcml
> ---------------------
> <configure xmlns="http://namespaces.zope.org/zope" >
> 
> 
>   <interface
>     interface=".IPerson"
>     type="zope.app.content.interfaces.IContentType"
>     />
> 
>   <content class=".Person">
>     <factory
>         id="person.Person"
>         description="Person"
>         />
>     <require
>         permission="zope.View"
>         interface=".IPerson"
>         />
>     <require
>         permission="zope.ManageContent"
>         set_schema=".IPerson"
>         />
>   </content>
> 
> 
>   <interface
>     interface=".IFamily"
>     type="zope.app.content.interfaces.IContentType"
>     />
> 
>   <content class=".Family">
>     <factory
>         id="person.Family"
>         description="Family"
>         />
>     <require
>         permission="zope.View"
>         interface=".IFamily"
>         />
>     <require
>         permission="zope.ManageContent"
>         set_schema=".IFamily"
>         />
>   </content>
> 
> 
>   <include package=".browser" />
> 
> </configure>
> 
> 
> 
> 
> ------------------
> person/__init__.py
> ------------------
> from zope.interface import Interface, implements
> from zope.schema import TextLine, Object, List, Choice, Field
> from persistent import Persistent
> 
> class IPerson(Interface):
>     name = TextLine(title=u'Name', description=u'The first name')
> 
> 
> class Person(Persistent):
>     implements(IPerson)
> 
>     name = ''
> 
> 
> 
> class IFamily(Interface):
>     """The familiy interface."""
> 
>     mother = Object(title=u'Mother',
>                     required=False,
>                     schema=IPerson)
> 
>     father = Object(title=u'Father',
>                     required=False,
>                     schema=IPerson)
> 
>     children = List(title=u'Children',
>                     required=False,
>                     value_type=Object(
>                         title=u'Child',
>                         schema=IPerson)
>                     )
> 
> 
> 
> class Family(Persistent):
>     """The familiy interface."""
> 
>     implements(IFamily)
> 
>     mother = ''
>     father = ''
>     children = []
> 
> 
> 
> 
> -----------------------------
> person/browser/configure.zcml
> -----------------------------
> <configure
>     xmlns:zope="http://namespaces.zope.org/zope"
>     xmlns:browser="http://namespaces.zope.org/browser"
>     >
> 
> 
>   <!-- PERSON -->
> 
>   <browser:page
>     class=".forms.PersonAdd"
>     name="AddPerson.html"
>     permission="zope.ManageContent"
>     for="zope.app.container.interfaces.IAdding"
>     />
> 
>   <browser:addMenuItem
>     factory="person.Person"
>     title="Person"
>     description="New Person"
>     permission="zope.ManageContent"
>     view="AddPerson.html"
>     />
> 
>   <browser:page
>     for="person.IPerson"
>     name="edit.html"
>     class=".forms.PersonEdit"
>     permission="zope.ManageContent"
>     menu="zmi_views"
>     title="Edit"
>     />
> 
> 
> 
>   <!-- FAMILY -->
> 
>   <browser:page
>     class=".forms.FamilyAdd"
>     name="AddFamily.html"
>     permission="zope.ManageContent"
>     for="zope.app.container.interfaces.IAdding"
>     />
> 
>   <browser:addMenuItem
>     factory="person.Family"
>     title="Family"
>     description="New Family"
>     permission="zope.ManageContent"
>     view="AddFamily.html"
>     />
> 
>   <browser:page
>     for="person.IFamily"
>     name="edit.html"
>     class=".forms.FamilyEdit"
>     permission="zope.ManageContent"
>     menu="zmi_views"
>     title="Edit"
>     />
> 
> 
> </configure>
> 
> 
> 
> 
> -----------------------
> person/browser/forms.py
> -----------------------
> from zope.formlib.form import Fields, AddForm, EditForm
> from person import Person, IPerson, Family, IFamily
> from zope.app.form.browser import ObjectWidget, SequenceWidget
> from zope.app.form import CustomWidgetFactory
> 
> 
> 
> class PersonAdd(AddForm):
>     form_fields = Fields(IPerson)
> 
>     def create(self, data):
>         person = Person()
>         person.name = data['name']
>         IPerson.validateInvariants(person)
>         return person
> 
> class PersonEdit(EditForm):
>     form_fields = Fields( IPerson, render_context=True)
> 
> 
> 
> class FamilyAdd(AddForm):
>     form_fields = Fields(IFamily)
>     form_fields['mother'].custom_widget =
>     CustomWidgetFactory(ObjectWidget, Person)
>     form_fields['father'].custom_widget =
>     CustomWidgetFactory(ObjectWidget, Person)
>     form_fields['children'].custom_widget = CustomWidgetFactory(SequenceWidget,
>                                              CustomWidgetFactory(ObjectWidget, Person))
> 
>     def create(self, data):
>         family = Family()
>         family.mother = data['mother']
>         family.father = data['father']
>         family.children = data['children']
>         return family
> 
> 
> class FamilyEdit(EditForm):
>     form_fields = Fields( IFamily, omit_readonly=True,
>     render_context=True)
>     form_fields['mother'].custom_widget =
>     CustomWidgetFactory(ObjectWidget, Person)
>     form_fields['father'].custom_widget =
>     CustomWidgetFactory(ObjectWidget, Person)
>     form_fields['children'].custom_widget = CustomWidgetFactory(SequenceWidget,
>                                              CustomWidgetFactory(ObjectWidget, Person))
> 



More information about the Zope3-users mailing list