Question

Given following widget based on z3c.form https://github.com/collective/Products.UserAndGroupSelectionWidget/blob/z3cform-widget/src/Products/UserAndGroupSelectionWidget/z3cform/widget.py

I would like in some browserview to access its settings and corresponding field. Since Widget does not know the schema and field upfront, I'm interested in what information do I need to get widget and field. Currently I have available the fieldname and context, which seemed to be enough for archtypes https://github.com/collective/Products.UserAndGroupSelectionWidget/blob/z3cform-widget/src/Products/UserAndGroupSelectionWidget/browser.py#L60

EDIT: To simplify the question, I would like to access a field that is defined in some z3c form and its widget. I could not find other way except passing request and context to form init and then accessing the field. Is there a multiadapter?

The idea is to have a z3c.form widget that people hook into whatever field which does an ajax call. That ajax request needs to pass parameters and response will lookup where widget was used and with what settings. The question is, how to lookup the z3c.form field and which information is needed to do so?

Was it helpful?

Solution

Getting the Field

If you can get the schema, you can get the field.

For a dexterity content type, if you know the field name and the type's portal_type, you can get the schema from the type's Factory Type Information (FTI).

So, if we know portal_type and field_name:

from zope.component import getUtility
from plone.dexterity.interfaces import IDexterityFTI
fti = getUtility(IDexterityFTI, name=portal_type)
schema = fti.lookupSchema()
field = schema.get(field_name)

Getting the Widget

From the z3c.form documentation: http://packages.python.org/z3c.form/widget.html

The widget is a multiadapter, so if you have the field, you can get it like so:

ageWidget = zope.component.getMultiAdapter((field, request),
    interfaces.IFieldWidget)

Important: If you have however specified a widget via plone.autoform, then that widget won't be fetched. plone.autoform manually sets a widgetFactory on the z3c.form.field.Field object (which is not the same as the zope.schema Field!). The best way to get the widget then, is what you have already done, by manually calling initiating a FieldWidget.

So for example if you want the UserAndGroupSelectionWidget:

widget = FieldWidget(field, UserAndGroupSelectionWidget(field, request))

P.S Since I'm also in the collective and use the picker widget, I've updated the code for you ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top