", line 4.2-7.8
ConfigurationError: ('No such file', '...unknown.pt')
Object Widget template directive
--------------------------------
Show how we can use the objectwidget template directive.
The big difference between the 'simple' Widget template and the Object Widget
directive is that the Object Widget template takes the field's schema into
account. That makes it easy to register different widget templates for different
sub-schemas. You can use this together with SubformAdapter to get a totally
custom subwidget.
We need a custom widget template
>>> widget_file = os.path.join(temp_dir, 'widget.pt')
>>> with open(widget_file, 'w') as file:
... _ = file.write('''
...
...
... yeah, this can get complex
...
...
... ''')
and a interface
>>> class IMyObjectWidget(interfaces.IObjectWidget):
... """My objectwidget interface."""
and a widget class:
>>> from z3c.form.browser import object
>>> @zope.interface.implementer(IMyObjectWidget)
... class MyObjectWidget(object.ObjectWidget):
... pass
>>> request = TestRequest()
>>> myObjectWidget = MyObjectWidget(request)
>>> from z3c.form.testing import IMySubObject
>>> import zope.schema
>>> field = zope.schema.Object(
... __name__='subobject',
... title=u'my object widget',
... schema=IMySubObject)
>>> myObjectWidget.field = field
Make them available under the fake package ``custom``:
>>> sys.modules['custom'] = type(
... 'Module', (),
... {'IMyObjectWidget': IMyObjectWidget})()
and register them as a widget template within the ``z3c:objectWidgetTemplate``
directive:
>>> context = xmlconfig.string("""
...
...
...
... """ % widget_file, context=context)
Let's get the template
>>> template = zope.component.queryMultiAdapter((None, request, None, None,
... myObjectWidget, None), interface=IPageTemplate, name='input')
and check it:
>>> isinstance(template, ViewPageTemplateFile)
True
Let's use the template within the widget.
>>> print(template(myObjectWidget))
yeah, this can get complex
We normally render the widget which returns the registered template.
>>> print(myObjectWidget.render())
yeah, this can get complex
If the template does not exist, then the widget directive should fail
immediately:
>>> unknownFile = os.path.join(temp_dir, 'unknown.pt')
>>> context = xmlconfig.string("""
...
...
...
... """ % unknownFile, context=context)
Traceback (most recent call last):
...
ZopeXMLConfigurationError: File "", line 4.2-7.8
ConfigurationError: ('No such file', '...unknown.pt')
Register a specific template for a schema:
We need a custom widget template
>>> widgetspec_file = os.path.join(temp_dir, 'widgetspec.pt')
>>> with open(widgetspec_file, 'w') as file:
... _ = file.write('''
...
...
... this one is specific
...
...
... ''')
>>> context = xmlconfig.string("""
...
...
...
... """ % widgetspec_file, context=context)
Let's get the template
>>> template = zope.component.queryMultiAdapter((None, request, None, None,
... myObjectWidget, None), interface=IPageTemplate, name='input')
and check it:
>>> print(myObjectWidget.render())
this one is specific
Cleanup
-------
Now we need to clean up the custom module.
>>> del sys.modules['custom']
Also let's not leave temporary files lying around
>>> import shutil
>>> shutil.rmtree(temp_dir)