[Checkins] SVN: z3c.form/branches/fieldsandcontentproviders/src/z3c/form/ initial concept of contentprovider in a form
Jean-Francois Roche
jfroche at jfroche.be
Fri Feb 12 07:26:27 EST 2010
Log message for revision 108950:
initial concept of contentprovider in a form
Changed:
A z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.py
A z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.txt
U z3c.form/branches/fieldsandcontentproviders/src/z3c/form/interfaces.py
U z3c.form/branches/fieldsandcontentproviders/src/z3c/form/tests/test_doc.py
-=-
Added: z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.py
===================================================================
--- z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.py (rev 0)
+++ z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.py 2010-02-12 12:26:27 UTC (rev 108950)
@@ -0,0 +1,76 @@
+import zope.component
+import zope.interface
+import zope.location
+import zope.schema.interfaces
+
+from z3c.form.field import FieldWidgets
+from z3c.form import interfaces, util
+from z3c.form.widget import AfterWidgetUpdateEvent
+
+
+class ContentProviders(dict):
+
+ def __getitem__(self, key):
+ factory = super(ContentProviders, self).__getitem__(key)
+ return ContentProviderFactory(name=key, factory=factory)
+
+
+class ContentProviderFactory(object):
+
+ def __init__(self, factory, *args, **kwargs):
+ self.factory = factory
+ self.args = args
+ self.kwargs = kwargs
+
+ def __call__(self, manager):
+ contentProvider = self.factory(manager.form, manager.request, manager.form)
+ return contentProvider
+
+
+class FieldWidgetsAndProviders(FieldWidgets):
+ zope.component.adapts(
+ interfaces.IWidgetsForm, interfaces.IFormLayer, zope.interface.Interface)
+ zope.interface.implementsOnly(interfaces.IWidgets)
+
+ def update(self):
+ super(FieldWidgetsAndProviders, self).update()
+ prefix = util.expandPrefix(self.form.prefix)
+ prefix += util.expandPrefix(self.prefix)
+
+ uniqueOrderedKeys = self._data_keys
+ for name in self.form.contentProviders:
+ factory = self.form.contentProviders[name]
+ contentProvider = factory(self)
+ newWidget = True
+ ignoreContext = True
+ # Step 1: Determine the mode of the contentProvider.
+ mode = self.mode
+ # Step 2: Get the widget for the given field.
+ shortName = name
+ #widget.name = prefix + shortName
+ contentProvider.id = (prefix + shortName).replace('.', '-')
+ # Step 4: Set the context
+ contentProvider.context = self.content
+ # Step 5: Set the form
+ contentProvider.form = self.form
+ # Optimization: Set both interfaces here, rather in step 4 and 5:
+ # ``alsoProvides`` is quite slow
+ zope.interface.alsoProvides(
+ contentProvider, interfaces.IContextAware, interfaces.IFormAware)
+ # Step 6: Set some variables
+ contentProvider.ignoreContext = ignoreContext
+ contentProvider.ignoreRequest = self.ignoreRequest
+ # Step 7: Set the mode of the widget
+ contentProvider.mode = mode
+ # Step 8: Update the widget
+ contentProvider.update()
+ zope.event.notify(AfterWidgetUpdateEvent(contentProvider))
+ # Step 9: Add the widget to the manager
+ uniqueOrderedKeys.append(shortName)
+ if newWidget:
+ self._data_values.append(contentProvider)
+ self._data[shortName] = contentProvider
+ zope.location.locate(contentProvider, self, shortName)
+ # allways ensure that we add all keys and keep the order given from
+ # button items
+ self._data_keys = uniqueOrderedKeys
Added: z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.txt
===================================================================
--- z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.txt (rev 0)
+++ z3c.form/branches/fieldsandcontentproviders/src/z3c/form/contentprovider.txt 2010-02-12 12:26:27 UTC (rev 108950)
@@ -0,0 +1,71 @@
+ContentProviders
+----------------
+
+Before we can use a widget manager, we have to register the ``IFieldWidget`` adapter
+for the ``ITextLine`` field:
+
+ >>> import zope.component
+ >>> import zope.interface
+ >>> from z3c.form import interfaces, widget
+ >>> from z3c.form.testing import TestRequest
+
+ >>> @zope.component.adapter(zope.schema.TextLine, TestRequest)
+ ... @zope.interface.implementer(interfaces.IFieldWidget)
+ ... def TextFieldWidget(field, request):
+ ... return widget.FieldWidget(field, widget.Widget(request))
+
+ >>> zope.component.provideAdapter(TextFieldWidget)
+
+ >>> from z3c.form import converter
+ >>> zope.component.provideAdapter(converter.FieldDataConverter)
+ >>> zope.component.provideAdapter(converter.FieldWidgetDataConverter)
+
+ >>> import zope.interface
+ >>> import zope.schema
+
+ >>> class IPerson(zope.interface.Interface):
+ ... id = zope.schema.TextLine(
+ ... title=u'ID',
+ ... description=u"The person's ID.",
+ ... readonly=True,
+ ... required=True)
+ ...
+
+We want to mix fields and content providers::
+
+ >>> from z3c.form import field, form
+ >>> from z3c.form.interfaces import IWidgetsForm
+ >>> from z3c.form import widget
+ >>> from zope.contentprovider.provider import ContentProviderBase
+
+ >>> class ExtendedHelp(ContentProviderBase):
+ ...
+ ... def update(self):
+ ... pass
+ ...
+ ... def render(self):
+ ... """see `z3c.form.interfaces.IWidget`
+ ... """
+ ... return '<div class="extendedhelp">Some very long help text ...</div>'
+
+ >>> from z3c.form.contentprovider import ContentProviders
+ >>> class PersonForm(form.Form):
+ ... zope.interface.implements(IWidgetsForm)
+ ... prefix = 'form.'
+ ... fields = field.Fields(IPerson)
+ ... contentProviders = ContentProviders()
+ ... contentProviders['longHelp'] = ExtendedHelp
+
+ >>> from z3c.form.testing import TestRequest
+ >>> request = TestRequest()
+ >>> context = object()
+ >>> personForm = PersonForm(context, request)
+
+ >>> from z3c.form.contentprovider import FieldWidgetsAndProviders
+ >>> manager = FieldWidgetsAndProviders(personForm, request, context)
+ >>> manager.ignoreContext = True
+ >>> manager.update()
+ >>> manager._data
+ {'longHelp': <ExtendedHelp object at ...>, 'id': <Widget 'form.widgets.id'>}
+ >>> manager.get('longHelp').render()
+ '<div class="extendedhelp">Some very long help text ...</div>'
Modified: z3c.form/branches/fieldsandcontentproviders/src/z3c/form/interfaces.py
===================================================================
--- z3c.form/branches/fieldsandcontentproviders/src/z3c/form/interfaces.py 2010-02-12 12:10:09 UTC (rev 108949)
+++ z3c.form/branches/fieldsandcontentproviders/src/z3c/form/interfaces.py 2010-02-12 12:26:27 UTC (rev 108950)
@@ -1007,7 +1007,15 @@
'the form.'),
schema=IFields)
+class IWidgetsForm(IForm):
+ """A form that is based upon defined fields."""
+ widgetsItems = zope.schema.Object(
+ title=_('Widgets'),
+ description=_('A field manager describing the fields to be used for '
+ 'the form.'),
+ schema=IFields)
+
class IButtonForm(IForm):
"""A form that is based upon defined buttons."""
Modified: z3c.form/branches/fieldsandcontentproviders/src/z3c/form/tests/test_doc.py
===================================================================
--- z3c.form/branches/fieldsandcontentproviders/src/z3c/form/tests/test_doc.py 2010-02-12 12:10:09 UTC (rev 108949)
+++ z3c.form/branches/fieldsandcontentproviders/src/z3c/form/tests/test_doc.py 2010-02-12 12:26:27 UTC (rev 108950)
@@ -56,6 +56,12 @@
checker=checker,
),
doctest.DocFileSuite(
+ '../contentprovider.txt',
+ setUp=setUp, tearDown=testing.tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ checker=checker,
+ ),
+ doctest.DocFileSuite(
'../value.txt',
setUp=placelesssetup.setUp, tearDown=placelesssetup.tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
More information about the checkins
mailing list