[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