[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