Added "override_widget_template" and "override_widget_layout" functions
authorThierry Florac <thierry.florac@onf.fr>
Fri, 19 Oct 2018 17:47:05 +0200
changeset 155 42c7d16e01fc
parent 154 92688225ec40
child 156 437f3b783d25
Added "override_widget_template" and "override_widget_layout" functions
src/pyams_form/widget/__init__.py
--- a/src/pyams_form/widget/__init__.py	Wed Oct 17 16:10:30 2018 +0200
+++ b/src/pyams_form/widget/__init__.py	Fri Oct 19 17:47:05 2018 +0200
@@ -30,6 +30,7 @@
 from z3c.form.interfaces import DISPLAY_MODE, IButtonAction, IDataConverter, IFieldWidget, INPUT_MODE, ITextWidget, \
     IWidgetLayoutTemplate, NO_VALUE
 from z3c.form.widget import FieldWidget, WidgetLayoutFactory, WidgetTemplateFactory
+from zope.component import getGlobalSiteManager
 from zope.interface import Interface, directlyProvides, implementer, implementer_only
 from zope.pagetemplate.interfaces import IPageTemplate
 from zope.schema.fieldproperty import FieldProperty
@@ -99,6 +100,32 @@
         return wrapped
 
 
+def override_widget_template(widget, **settings):
+    """Override template for a given widget
+
+    This function can be used to override a widget template without using ZCML.
+    Settings are the same as for @widgettemplate_config decorator.
+    """
+    stack = inspect.stack()[-1]
+    template = os.path.join(os.path.dirname(inspect.getfile(inspect.getmodule(stack[0]))),
+                            settings.get('template'))
+    if not os.path.isfile(template):
+        raise ConfigurationError("No such file", template)
+    contentType = settings.get('contentType', 'text/html')
+    factory = WidgetTemplateFactory(template, contentType)
+    provides = settings.get('provides', IPageTemplate)
+    directlyProvides(factory, provides)
+    registry = getGlobalSiteManager()
+    registry.registerAdapter(factory,
+                             (settings.get('context', Interface),
+                              settings.get('layer', IRequest),
+                              settings.get('view', None),
+                              settings.get('field', None),
+                              widget),
+                             provides,
+                             settings.get('mode', INPUT_MODE))
+
+
 class widgetlayout_config(object):
     """Class decorator used to declare a widget layout"""
 
@@ -147,6 +174,32 @@
         return wrapped
 
 
+def override_widget_layout(widget, **settings):
+    """Override layout template for a given widget
+
+    This function can be used to override a widget layout template without using ZCML.
+    Settings are the same as for @widgetlayout_config decorator.
+    """
+    stack = inspect.stack()[-1]
+    template = os.path.join(os.path.dirname(inspect.getfile(inspect.getmodule(stack[0]))),
+                            settings.get('template'))
+    if not os.path.isfile(template):
+        raise ConfigurationError("No such file", template)
+    contentType = settings.get('contentType', 'text/html')
+    factory = WidgetTemplateFactory(template, contentType)
+    provides = settings.get('provides', IWidgetLayoutTemplate)
+    directlyProvides(factory, provides)
+    registry = getGlobalSiteManager()
+    registry.registerAdapter(factory,
+                             (settings.get('context', Interface),
+                              settings.get('layer', IRequest),
+                              settings.get('view', None),
+                              settings.get('field', None),
+                              widget),
+                             provides,
+                             settings.get('mode', INPUT_MODE))
+
+
 #
 # Reset button widget and action
 #