[ZPT] Patches to PageTemplate product

Shane Hathaway shane@digicool.com
Wed, 04 Apr 2001 17:49:35 -0400


I used ZPT for the first time today.  I jumped right in.  It works well
for the most part, but I really had trouble until I applied the
following patches.  Should I check them in?

Expressions.py is not good about invoking DTML.  The patch fixes it.  It
also invokes the security machinery correctly in restrictedTraverse().

PageTemplate.py and TALES.py generated exceptions that were very
difficult to interpret until I patched them.

Also, we really need to look into providing a way to zero in on a
runtime error in a template, similar to what ZDebug does (it shows the
source of the DTML with the problematic statement highlighted in red.)

Shane

Index: Expressions.py
===================================================================
RCS file:
/cvs-repository/Packages/Products/PageTemplates/Expressions.py,v
retrieving revision 1.4
diff -u -r1.4 Expressions.py
--- Expressions.py	2001/03/27 15:10:09	1.4
+++ Expressions.py	2001/04/04 21:44:40
@@ -95,6 +95,7 @@
 from TALES import Engine, CompilerError, _valid_name, NAME_RE
 from string import strip, split, join, replace, lstrip
 from DocumentTemplate.DT_Util import TemplateDict
+from Acquisition import aq_base, aq_parent
 
 _engine = None
 def getEngine():
@@ -114,6 +115,24 @@
     reg('not', NotExpr)
     reg('import', ImportExpr)
 
+def render(ob):
+    """
+    Calls the object, possibly a document template, or just returns it
if
+    not callable.
+    """
+    base = aq_base(ob)
+    if callable(base):
+        try:
+            if getattr(base, 'isDocTemp', 0):
+                ob = ob(ob, ob.REQUEST)
+            else:
+                ob = ob()
+        except AttributeError, n:
+            if n != '__call__':
+                raise
+    return ob
+
+
 class PathExpr:
     def __init__(self, name, expr):
         self._s = expr
@@ -158,10 +177,11 @@
                 return 1
         if self._name == 'nocall':
             return ob
-        mm = TemplateDict()
-        mm._push(var)
-        mm._push({'_ob': ob})
-        return mm['_ob']
+        return render(ob)
+##        mm = TemplateDict()
+##        mm._push(var)
+##        mm._push({'_ob': ob})
+##        return mm['_ob']
 
     def __str__(self):
         return '%s expression "%s"' % (self._name, self._s)
@@ -310,6 +330,8 @@
 
     if not path: return self
 
+    __traceback_info__ = path
+
     get=getattr
     N=None
     M=[] #marker
@@ -335,7 +357,7 @@
             raise 'NotFound', name
 
         if name=='..':
-            o=getattr(object, 'aq_parent', M)
+            o = aq_parent(object)
             if o is not M:
                 if not securityManager.validate(object, object, name,
o):
                     raise 'Unauthorized', name
@@ -354,19 +376,13 @@
         else:
             o=get(object, name, M)
             if o is not M:
-                # waaaa
-                if hasattr(get(object,'aq_base',object), name):
-                    # value wasn't acquired
-                    if not securityManager.validate(
-                        object, object, name, o):
-                        raise 'Unauthorized', name
-                    pass
+                # Check security.
+                if hasattr(object, 'aq_acquire'):
+                    object.aq_acquire(
+                        name, validate2, securityManager.validate)
                 else:
-                    if not securityManager.validate(
-                        object, None, name, o):
+                    if not securityManager.validate(object, object,
name, o):
                         raise 'Unauthorized', name
-                    pass
-                        
             else:
                 o=object[name]
                 if not securityManager.validate(object, object, None,
o):
@@ -374,3 +390,9 @@
         object = o
 
     return object
+
+
+def validate2(orig, inst, name, v, real_validate):
+    if not real_validate(orig, inst, name, v):
+        raise 'Unauthorized', name
+    return 1
Index: PageTemplate.py
===================================================================
RCS file:
/cvs-repository/Packages/Products/PageTemplates/PageTemplate.py,v
retrieving revision 1.4
diff -u -r1.4 PageTemplate.py
--- PageTemplate.py	2001/03/29 10:21:56	1.4
+++ PageTemplate.py	2001/04/04 21:44:40
@@ -145,7 +145,7 @@
         output = StringIO()
         c = self.pt_getContext()
         c.update(extra_context)
-        __traceback_info__ = c
+        #__traceback_info__ = c
 
         TALInterpreter(self._v_program, self._v_macros,
                        getEngine().getContext(c),
Index: TALES.py
===================================================================
RCS file: /cvs-repository/Packages/Products/PageTemplates/TALES.py,v
retrieving revision 1.3
diff -u -r1.3 TALES.py
--- TALES.py	2001/03/29 10:22:33	1.3
+++ TALES.py	2001/04/04 21:44:40
@@ -252,10 +252,10 @@
     def evaluate(self, expression):
         if type(expression) is type(''):
             expression = self._engine.compile(expression)
-        try:
-            return expression(self)
-        except:
-            raise TALESError, (`expression`, sys.exc_info())
+        #try:
+        return expression(self)
+        #except:
+        #    raise TALESError, (`expression`, sys.exc_info())
 
     evaluateValue = evaluate