Added "override_template" and "override_layout" functions to be able to override templates without creating new classes or using ZCML
authorThierry Florac <thierry.florac@onf.fr>
Wed, 23 May 2018 15:22:28 +0200
changeset 11 be5b3d594a84
parent 10 1acfa99756ad
child 12 fae764fa609a
Added "override_template" and "override_layout" functions to be able to override templates without creating new classes or using ZCML
src/pyams_template/template.py
--- a/src/pyams_template/template.py	Wed May 23 15:21:24 2018 +0200
+++ b/src/pyams_template/template.py	Wed May 23 15:22:28 2018 +0200
@@ -27,6 +27,7 @@
 from pyramid.exceptions import ConfigurationError
 from pyramid_chameleon.zpt import PyramidPageTemplateFile
 from zope.component import queryUtility
+from zope.component.globalregistry import getGlobalSiteManager
 from zope.interface import directlyProvides
 
 
@@ -158,6 +159,28 @@
         return wrapped
 
 
+def override_template(context, **settings):
+    """Override template for a given context
+
+    This function can be used to override a class template without using ZCML.
+    Settings are the same as for @template_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')
+    macro = settings.get('macro')
+    factory = TemplateFactory(template, contentType, macro)
+    provides = settings.get('provides', IContentTemplate)
+    directlyProvides(factory, provides)
+    registry = getGlobalSiteManager()
+    registry.registerAdapter(factory,
+                             (context, settings.get('layer', IRequest)),
+                             provides, settings.get('name', ''))
+
+
 class layout_config(object):
     """Class decorator used to declare a layout template"""
 
@@ -200,3 +223,25 @@
 
         settings['_info'] = info.codeinfo  # fbo "action_method"
         return wrapped
+
+
+def override_layout(context, **settings):
+    """Override layout template for a given class
+
+    This function can be used to override a class layout template without using ZCML.
+    Settings are the same as for @layout_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')
+    macro = settings.get('macro')
+    factory = TemplateFactory(template, contentType, macro)
+    provides = settings.get('provides', ILayoutTemplate)
+    directlyProvides(factory, provides)
+    registry = getGlobalSiteManager()
+    registry.registerAdapter(factory,
+                             (context, settings.get('layer', IRequest)),
+                             provides, settings.get('name', ''))