Stephan Richter schrieb:
>
> The problem, I think (actually I just checked, so I know ;-), is that
> CustomWidgetFactory was not designed to work well with advanced widgets, i.e.
> widgets that have more constructor arguments beyond the field and the
> request.
>
Hm, so you think :-) I should rather use CustomSequenceWidgetFactory?
No, that doesn't work ether. (Still the same error, still don't know what to
pass to 'fields'.)
But I got an other solution/suggestion: Redefine the constructor of
zope.app.form.browser.sequencewidget.SequenceWidget in new classes, say
CustomSequenceWidget and CustomListSequenceWidget. They work together
with CustomWidgetFactory (pretty) well:
from zope.app.form.browser.sequencewidget import SequenceWidget,
ListSequenceWidget
class CustomSequenceWidget(SequenceWidget):
def __init__(self, context, request, subwidget=None):
super(SequenceWidget, self).__init__(context, request)
self.subwidget = subwidget
class CustomListSequenceWidget(ListSequenceWidget):
def __init__(self, context, request, subwidget=None):
super(SequenceWidget, self).__init__(context, request)
self.subwidget = subwidget
And then defining tuple/sequence-widgets like this:
tuplex_widget = CustomWidgetFactory(CustomSequenceWidget, subwidget=objectx_w)
listx_widget = CustomWidgetFactory(CustomListSequenceWidget,
subwidget=objectx_w)
This way I got the poll-example of zope/app/form/browser/widget.txt
working, which did not work out of the box. Besides this bigger change there had
to be added some minor changes, espesially in configure.zcml
I suggest to add the two above classes to
zope/app/form/browser/sequencewidget.py
Regards
Christian
The poll-example:
interfaces.py
from zope.interface import Interface
from zope.schema import Object, Tuple, TextLine
from zope.schema.interfaces import ITextLine
from zope.i18n import MessageIDFactory
_ = MessageIDFactory("poll")
class IPollOption(Interface):
label = TextLine(
title=u'Label',
min_length=1)
description = TextLine(
title=u'Description',
min_length=1)
class IPoll(Interface):
options = Tuple(
title=u'Options',
value_type=Object(schema=IPollOption,
title=u'Poll Option'))
def getResponse(option):
"get the response for an option"
def choose(option):
'user chooses an option'
poll.py
from persistent import Persistent
from interfaces import IPoll, IPollOption
from zope.interface import implements, classImplements
class PollOption(Persistent, object):
implements(IPollOption)
class Poll(Persistent, object):
implements(IPoll)
def getResponse(self, option):
return self._responses[option]
def choose(self, option):
self._responses[option] += 1
self._p_changed = 1
def get_options(self):
return self._options
def set_options(self, options):
self._options = options
self._responses = {}
for option in self._options:
self._responses[option.label] = 0
options = property(get_options, set_options, None, 'fiddle options')
browser.py
from zope.app.form.browser.editview import EditView
from zope.app.form.browser.add import AddView
from zope.app.form import CustomWidgetFactory
from zope.app.form.browser import SequenceWidget, ObjectWidget
from interfaces import IPoll, IPollOption
from poll import Poll, PollOption
class PollVoteView:
__used_for__ = IPoll
def choose(self, option):
self.context.choose(option)
self.request.response.redirect('.')
class CustomSequenceWidget(SequenceWidget):
def __init__(self, context, request, subwidget=None):
super(SequenceWidget, self).__init__(context, request)
self.subwidget = subwidget
ow = CustomWidgetFactory(ObjectWidget, PollOption)
sw = CustomWidgetFactory(CustomSequenceWidget, subwidget=ow)
class PollEditView(EditView):
__used_for__ = IPoll
options_widget = sw
class PollAddView(AddView):
__used_for__ = IPoll
options_widget = sw
configure.zcml
vote.zpt
Poll voting
Poll voting
Option
Option
results.zpt
Poll results
Poll results
OptionResultsDescription
Option
Result