[Zope3-dev] RFC: CustomWidgetFactory and widgets having different
__init__ signature
Dominik Huber
dominik.huber at perse.ch
Tue Nov 15 09:56:37 EST 2005
Adam Groszer wrote:
>As I'm digging through zope.app.form.browser to fix the
>CustomWidgetFactory collector issue, I found the following:
>
>IWidget has no __init__ defined
>
>class Widget(object):
> def __init__(self, context, request):
>
>class ItemsWidgetBase(TranslationHook, SimpleInputWidget):
> def __init__(self, field, vocabulary, request):
>
>class ItemsEditWidgetBase(SingleDataHelper, ItemsWidgetBase):
> def __init__(self, field, vocabulary, request):
>
>class ObjectWidget(BrowserWidget, InputWidget):
> def __init__(self, context, request, factory, **kw):
>
>class SequenceWidget(BrowserWidget, InputWidget):
> def __init__(self, context, field, request, subwidget=None):
>
>class SequenceDisplayWidget(DisplayWidget):
> def __init__(self, context, field, request, subwidget=None):
>
>class SourceDisplayWidget(zope.app.form.Widget):
> def __init__(self, field, source, request):
>
>class SourceInputWidget(zope.app.form.InputWidget):
> def __init__(self, field, source, request):
>
>class SourceSelectWidget(zope.app.form.browser.SelectWidget):
> def __init__(self, field, source, request):
>
>CustomWidgetFactory fails on these different signatures. This affects
>the ZCML <browser:widget field="..." class="..."/>. Simple widgets
>will work, widgets with different signatures of course not.
>
>class CustomWidgetFactory(object):
> implements(IViewFactory)
> def __call__(self, context, request):
>class CustomSequenceWidgetFactory(object):
> implements(IViewFactory)
> def __call__(self, context, field, request):
>
>In fact, CustomSequenceWidgetFactory violates the IViewFactory
>interface with the different __call__ signature. That causes
>setUpWidget to fail. I'm wondering if this worked for anyone anytime.
>
>
No, the widget stuff was broken long time ago. Phillip did some fixes
within a branch, but this branch got deleted during the last repository
cleaned up.
I'm not shure which change the widget-refactoring will bring, that was
the reason why I never was digging deeper.
(svn://svn.zope.org/repos/main/Zope3/branches/f12gsprint-widget).
>Now I'm stuck a little bit. How does a good solution look like?
>
>My half-baked solution was up to today for Itemswidgets (which caused
>the error for me) to mark it with a different interface and look for
>that in CustomWidgetFactory and pass different arguments.
>Now I'm not so sure that this is the right one.
>
>
The current solution does not covers ObjectWidgets. My solutions are
half-baked too, but maybe we can collect them to get an overview (see
attached file).
The problem can be split in two parts:
1. __call__ with different signatures
2. creation/customization of widgets using the setattr(instance, name,
value)
Regards,
Dominik
-------------- next part --------------
from zope.component.interfaces import IViewFactory
from zope.interface import implements
from zope.schema.interfaces import IChoice, ICollection
class CustomWidgetFactory(object):
"""Custom Widget Factory."""
implements(IViewFactory)
def __init__(self, widget_factory, *args, **kw):
self._widget_factory = widget_factory
self.args = args
self.kw = kw
def _create(self, args):
instance = self._widget_factory(*args)
for name, value in self.kw.items():
setattr(instance, name, value)
return instance
def __call__(self, context, request):
return self._create((context, request) + self.args)
class CustomSequenceWidgetFactory(CustomWidgetFactory):
"""Custom sequence widget factory."""
def __call__(self, context, request):
if not ICollection.providedBy(context):
raise TypeError, "Provided field does not provide ICollection."
args = (context, context.value_type, request) + self.args
return self._create(args)
class CustomVocabularyWidgetFactory(CustomWidgetFactory):
"""Custom vocabulary widget factory."""
def __call__(self, context, request):
if not IChoice.providedBy(context):
raise TypeError, "Provided field does not provide ICollection."
args = (context, context.vocabulary, request) + self.args
return self._create(args)
class TemplateWidgetFactory(CustomWidgetFactory):
"""The view kw attribute is called like a ViewPageTemplateFile."""
def _create(self, args):
instance = self._widget_factory(*args)
for name, value in self.kw.items():
if name is 'view':
setattr(instance, name, value(instance, instance.request))
else:
setattr(instance, name, value)
return instance
class TemplateSequenceWidgetFactory(CustomSequenceWidgetFactory):
"""The view kw attribute is called like a ViewPageTemplateFile."""
def _create(self, args):
instance = self._widget_factory(*args)
for name, value in self.kw.items():
if name is 'view':
setattr(instance, name, value(instance, instance.request))
else:
setattr(instance, name, value)
return instance
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dominik.huber.vcf
Type: text/x-vcard
Size: 154 bytes
Desc: not available
Url : http://mail.zope.org/pipermail/zope3-dev/attachments/20051115/b60a2531/dominik.huber.vcf
More information about the Zope3-dev
mailing list