[Zope-Checkins] CVS: Zope3/lib/python/Zope/PageTemplate - Engine.py:1.1.2.1 Expressions.py:1.1.2.13 PageTemplate.py:1.1.2.18 PageTemplateFile.py:1.1.2.21 PythonExpr.py:1.1.2.8 TALES.py:1.1.2.13 __init__.py:1.1.2.7 EngineConfig.py:NONE SimpleViewClass.py:NONE ViewZPT.py:NONE ZPT.py:NONE

Jim Fulton jim@zope.com
Thu, 23 May 2002 14:01:51 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/PageTemplate
In directory cvs.zope.org:/tmp/cvs-serv26429/lib/python/Zope/PageTemplate

Modified Files:
      Tag: Zope-3x-branch
	Expressions.py PageTemplate.py PageTemplateFile.py 
	PythonExpr.py TALES.py __init__.py 
Added Files:
      Tag: Zope-3x-branch
	Engine.py 
Removed Files:
      Tag: Zope-3x-branch
	EngineConfig.py SimpleViewClass.py ViewZPT.py ZPT.py 
Log Message:
This all started with wanting to be able to use url;view in a ZPT path. :)

That lead me to:

- Massive traversal refactoring.

  Namespace handling is now centralized in Zope.App.Traversing. 

- ZPT refactoring, including some renaming that touches pretty much everything. :)

  - The application specific ZPT support was moved into
    Zope.App.PageTemplate. 

  - To get page template files (for use in views):

    from Zope.App.PageTemplate import ViewPageTemplateFile

  - Fixed up security so that ZPT expressions only have access to 
    safe builtins and so that modules namespace does imports safely.

  - Got ZPTPage working!

- renaming url to absolute_url and got absolute_url to work in paths.

- Cleaned up the (as yet unused) RestrictedInterpreter module in
  Zope.Security. In particular, changed to use a separate
  RestrictedBuiltins module.



=== Added File Zope3/lib/python/Zope/PageTemplate/Engine.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""Expression engine configuration and registration.

Each expression engine can have its own expression types and base names.

$Id: Engine.py,v 1.1.2.1 2002/05/23 18:01:20 jim Exp $
"""

from TALES import ExpressionEngine, RegistrationError
from Expressions import PathExpr, StringExpr, NotExpr, DeferExpr
from Expressions import SimpleModuleImporter
from PythonExpr import PythonExpr

def Engine():
    e = ExpressionEngine()
    reg = e.registerType
    for pt in PathExpr._default_type_names:
        reg(pt, PathExpr)
    reg('string', StringExpr)
    reg('python', PythonExpr)
    reg('not', NotExpr)
    reg('defer', DeferExpr)
    e.registerBaseName('modules', SimpleModuleImporter())
    return e

Engine = Engine()



=== Zope3/lib/python/Zope/PageTemplate/Expressions.py 1.1.2.12 => 1.1.2.13 ===
 ##############################################################################
 """Basic Page Template expression types.
-"""
 
-__version__='$Revision$'[11:-2]
+$Id$
+"""
+__metaclass__ = type # All classes are new style when run with Python 2.2+
 
 import re, sys
-from Zope.Exceptions import Unauthorized
 
 from TALES import ExpressionEngine, CompilerError, RegistrationError
 from TALES import _valid_name, _parse_expr, NAME_RE, Undefined
 from PythonExpr import PythonExpr
 
-# XXX should we have this dependency?
-from Zope.Exceptions import NotFoundError, Unauthorized
-
 Undefs = (Undefined, AttributeError, KeyError,
-          TypeError, IndexError, Unauthorized)
+          TypeError, IndexError)
 
 _marker = object()
 
-def simpleTraverse(object, path_items):
+def simpleTraverse(object, path_items, econtext):
     """Traverses a sequence of names, first trying attributes then items.
     """
 
@@ -42,7 +39,7 @@
         elif hasattr(object, '__getitem__'):
             object = object[name]
         else:
-            raise NotFoundError, name
+            raise NameError, name
     return object
 
 
@@ -83,7 +80,7 @@
         if isinstance(ob, DeferWrapper):
             ob = ob()
         if path:
-            ob = self._traverser(ob, path)
+            ob = self._traverser(ob, path, econtext)
         return ob
 
 


=== Zope3/lib/python/Zope/PageTemplate/PageTemplate.py 1.1.2.17 => 1.1.2.18 ===
 
 HTML- and XML-based template objects using TAL, TALES, and METAL.
-"""
 
-__version__ = '$Revision$'[11:-2]
+$Id$
+"""
+__metaclass__ = type # All classes are new style when run with Python 2.2+
 
 import sys
 from Zope.TAL.TALParser import TALParser
 from Zope.TAL.HTMLTALParser import HTMLTALParser
 from Zope.TAL.TALGenerator import TALGenerator
 from Zope.TAL.TALInterpreter import TALInterpreter
-from EngineConfig import getEngine
+from Engine import Engine
 from cStringIO import StringIO
 
 
-class MacroCollection(object):
+class MacroCollection:
     def __get__(self, parent, type=None):
         parent._cook_check()
         return parent._v_macros
 
 
-class PageTemplate(object):
+_default_options = {}
+
+class PageTemplate:
     """Page Templates using TAL, TALES, and METAL.
 
     Subclassing
@@ -78,15 +81,23 @@
             text = text.read()
         self.write(text)
 
-    def pt_getContext(self, args=(), options={}, **ignored):
+    def pt_getContext(self, args=(), options=_default_options, **ignored):
         rval = {'template': self,
                 'options': options,
                 'args': args,
                 'nothing': None,
                 }
-        rval.update(getEngine(self._engine_name).getBaseNames())
+        rval.update(self.pt_getEngine().getBaseNames())
         return rval
 
+    def __call__(self, *args, **kwargs):
+        return self.pt_render(self.pt_getContext(args, kwargs))
+
+    pt_getEngineContext = Engine.getContext
+
+    def pt_getEngine(self):
+        return Engine
+
     def pt_render(self, namespace, source=0):
         """Render this Page Template"""
         self._cook_check()
@@ -96,14 +107,11 @@
             raise PTRuntimeError(str(self._v_errors))
         output = StringIO()
 
-        context = getEngine(self._engine_name).getContext(namespace)
+        context = self.pt_getEngineContext(namespace)
         TALInterpreter(self._v_program, self._v_macros,
                        context, output, tal=not source, strictinsert=0)()
         return output.getvalue()
 
-    def __call__(self, *args, **kwargs):
-        return self.pt_render(self.pt_getContext(*args, **kwargs))
-
     def pt_errors(self, namespace):
         self._cook_check()
         err = self._v_errors
@@ -160,7 +168,7 @@
 
         Cooking must not fail due to compilation errors in templates.
         """
-        engine = getEngine(self._engine_name)
+        engine = self.pt_getEngine()
         source_file = self.pt_source_file()
         if self.html():
             gen = TALGenerator(engine, xml=0, source_file=source_file)
@@ -173,7 +181,7 @@
         try:
             parser.parseString(self._text)
             self._v_program, self._v_macros = parser.getCode()
-            self.macros = self._v_macros
+            self._v_macros = self._v_macros
         except:
             self._v_errors = ["Compilation failed",
                               "%s: %s" % sys.exc_info()[:2]]


=== Zope3/lib/python/Zope/PageTemplate/PageTemplateFile.py 1.1.2.20 => 1.1.2.21 ===
 import os, sys
 from zLOG import LOG, ERROR, INFO
-from ViewZPT import ViewZPT
-from Zope.Misc.package_home import package_home
+from PageTemplate import PageTemplate
 
-DevelopmentMode = 1  # XXX should be imported from somewhere
+def package_home(gdict):
+    filename = gdict["__file__"]
+    return os.path.dirname(filename)
 
-class MacroCollection:
-    def __of__(self, parent):
-        parent._cook_check()
-        return parent._v_macros
-
-
-class PageTemplateFile(ViewZPT):
+class PageTemplateFile(PageTemplate):
     "Zope wrapper for filesystem Page Template using TAL, TALES, and METAL"
 
-    meta_type = 'Page Template (File)'
-
-    _need__name__ = 1
     _v_last_read = 0
 
-    def __init__(self, filename, _prefix=None, engine_name=None):
-        if _prefix is None:
-            _prefix = sys._getframe(1).f_globals
+    def __init__(self, filename, _prefix=None):
         if not isinstance(_prefix, str):
+            if _prefix is None:
+                _prefix = sys._getframe(1).f_globals
             _prefix = package_home(_prefix)
-        if not os.path.splitext(filename)[1]:
-            filename = filename + '.zpt'
+            
         self.filename = os.path.join(_prefix, filename)
-        if engine_name is not None:
-            # Explicitly choose an expression engine.
-            self._engine_name = engine_name
-
-    def pt_getContext(self, **keywords):
-        return ViewZPT.pt_getContext(self, **keywords)
-
-    def __call__(self, instance, REQUEST, *args, **kw):
-        """Call a Page Template"""
-        self._cook_check()
-        return ViewZPT.__call__(self, instance, REQUEST, *args, **kw)
 
     def _cook_check(self):
-        if self._v_last_read and not DevelopmentMode:
+        if self._v_last_read and not __debug__:
             return
         __traceback_info__ = self.filename
         try:
@@ -82,7 +62,6 @@
     def document_src(self, REQUEST=None):
         """Return expanded document source."""
 
-
         if REQUEST is not None:
             REQUEST.getResponse().setHeader('Content-Type', self.content_type)
         return self.read()
@@ -91,5 +70,4 @@
         return self.filename
 
     def __getstate__(self):
-        raise StorageError, ("Instance of AntiPersistent class %s "
-                             "cannot be stored." % self.__class__.__name__)
+        raise TypeError("non-picklable object")


=== Zope3/lib/python/Zope/PageTemplate/PythonExpr.py 1.1.2.7 => 1.1.2.8 ===
 __version__ = '$Revision$'[11:-2]
 
-_marker = object()
-
-
 class PythonExpr:
     def __init__(self, name, expr, engine):
         text = expr.replace('\n', ' ').strip()
         self.text = text
         # The next line can legally raise SyntaxError.
-        self._code = compile(text, '<string>', 'eval')
-        self._get_used_names()
+        self._code = code = compile(text, '<string>', 'eval')
+        self._varnames = code.co_names
 
-    def _get_used_names(self):
-        vnames = []
-        for vname in self._code.co_names:
-            if vname[0] not in '$_':
-                vnames.append(vname)
-        self._varnames = vnames
-
-    def _bind_used_names(self, econtext):
+    def _bind_used_names(self, econtext, builtins):
         # Bind template variables
         names = {}
         vars = econtext.vars
-        getType = econtext._engine.getTypes().get
-        marker = _marker
+        marker = self
         for vname in self._varnames:
             val = vars.get(vname, marker)
             if val is not marker:
                 names[vname] = val
-            else:
+            elif vname not in builtins:
                 # Fall back to using expression types as variable values.
-                val = getType(vname)
-                if val is not None:
+                val = econtext._engine.getTypes().get(vname, marker)
+                if val is not marker:
                     val = ExprTypeProxy(vname, val, econtext)
                     names[vname] = val
+
+        names['__builtins__'] = builtins
         return names
 
     def __call__(self, econtext):
         __traceback_info__ = self.text
-        vars = self._bind_used_names(econtext)
+        vars = self._bind_used_names(econtext, __builtins__)
         return eval(self._code, vars)
 
     def __str__(self):


=== Zope3/lib/python/Zope/PageTemplate/TALES.py 1.1.2.12 => 1.1.2.13 ===
 An implementation of a generic TALES engine
 """
+__metaclass__ = type # All classes are new style when run with Python 2.2+
 
 __version__ = '$Revision$'[11:-2]
 


=== Zope3/lib/python/Zope/PageTemplate/__init__.py 1.1.2.6 => 1.1.2.7 ===
 ##############################################################################
 """Page Templates for Zope 3."""
-
-from SimpleViewClass import SimpleViewClass
-from PageTemplateFile import PageTemplateFile

=== Removed File Zope3/lib/python/Zope/PageTemplate/EngineConfig.py ===

=== Removed File Zope3/lib/python/Zope/PageTemplate/SimpleViewClass.py ===

=== Removed File Zope3/lib/python/Zope/PageTemplate/ViewZPT.py ===

=== Removed File Zope3/lib/python/Zope/PageTemplate/ZPT.py ===