[Checkins] SVN: five.pt/trunk/ Update to zope.pagetemplate 3.6.x which provides a means of plugging in the template engine implementation via utility component.

Malthe Borch mborch at gmail.com
Wed Sep 21 09:25:05 EST 2011


Log message for revision 122873:
  Update to zope.pagetemplate 3.6.x which provides a means of plugging in the template engine implementation via utility component.

Changed:
  U   five.pt/trunk/CHANGES.txt
  U   five.pt/trunk/setup.py
  U   five.pt/trunk/src/five/pt/configure.zcml
  A   five.pt/trunk/src/five/pt/engine.py
  D   five.pt/trunk/src/five/pt/patches.py
  A   five.pt/trunk/src/five/pt/tests/test_engine.py
  D   five.pt/trunk/src/five/pt/tests/test_patches.py
  U   five.pt/trunk/src/five/pt/tests/test_persistenttemplate.py

-=-
Modified: five.pt/trunk/CHANGES.txt
===================================================================
--- five.pt/trunk/CHANGES.txt	2011-09-21 14:16:17 UTC (rev 122872)
+++ five.pt/trunk/CHANGES.txt	2011-09-21 14:25:05 UTC (rev 122873)
@@ -1,8 +1,10 @@
 Changelog
 =========
 
-2.1.6 (unreleased)
-~~~~~~~~~~~~~~~~~~
+2.2 (unreleased)
+~~~~~~~~~~~~~~~~
+- Update implementation to use component-based template engine
+  configuration, plugging directly into the Zope Toolkit framework.
 
 - Declare RepeatItem as public object with allowed subobjects
   [leorochael]

Modified: five.pt/trunk/setup.py
===================================================================
--- five.pt/trunk/setup.py	2011-09-21 14:16:17 UTC (rev 122872)
+++ five.pt/trunk/setup.py	2011-09-21 14:25:05 UTC (rev 122873)
@@ -1,6 +1,6 @@
 from setuptools import setup, find_packages
 
-version = '2.1.5'
+version = '2.2-dev'
 
 setup(name='five.pt',
       version=version,
@@ -25,8 +25,9 @@
       zip_safe=False,
       install_requires=[
           'setuptools',
+          'sourcecodegen>=0.6.14',
           'z3c.pt>=2.1.4',
-          'sourcecodegen>=0.6.14',
+          'zope.pagetemplate>=3.6.2',
       ],
       entry_points="""
       [z3c.autoinclude.plugin]

Modified: five.pt/trunk/src/five/pt/configure.zcml
===================================================================
--- five.pt/trunk/src/five/pt/configure.zcml	2011-09-21 14:16:17 UTC (rev 122872)
+++ five.pt/trunk/src/five/pt/configure.zcml	2011-09-21 14:25:05 UTC (rev 122873)
@@ -3,6 +3,8 @@
     xmlns:five="http://namespaces.zope.org/five">
 
   <include package="z3c.pt" />
-  <include package=".patches" />
+  <include package=".engine" />
 
+  <utility component=".engine.Program" />
+
 </configure>

Copied: five.pt/trunk/src/five/pt/engine.py (from rev 122523, five.pt/trunk/src/five/pt/patches.py)
===================================================================
--- five.pt/trunk/src/five/pt/engine.py	                        (rev 0)
+++ five.pt/trunk/src/five/pt/engine.py	2011-09-21 14:25:05 UTC (rev 122873)
@@ -0,0 +1,108 @@
+"""Patch legacy template classes.
+
+We patch the ``TALInterpreter`` class as well as the cook-method on
+the pagetemplate base class (which produces the input for the TAL
+interpreter).
+"""
+
+import sys
+
+from zope.tal.talinterpreter import TALInterpreter
+from zope.interface import implements
+from zope.interface import classProvides
+
+from zope.pagetemplate.pagetemplate import PageTemplate
+from zope.pagetemplate.interfaces import IPageTemplateEngine
+from zope.pagetemplate.interfaces import IPageTemplateProgram
+
+from z3c.pt.pagetemplate import PageTemplate as ChameleonPageTemplate
+from z3c.pt.pagetemplate import PageTemplateFile as ChameleonPageTemplateFile
+
+from AccessControl.SecurityInfo import ClassSecurityInfo
+from App.class_init import InitializeClass
+from Products.PageTemplates.Expressions import getEngine
+from Products.PageTemplates import ZRPythonExpr
+
+from chameleon.tales import StringExpr
+from chameleon.tales import NotExpr
+from chameleon.tal import RepeatDict
+
+from z3c.pt.expressions import PythonExpr
+
+from .expressions import PathExpr
+from .expressions import TrustedPathExpr
+from .expressions import ProviderExpr
+from .expressions import NocallExpr
+from .expressions import ExistsExpr
+from .expressions import UntrustedPythonExpr
+
+
+# Declare Chameleon's repeat dictionary public
+RepeatDict.security = ClassSecurityInfo()
+RepeatDict.security.declareObjectPublic()
+RepeatDict.__allow_access_to_unprotected_subobjects__ = True
+
+InitializeClass(RepeatDict)
+
+
+class Program(object):
+    implements(IPageTemplateProgram)
+    classProvides(IPageTemplateEngine)
+
+    # Zope 2 Page Template expressions
+    secure_expression_types = {
+        'python': UntrustedPythonExpr,
+        'string': StringExpr,
+        'not': NotExpr,
+        'exists': ExistsExpr,
+        'path': PathExpr,
+        'provider': ProviderExpr,
+        'nocall': NocallExpr,
+        }
+
+    # Zope 3 Page Template expressions
+    expression_types = {
+        'python': PythonExpr,
+        'string': StringExpr,
+        'not': NotExpr,
+        'exists': ExistsExpr,
+        'path': TrustedPathExpr,
+        'provider': ProviderExpr,
+        'nocall': NocallExpr,
+        }
+
+    extra_builtins = {
+        'modules': ZRPythonExpr._SecureModuleImporter()
+        }
+
+    def __init__(self, template):
+        self.template = template
+
+    def __call__(self, context, macros, tal=True, **options):
+        if tal is False:
+            return self.template.body
+
+        # Swap out repeat dictionary for Chameleon implementation
+        # and store wrapped dictionary in new variable -- this is
+        # in turn used by the secure Python expression
+        # implementation whenever a 'repeat' symbol is found
+        kwargs = context.vars
+        kwargs['wrapped_repeat'] = kwargs['repeat']
+        kwargs['repeat'] = RepeatDict(context.repeat_vars)
+
+        return self.template.render(**kwargs)
+
+    @classmethod
+    def cook(cls, source_file, text, engine, content_type):
+        if engine is getEngine():
+            expression_types = cls.secure_expression_types
+        else:
+            expression_types = cls.expression_types
+
+        template = ChameleonPageTemplate(
+            text, filename=source_file, keep_body=True,
+            expression_types=expression_types,
+            encoding='utf-8', extra_builtins=cls.extra_builtins,
+            )
+
+        return cls(template), template.macros

Deleted: five.pt/trunk/src/five/pt/patches.py
===================================================================
--- five.pt/trunk/src/five/pt/patches.py	2011-09-21 14:16:17 UTC (rev 122872)
+++ five.pt/trunk/src/five/pt/patches.py	2011-09-21 14:25:05 UTC (rev 122873)
@@ -1,139 +0,0 @@
-"""Patch legacy template classes.
-
-We patch the ``TALInterpreter`` class as well as the cook-method on
-the pagetemplate base class (which produces the input for the TAL
-interpreter).
-"""
-
-import sys
-
-from zope.tal.talinterpreter import TALInterpreter
-from zope.pagetemplate.pagetemplate import PageTemplate
-from z3c.pt.pagetemplate import PageTemplate as ChameleonPageTemplate
-
-from AccessControl.SecurityInfo import ClassSecurityInfo
-from App.class_init import InitializeClass
-from Products.PageTemplates.Expressions import getEngine
-from Products.PageTemplates import ZRPythonExpr
-
-from chameleon.tales import StringExpr
-from chameleon.tales import NotExpr
-from chameleon.tal import RepeatDict
-from chameleon.tal import RepeatItem
-
-from z3c.pt.expressions import PythonExpr
-
-from .expressions import PathExpr
-from .expressions import TrustedPathExpr
-from .expressions import ProviderExpr
-from .expressions import NocallExpr
-from .expressions import ExistsExpr
-from .expressions import UntrustedPythonExpr
-
-
-# Declare Chameleon's repeat objects public
-_public_classes = [
-    RepeatDict,
-    RepeatItem,
-]
-for cls in _public_classes:
-    cls.security = ClassSecurityInfo()
-    cls.security.declareObjectPublic()
-    cls.__allow_access_to_unprotected_subobjects__ = True
-    InitializeClass(cls)
-
-# Zope 2 Page Template expressions
-_secure_expression_types = {
-    'python': UntrustedPythonExpr,
-    'string': StringExpr,
-    'not': NotExpr,
-    'exists': ExistsExpr,
-    'path': PathExpr,
-    'provider': ProviderExpr,
-    'nocall': NocallExpr,
-    }
-
-
-# Zope 3 Page Template expressions
-_expression_types = {
-    'python': PythonExpr,
-    'string': StringExpr,
-    'not': NotExpr,
-    'exists': ExistsExpr,
-    'path': TrustedPathExpr,
-    'provider': ProviderExpr,
-    'nocall': NocallExpr,
-    }
-
-
-def cook(self):
-    program = self._v_program
-    if program is None:
-        engine = self.pt_getEngine()
-        source_file = self.pt_source_file()
-
-        if engine is getEngine():
-            expression_types = _secure_expression_types
-        else:
-            expression_types = _expression_types
-
-        extra_builtins = {
-            'modules': ZRPythonExpr._SecureModuleImporter()
-            }
-
-        program = ChameleonPageTemplate(
-            "", filename=source_file, keep_body=True,
-            expression_types=expression_types,
-            encoding='utf-8', extra_builtins=extra_builtins,
-            )
-
-        self._v_program = program
-        self._v_macros = program.macros
-
-    try:
-        program.cook(self._text)
-    except:
-        etype, e = sys.exc_info()[:2]
-        self._v_errors = [
-            "Compilation failed",
-            "%s.%s: %s" % (etype.__module__, etype.__name__, e)
-            ]
-    else:
-        self._v_errors = ()
-
-    self._v_cooked = 1
-
-
- at staticmethod
-def create_interpreter(cls, *args, **kwargs):
-    return ChameleonTALInterpreter(*args, **kwargs)
-
-
-class ChameleonTALInterpreter(object):
-    def __init__(self, template, macros, context, stream, tal=True, **kwargs):
-        self.template = template
-        self.context = context.vars
-        self.repeat = context.repeat_vars
-        self.stream = stream
-        self.tal = tal
-
-    def __call__(self):
-        if self.tal is False:
-            result = self.template.body
-        else:
-            context = self.context
-
-            # Swap out repeat dictionary for Chameleon implementation
-            # and store wrapped dictionary in new variable -- this is
-            # in turn used by the secure Python expression
-            # implementation whenever a 'repeat' symbol is found
-            context['wrapped_repeat'] = context['repeat']
-            context['repeat'] = RepeatDict(self.repeat)
-
-            result = self.template.render(**context)
-
-        self.stream.write(result)
-
-
-TALInterpreter.__new__ = create_interpreter
-PageTemplate._cook = cook

Copied: five.pt/trunk/src/five/pt/tests/test_engine.py (from rev 122522, five.pt/trunk/src/five/pt/tests/test_patches.py)
===================================================================
--- five.pt/trunk/src/five/pt/tests/test_engine.py	                        (rev 0)
+++ five.pt/trunk/src/five/pt/tests/test_engine.py	2011-09-21 14:25:05 UTC (rev 122873)
@@ -0,0 +1,61 @@
+import os
+import unittest
+
+from Testing.ZopeTestCase import ZopeTestCase
+from Testing.ZopeTestCase.sandbox import Sandboxed
+
+path = os.path.dirname(__file__)
+
+class TestPatches(Sandboxed, ZopeTestCase):
+    def afterSetUp(self):
+        from Products.Five import zcml
+        import Products.Five
+        import z3c.pt
+        import five.pt
+        zcml.load_config("configure.zcml", Products.Five)
+        zcml.load_config("configure.zcml", five.pt)
+        zcml.load_config("configure.zcml", z3c.pt)
+
+    def test_pagetemplate(self):
+        from Products.PageTemplates.PageTemplate import PageTemplate
+        template = PageTemplate()
+
+        # test rendering engine
+        template.write(open(os.path.join(path, "simple.pt")).read())
+        self.assertTrue('world' in template())
+
+        # test arguments
+        template.write(open(os.path.join(path, "options.pt")).read())
+        self.assertTrue('Hello world' in template(greeting='Hello world'))
+
+    def test_pagetemplatefile(self):
+        from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+
+        # test rendering engine
+        template = PageTemplateFile(os.path.join(path, "simple.pt"))
+        template = template.__of__(self.folder)
+        self.assertTrue('world' in template())
+
+    def test_zopepagetemplate(self):
+        from Products.PageTemplates.ZopePageTemplate import manage_addPageTemplate
+        template = manage_addPageTemplate(self.folder, 'test')
+
+        # aq-wrap before we proceed
+        template = template.__of__(self.folder)
+
+        # test rendering engine
+        template.write(open(os.path.join(path, "simple.pt")).read())
+        self.assertTrue('world' in template())
+
+        # test arguments
+        template.write(open(os.path.join(path, "options.pt")).read())
+        self.assertTrue('Hello world' in template(
+            greeting='Hello world'))
+
+        # test commit
+        import transaction
+        transaction.commit()
+
+def test_suite():
+    import sys
+    return unittest.findTestCases(sys.modules[__name__])

Deleted: five.pt/trunk/src/five/pt/tests/test_patches.py
===================================================================
--- five.pt/trunk/src/five/pt/tests/test_patches.py	2011-09-21 14:16:17 UTC (rev 122872)
+++ five.pt/trunk/src/five/pt/tests/test_patches.py	2011-09-21 14:25:05 UTC (rev 122873)
@@ -1,62 +0,0 @@
-import os
-import unittest
-
-from Testing.ZopeTestCase import ZopeTestCase
-from Testing.ZopeTestCase.sandbox import Sandboxed
-
-path = os.path.dirname(__file__)
-
-class TestPatches(Sandboxed, ZopeTestCase):
-    def afterSetUp(self):
-        from Products.Five import zcml
-        import Products.Five
-        import z3c.pt
-        import five.pt
-        zcml.load_config("configure.zcml", Products.Five)
-        zcml.load_config("configure.zcml", five.pt)
-        zcml.load_config("configure.zcml", z3c.pt)
-
-    def test_pagetemplate(self):
-        from Products.PageTemplates.PageTemplate import PageTemplate
-        template = PageTemplate()
-
-        # test rendering engine
-        template.write(open(os.path.join(path, "simple.pt")).read())
-        self.assertTrue('world' in template())
-
-        # test arguments
-        template.write(open(os.path.join(path, "options.pt")).read())
-        self.assertTrue('Hello world' in template(
-            greeting='Hello world'))
-
-    def test_pagetemplatefile(self):
-        from Products.PageTemplates.PageTemplateFile import PageTemplateFile
-
-        # test rendering engine
-        template = PageTemplateFile(os.path.join(path, "simple.pt"))
-        template = template.__of__(self.folder)
-        self.assertTrue('world' in template())
-
-    def test_zopepagetemplate(self):
-        from Products.PageTemplates.ZopePageTemplate import manage_addPageTemplate
-        template = manage_addPageTemplate(self.folder, 'test')
-
-        # aq-wrap before we proceed
-        template = template.__of__(self.folder)
-
-        # test rendering engine
-        template.write(open(os.path.join(path, "simple.pt")).read())
-        self.assertTrue('world' in template())
-
-        # test arguments
-        template.write(open(os.path.join(path, "options.pt")).read())
-        self.assertTrue('Hello world' in template(
-            greeting='Hello world'))
-
-        # test commit
-        import transaction
-        transaction.commit()
-
-def test_suite():
-    import sys
-    return unittest.findTestCases(sys.modules[__name__])

Modified: five.pt/trunk/src/five/pt/tests/test_persistenttemplate.py
===================================================================
--- five.pt/trunk/src/five/pt/tests/test_persistenttemplate.py	2011-09-21 14:16:17 UTC (rev 122872)
+++ five.pt/trunk/src/five/pt/tests/test_persistenttemplate.py	2011-09-21 14:25:05 UTC (rev 122873)
@@ -159,23 +159,13 @@
 
     def test_avoid_recompilation(self):
         template = self._makeOne('foo', simple_i18n)
-        macro_template = self._makeOne('macro_outer', macro_outer)
-        # templates are only compiled after the first call
-        self.assertEqual(getattr(template, '_v_template', _marker), _marker)
-        template()
-        # or the first fetching of macros
-        self.assertEqual(getattr(macro_template, '_v_template', _marker),
-                         _marker)
-        macro_template.macros
 
-        template_compiled = template._v_program
-        macro_template_compiled = macro_template._v_program
+        # Template is already cooked
+        program = template._v_program
+        template.pt_render({})
 
-        # but they should not be recompiled afterwards
-        template()
-        macro_template.macros
-        self.assertTrue(template_compiled is template._v_program)
-        self.assertTrue(macro_template_compiled is macro_template._v_program)
+        # The program does not change
+        self.assertEqual(program, template._v_program)
 
     def test_repeat_object_security(self):
         template = self._makeOne('foo', repeat_object)



More information about the checkins mailing list