zope.formlib has the ability to customize the used widget like this:
class KeywordsManagementForm(five.formlib.formbase.SubPageForm): form_fields = zope.formlib.form.Fields(IKeywords) form_fields['keywords'].custom_widget = KWSelectWidgetFactory
I do not like this approach for two reasons:
- the widget has to be set manually every time the specific field is used
- there is no easy way to get a display widget if the form or field is not editable for the user
Defining a new schema field and registering the widget for this field seems a bit heavy, so I came up with providing a marker interface on the field:
class IHaveSelectableKeywords(zope.interface.Interface): """Marker interface to get a special keywords widget.""" class IKeywords(zope.interface.Interface): keywords = zope.schema.List( title = _("Edit Keywords"), value_type = zope.schema.Choice( vocabulary=u"uc.keywords.Keywords")) zope.interface.alsoProvides(keywords, IHaveSelectableKeywords)
I registered the edit widget and display widget for the IHaveSelectableKeywords
interface, so the custom widget does not have to be set in the form like this (edit widget):
<adapter for=".IHaveSelectableKeywords zope.publisher.interfaces.browser.IBrowserRequest" provides="zope.app.form.browser.interfaces.ISimpleInputWidget" factory=".KWSelectWidgetFactory" permission="zope.Public" />