[Zope-Checkins]
SVN: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/
getting rid of the old ZPT implementation
Andreas Jung
andreas at andreas-jung.com
Sun Dec 11 07:53:04 EST 2005
Log message for revision 40699:
getting rid of the old ZPT implementation
Changed:
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/DeferExpr.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/Expressions.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/GlobalTranslationService.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/HISTORY.txt
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplate.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplateFile.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/README.txt
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/TALES.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZPythonExpr.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZRPythonExpr.py
U Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZopePageTemplate.py
A Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/
A Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/default.html
A Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/exclamation.gif
A Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptAdd.pt
A Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptEdit.pt
A Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/zpt.gif
D Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/www/
-=-
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/DeferExpr.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/DeferExpr.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/DeferExpr.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,102 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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
-#
-##############################################################################
-"""Defer and Lazy expression handler
-
-defer expressions can be usesd for a design pattern called deferred evaluation.
-
-Example:
-
- <div tal:define="xis defer:string:x is $x">
- <p tal:repeat="x python:range(3)"
- tal:content="xis"></p>
- </div>
-
-Output:
-
- <div>
- <p>x is 0</p>
- <p>x is 1</p>
- <p>x is 2</p>
- </div>
-
-A lazy expressions is implemented in a similar way but has a different result. While
-a defer expression is evaluated every time it is used according to its context a lazy
-expression is evaluted only the first time it is used. Lazy expression are known
-under the name lazy initialization of variables, too.
-A common use case for a lazy expression is a lazy binding of a costly expression.
-While one could call an expression only when it's required it makes sense to define
-it only one time when it could be used multiple times.
-
-Example
-
- <div tal:define="lazyvar lazy:here/suckMyCPU">
- <div tal:condition="foo" tal:content="lazyvar" />
- <div tal:condition="bar" tal:content="lazyvar" />
- <div tal:condition"python: not (foo or bar)">...</div>
- </div>
-"""
-
-_marker = object()
-
-# defer expression
-
-class DeferWrapper:
- """Wrapper for defer: expression
- """
- def __init__(self, expr, econtext):
- self._expr = expr
- self._econtext = econtext
-
- def __str__(self):
- return str(self())
-
- def __call__(self):
- return self._expr(self._econtext)
-
-class DeferExpr:
- """defer: expression handler for deferred evaluation of the context
- """
- def __init__(self, name, expr, compiler):
- self._s = expr = expr.lstrip()
- self._c = compiler.compile(expr)
-
- def __call__(self, econtext):
- return DeferWrapper(self._c, econtext)
-
- def __repr__(self):
- return 'defer:%s' % `self._s`
-
-# lazy expression
-
-class LazyWrapper(DeferWrapper):
- """Wrapper for lazy: expression
- """
- def __init__(self, expr, econtext):
- DeferWrapper.__init__(self, expr, econtext)
- self._result = _marker
-
- def __call__(self):
- r = self._result
- if r is _marker:
- self._result = r = self._expr(self._econtext)
- return r
-
-class LazyExpr(DeferExpr):
- """lazy: expression handler for lazy initialization of expressions
- """
- def __call__(self, econtext):
- return LazyWrapper(self._c, econtext)
-
- def __repr__(self):
- return 'lazy:%s' % `self._s`
-
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/Expressions.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/Expressions.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/Expressions.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,330 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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
-#
-##############################################################################
-
-"""Page Template Expression Engine
-
-Page Template-specific implementation of TALES, with handlers
-for Python expressions, string literals, and paths.
-"""
-
-__version__='$Revision: 1.45 $'[11:-2]
-
-import re, sys
-from TALES import Engine
-from TALES import CompilerError
-from TALES import _valid_name
-from TALES import NAME_RE
-from TALES import Undefined
-from TALES import Default
-from TALES import _parse_expr
-from Acquisition import aq_base, aq_inner, aq_parent
-from DeferExpr import LazyWrapper
-from DeferExpr import LazyExpr
-from DeferExpr import DeferWrapper
-from DeferExpr import DeferExpr
-
-_engine = None
-def getEngine():
- global _engine
- if _engine is None:
- from PathIterator import Iterator
- _engine = Engine(Iterator)
- installHandlers(_engine)
- return _engine
-
-def installHandlers(engine):
- reg = engine.registerType
- pe = PathExpr
- for pt in ('standard', 'path', 'exists', 'nocall'):
- reg(pt, pe)
- reg('string', StringExpr)
- reg('python', PythonExpr)
- reg('not', NotExpr)
- reg('defer', DeferExpr)
- reg('lazy', LazyExpr)
-
-import AccessControl
-import AccessControl.cAccessControl
-acquisition_security_filter = AccessControl.cAccessControl.aq_validate
-from AccessControl import getSecurityManager
-from AccessControl.ZopeGuards import guarded_getattr
-from AccessControl import Unauthorized
-from ZRPythonExpr import PythonExpr
-from ZRPythonExpr import _SecureModuleImporter
-from ZRPythonExpr import call_with_ns
-
-SecureModuleImporter = _SecureModuleImporter()
-
-Undefs = (Undefined, AttributeError, KeyError,
- TypeError, IndexError, Unauthorized)
-
-def render(ob, ns):
- """
- Calls the object, possibly a document template, or just returns it if
- not callable. (From DT_Util.py)
- """
- if hasattr(ob, '__render_with_namespace__'):
- ob = call_with_ns(ob.__render_with_namespace__, ns)
- else:
- base = aq_base(ob)
- if callable(base):
- try:
- if getattr(base, 'isDocTemp', 0):
- ob = call_with_ns(ob, ns, 2)
- else:
- ob = ob()
- except AttributeError, n:
- if str(n) != '__call__':
- raise
- return ob
-
-class SubPathExpr:
- def __init__(self, path):
- self._path = path = path.strip().split('/')
- self._base = base = path.pop(0)
- if base and not _valid_name(base):
- raise CompilerError, 'Invalid variable name "%s"' % base
- # Parse path
- self._dp = dp = []
- for i in range(len(path)):
- e = path[i]
- if e[:1] == '?' and _valid_name(e[1:]):
- dp.append((i, e[1:]))
- dp.reverse()
-
- def _eval(self, econtext,
- list=list, isinstance=isinstance, StringType=type('')):
- vars = econtext.vars
- path = self._path
- if self._dp:
- path = list(path) # Copy!
- for i, varname in self._dp:
- val = vars[varname]
- if isinstance(val, StringType):
- path[i] = val
- else:
- # If the value isn't a string, assume it's a sequence
- # of path names.
- path[i:i+1] = list(val)
- __traceback_info__ = base = self._base
- if base == 'CONTEXTS' or not base:
- ob = econtext.contexts
- else:
- ob = vars[base]
- if isinstance(ob, DeferWrapper):
- ob = ob()
- if path:
- ob = restrictedTraverse(ob, path, getSecurityManager())
- return ob
-
-class PathExpr:
- def __init__(self, name, expr, engine):
- self._s = expr
- self._name = name
- self._hybrid = 0
- paths = expr.split('|')
- self._subexprs = []
- add = self._subexprs.append
- for i in range(len(paths)):
- path = paths[i].lstrip()
- if _parse_expr(path):
- # This part is the start of another expression type,
- # so glue it back together and compile it.
- add(engine.compile(('|'.join(paths[i:]).lstrip())))
- self._hybrid = 1
- break
- add(SubPathExpr(path)._eval)
-
- def _exists(self, econtext):
- for expr in self._subexprs:
- try:
- expr(econtext)
- except Undefs:
- pass
- else:
- return 1
- return 0
-
- def _eval(self, econtext,
- isinstance=isinstance,
- BasicTypes=(str, unicode, dict, list, tuple, bool),
- render=render):
- for expr in self._subexprs[:-1]:
- # Try all but the last subexpression, skipping undefined ones.
- try:
- ob = expr(econtext)
- except Undefs:
- pass
- else:
- break
- else:
- # On the last subexpression allow exceptions through, and
- # don't autocall if the expression was not a subpath.
- ob = self._subexprs[-1](econtext)
- if self._hybrid:
- return ob
-
- if self._name == 'nocall' or isinstance(ob, BasicTypes):
- return ob
- # Return the rendered object
- return render(ob, econtext.vars)
-
- def __call__(self, econtext):
- if self._name == 'exists':
- return self._exists(econtext)
- return self._eval(econtext)
-
- def __str__(self):
- return '%s expression %s' % (self._name, `self._s`)
-
- def __repr__(self):
- return '%s:%s' % (self._name, `self._s`)
-
-
-_interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/[^}]*)*)}' % {'n': NAME_RE})
-
-class StringExpr:
- def __init__(self, name, expr, engine):
- self._s = expr
- if '%' in expr:
- expr = expr.replace('%', '%%')
- self._vars = vars = []
- if '$' in expr:
- parts = []
- for exp in expr.split('$$'):
- if parts: parts.append('$')
- m = _interp.search(exp)
- while m is not None:
- parts.append(exp[:m.start()])
- parts.append('%s')
- vars.append(PathExpr('path', m.group(1) or m.group(2),
- engine))
- exp = exp[m.end():]
- m = _interp.search(exp)
- if '$' in exp:
- raise CompilerError, (
- '$ must be doubled or followed by a simple path')
- parts.append(exp)
- expr = ''.join(parts)
- self._expr = expr
-
- def __call__(self, econtext):
- vvals = []
- for var in self._vars:
- v = var(econtext)
- # I hope this isn't in use anymore.
- ## if isinstance(v, Exception):
- ## raise v
- vvals.append(v)
- return self._expr % tuple(vvals)
-
- def __str__(self):
- return 'string expression %s' % `self._s`
-
- def __repr__(self):
- return 'string:%s' % `self._s`
-
-class NotExpr:
- def __init__(self, name, expr, compiler):
- self._s = expr = expr.lstrip()
- self._c = compiler.compile(expr)
-
- def __call__(self, econtext):
- # We use the (not x) and 1 or 0 formulation to avoid changing
- # the representation of the result in Python 2.3, where the
- # result of "not" becomes an instance of bool.
- return (not econtext.evaluateBoolean(self._c)) and 1 or 0
-
- def __repr__(self):
- return 'not:%s' % `self._s`
-
-def restrictedTraverse(object, path, securityManager,
- get=getattr, has=hasattr, N=None, M=[],
- TupleType=type(()) ):
-
- REQUEST = {'path': path}
- REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy!
- path.reverse()
- validate = securityManager.validate
- __traceback_info__ = REQUEST
- while path:
- name = path.pop()
-
- if isinstance(name, TupleType):
- object = object(*name)
- continue
-
- if not name or name[0] == '_':
- # Skip directly to item access
- o = object[name]
- # Check access to the item.
- if not validate(object, object, None, o):
- raise Unauthorized, name
- object = o
- continue
-
- if name=='..':
- o = get(object, 'aq_parent', M)
- if o is not M:
- if not validate(object, object, name, o):
- raise Unauthorized, name
- object=o
- continue
-
- t=get(object, '__bobo_traverse__', N)
- if t is not N:
- o=t(REQUEST, name)
-
- container = None
- if aq_base(o) is not o:
- # The object is wrapped, so the acquisition
- # context determines the container.
- container = aq_parent(aq_inner(o))
- elif has(o, 'im_self'):
- container = o.im_self
- elif (has(aq_base(object), name) and get(object, name) == o):
- container = object
- if not validate(object, container, name, o):
- raise Unauthorized, name
- else:
- # Try an attribute.
- o = guarded_getattr(object, str(name), M) # failed on u'aq_parent'
- if o is M:
- # Try an item.
- try:
- # XXX maybe in Python 2.2 we can just check whether
- # the object has the attribute "__getitem__"
- # instead of blindly catching exceptions.
- o = object[name]
- except AttributeError, exc:
- if str(exc).find('__getitem__') >= 0:
- # The object does not support the item interface.
- # Try to re-raise the original attribute error.
- # XXX I think this only happens with
- # ExtensionClass instances.
- guarded_getattr(object, name)
- raise
- except TypeError, exc:
- if str(exc).find('unsubscriptable') >= 0:
- # The object does not support the item interface.
- # Try to re-raise the original attribute error.
- # XXX This is sooooo ugly.
- guarded_getattr(object, name)
- raise
- else:
- # Check access to the item.
- if not validate(object, object, None, o):
- raise Unauthorized, name
- object = o
-
- return object
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/GlobalTranslationService.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/GlobalTranslationService.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/GlobalTranslationService.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,50 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""Global Translation Service for providing I18n to Page Templates.
-
-$Id$
-"""
-
-import re
-import Products.Five.i18n
-
-from DocumentTemplate.DT_Util import ustr
-from TAL.TALDefs import NAME_RE
-
-class DummyTranslationService:
- """Translation service that doesn't know anything about translation."""
- def translate(self, domain, msgid, mapping=None,
- context=None, target_language=None, default=None):
- def repl(m, mapping=mapping):
- return ustr(mapping[m.group(m.lastindex)])
- cre = re.compile(r'\$(?:(%s)|\{(%s)\})' % (NAME_RE, NAME_RE))
- return cre.sub(repl, default or msgid)
- # XXX Not all of Zope2.I18n.ITranslationService is implemented.
-
-#
-# As of Five 1.1, we're by default using Zope 3 Message Catalogs for
-# translation, but we allow fallback translation services such as PTS
-# and Localizer
-#
-
-Products.Five.i18n._fallback_translation_service = DummyTranslationService()
-fiveTranslationService = Products.Five.i18n.FiveTranslationService()
-
-def getGlobalTranslationService():
- return fiveTranslationService
-
-def setGlobalTranslationService(newservice):
- oldservice, Products.Five.i18n._fallback_translation_service = \
- Products.Five.i18n._fallback_translation_service, newservice
- return oldservice
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/HISTORY.txt
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/HISTORY.txt 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/HISTORY.txt 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,114 +0,0 @@
-Page Template history
-
- This file contains change information for previous versions of
- PageTemplates. Change information for the current release can be found
- in the file CHANGES.txt.
-
- Version 1.4.1
-
- Bugs Fixed
-
- - Tracebacks were often truncated.
-
- - __bobo_traverse__ objects, such as the root, triggered
- security incorrectly when traversed.
-
- - If a PageTemplate was owned by a missing user, or one with
- insufficient permissions, the editing form broke.
-
- - PageTemplateFiles didn't bind 'user'.
-
- - There was no help.
-
- Version 1.4.0
-
- Features Added
-
- - ZPTs are now cache-enabled
-
- - Added property sheet to ZPT
-
- Bugs Fixed
-
- - Expressions with embedded newlines were broken
-
- - History comparison tried to expand macros
-
- - Iterator exceptions weren't converted
-
- - 'Unauthorized' exception couldn't be handled by on-error
-
- Version 1.3.3
-
- Features Added
-
- - Allow any false value in tal:repeat to act as an empty sequence.
- - manage_addPageTemplate accepts optional title and text
- arguments, and returns the new object if REQUEST is None.
-
- Bugs Fixed
-
- - The various *Python modules failed to import CompilerError.
- - Security machinery changes in Zope 2.4 broke ZRPythonExpr
-
- Version 1.3.2
-
- Features Added
-
- - Adopted Zope-style CHANGES.txt and HISTORY.txt
- - Improved execution performance
- - nocall: paths are back in.
-
- Bugs Fixed
-
- - TALES expressions let any string exception through, not just
- Redirect and Unauthorized.
-
- Version 1.3.1
-
- Features Added
-
- - Added error logging to PageTemplateFiles.
- - Refactored PythonExpr, and added support for Zope 2.4
-
- Version 1.3.0
-
- Features Added
-
- - New builtin variables 'default', 'user', and 'attrs'.
- - Removed path modifiers.
- - Added '|' operator for paths.
- - Tweaked parameters passed when calling DTML.
- - Expression types now have corresponding builtin functions in
- Python expressions.
-
- Version 1.2.1
-
- Bug Fixed
-
- - 'repeat' variable access was broken.
-
- Version 1.2.0
-
- Features Added
-
- - Depends on the new ZTUtils package, which adds batching and
- tree widget capabilities.
- - Path expressions now have optional path modifiers. These
- appear in parenthesis before the path, and include 'if',
- 'exists', and 'nocall'.
- - Changed nocall: and exists: expressions types into path modifiers.
- - The 'if' path modifier can cancel any TAL action.
-
- Version 1.1.0
-
- Features Added
- - Changed tests to match TAL's omitted attributes.
-
- Version 1.0.0
-
- - Various minor bugs fixed
-
- Version 1.0.0b1
-
- - All functionality described in the Project Wiki is implemented
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplate.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplate.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplate.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,227 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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
-#
-##############################################################################
-"""Page Template module
-
-HTML- and XML-based template objects using TAL, TALES, and METAL.
-"""
-
-__version__='$Revision: 1.31 $'[11:-2]
-
-import sys, types
-
-from TAL.TALParser import TALParser
-from TAL.HTMLTALParser import HTMLTALParser
-from TAL.TALGenerator import TALGenerator
-# Do not use cStringIO here! It's not unicode aware. :(
-from TAL.TALInterpreter import TALInterpreter, FasterStringIO
-from Expressions import getEngine
-from ExtensionClass import Base
-from ComputedAttribute import ComputedAttribute
-
-
-class PageTemplate(Base):
- "Page Templates using TAL, TALES, and METAL"
-
- content_type = 'text/html'
- expand = 0
- _v_errors = ()
- _v_warnings = ()
- _v_program = None
- _v_macros = None
- _v_cooked = 0
- id = '(unknown)'
- _text = ''
- _error_start = '<!-- Page Template Diagnostics'
-
- def StringIO(self):
- # Third-party products wishing to provide a full Unicode-aware
- # StringIO can do so by monkey-patching this method.
- return FasterStringIO()
-
- def macros(self):
- return self.pt_macros()
- macros = ComputedAttribute(macros, 1)
-
- def pt_edit(self, text, content_type):
- if content_type:
- self.content_type = str(content_type)
- if hasattr(text, 'read'):
- text = text.read()
- charset = getattr(self, 'management_page_charset', None)
- if charset and type(text) == types.StringType:
- try:
- unicode(text,'us-ascii')
- except UnicodeDecodeError:
- text = unicode(text, charset)
- self.write(text)
-
- def pt_getContext(self):
- c = {'template': self,
- 'options': {},
- 'nothing': None,
- 'request': None,
- 'modules': ModuleImporter,
- }
- parent = getattr(self, 'aq_parent', None)
- if parent is not None:
- c['here'] = parent
- c['context'] = parent
- c['container'] = self.aq_inner.aq_parent
- while parent is not None:
- self = parent
- parent = getattr(self, 'aq_parent', None)
- c['root'] = self
- return c
-
- def pt_render(self, source=0, extra_context={}):
- """Render this Page Template"""
- if not self._v_cooked:
- self._cook()
-
- __traceback_supplement__ = (PageTemplateTracebackSupplement, self)
-
- if self._v_errors:
- e = str(self._v_errors)
- raise PTRuntimeError, (
- 'Page Template %s has errors: %s' % (self.id, e))
- output = self.StringIO()
- c = self.pt_getContext()
- c.update(extra_context)
-
- TALInterpreter(self._v_program, self._v_macros,
- getEngine().getContext(c),
- output,
- tal=not source, strictinsert=0)()
- return output.getvalue()
-
- def __call__(self, *args, **kwargs):
- if not kwargs.has_key('args'):
- kwargs['args'] = args
- return self.pt_render(extra_context={'options': kwargs})
-
- def pt_errors(self):
- if not self._v_cooked:
- self._cook()
- err = self._v_errors
- if err:
- return err
- if not self.expand: return
- try:
- self.pt_render(source=1)
- except:
- return ('Macro expansion failed', '%s: %s' % sys.exc_info()[:2])
-
- def pt_warnings(self):
- if not self._v_cooked:
- self._cook()
- return self._v_warnings
-
- def pt_macros(self):
- if not self._v_cooked:
- self._cook()
- if self._v_errors:
- __traceback_supplement__ = (PageTemplateTracebackSupplement, self)
- raise PTRuntimeError, (
- 'Page Template %s has errors: %s' % (
- self.id,
- self._v_errors
- ))
- return self._v_macros
-
- def pt_source_file(self):
- return None # Unknown.
-
- def write(self, text):
- assert type(text) in types.StringTypes
- if text[:len(self._error_start)] == self._error_start:
- errend = text.find('-->')
- if errend >= 0:
- text = text[errend + 4:]
- if self._text != text:
- self._text = text
- self._cook()
-
- def read(self):
- self._cook_check()
- if not self._v_errors:
- if not self.expand:
- return self._text
- try:
- return self.pt_render(source=1)
- except:
- return ('%s\n Macro expansion failed\n %s\n-->\n%s' %
- (self._error_start, "%s: %s" % sys.exc_info()[:2],
- self._text) )
-
- return ('%s\n %s\n-->\n%s' % (self._error_start,
- '\n '.join(self._v_errors),
- self._text))
-
- def _cook_check(self):
- if not self._v_cooked:
- self._cook()
-
- def _cook(self):
- """Compile the TAL and METAL statments.
-
- Cooking must not fail due to compilation errors in templates.
- """
- source_file = self.pt_source_file()
- if self.html():
- gen = TALGenerator(getEngine(), xml=0, source_file=source_file)
- parser = HTMLTALParser(gen)
- else:
- gen = TALGenerator(getEngine(), source_file=source_file)
- parser = TALParser(gen)
-
- self._v_errors = ()
- try:
- parser.parseString(self._text)
- self._v_program, self._v_macros = parser.getCode()
- except:
- self._v_errors = ["Compilation failed",
- "%s: %s" % sys.exc_info()[:2]]
- self._v_warnings = parser.getWarnings()
- self._v_cooked = 1
-
- def html(self):
- if not hasattr(getattr(self, 'aq_base', self), 'is_html'):
- return self.content_type == 'text/html'
- return self.is_html
-
-class _ModuleImporter:
- def __getitem__(self, module):
- mod = __import__(module)
- path = module.split('.')
- for name in path[1:]:
- mod = getattr(mod, name)
- return mod
-
-ModuleImporter = _ModuleImporter()
-
-class PTRuntimeError(RuntimeError):
- '''The Page Template has template errors that prevent it from rendering.'''
- pass
-
-
-class PageTemplateTracebackSupplement:
- #__implements__ = ITracebackSupplement
-
- def __init__(self, pt):
- self.object = pt
- w = pt.pt_warnings()
- e = pt.pt_errors()
- if e:
- w = list(w) + list(e)
- self.warnings = w
-
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplateFile.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplateFile.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/PageTemplateFile.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,204 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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
-#
-##############################################################################
-"""Filesystem Page Template module
-
-Zope object encapsulating a Page Template from the filesystem.
-"""
-
-__version__ = '$Revision: 1.30 $'[11:-2]
-
-import os, AccessControl
-from Globals import package_home, DevelopmentMode
-from zLOG import LOG, ERROR
-from Shared.DC.Scripts.Script import Script
-from Shared.DC.Scripts.Signature import FuncCode
-from AccessControl import getSecurityManager
-from OFS.Traversable import Traversable
-from PageTemplate import PageTemplate
-from Expressions import SecureModuleImporter
-from ComputedAttribute import ComputedAttribute
-from Acquisition import aq_parent, aq_inner
-from App.config import getConfiguration
-from OFS.SimpleItem import Item_w__name__
-
-class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable):
- "Zope wrapper for filesystem Page Template using TAL, TALES, and METAL"
-
- meta_type = 'Page Template (File)'
-
- func_defaults = None
- func_code = FuncCode((), 0)
- _v_last_read = 0
-
- # needed by App.class_init.default__class_init__, often imported
- # using the alias Globals.InitializeClass
- _need__name__ = 1
-
- _default_bindings = {'name_subpath': 'traverse_subpath'}
-
- security = AccessControl.ClassSecurityInfo()
- security.declareProtected('View management screens',
- 'read', 'document_src')
-
- def __init__(self, filename, _prefix=None, **kw):
- self.ZBindings_edit(self._default_bindings)
- if _prefix is None:
- _prefix = getConfiguration().softwarehome
- elif not isinstance(_prefix, str):
- _prefix = package_home(_prefix)
- name = kw.get('__name__')
- basepath, ext = os.path.splitext(filename)
- if name:
- self._need__name__ = 0
- self.__name__ = name
- else:
- self.__name__ = os.path.basename(basepath)
- if not ext:
- # XXX This is pretty bogus, but can't be removed since
- # it's been released this way.
- filename = filename + '.zpt'
- self.filename = os.path.join(_prefix, filename)
-
- def getId(self):
- """return the ID of this object"""
- return self.__name__
-
- def pt_getContext(self):
- root = self.getPhysicalRoot()
- context = self._getContext()
- c = {'template': self,
- 'here': context,
- 'context': context,
- 'container': self._getContainer(),
- 'nothing': None,
- 'options': {},
- 'root': root,
- 'request': getattr(root, 'REQUEST', None),
- 'modules': SecureModuleImporter,
- }
- return c
-
- def _exec(self, bound_names, args, kw):
- """Call a Page Template"""
- self._cook_check()
- if not kw.has_key('args'):
- kw['args'] = args
- bound_names['options'] = kw
-
- try:
- response = self.REQUEST.RESPONSE
- if not response.headers.has_key('content-type'):
- response.setHeader('content-type', self.content_type)
- except AttributeError:
- pass
-
- # Execute the template in a new security context.
- security = getSecurityManager()
- bound_names['user'] = security.getUser()
- security.addContext(self)
- try:
- return self.pt_render(extra_context=bound_names)
- finally:
- security.removeContext(self)
-
- def pt_macros(self):
- self._cook_check()
- return PageTemplate.pt_macros(self)
-
- def pt_source_file(self):
- """Returns a file name to be compiled into the TAL code."""
- return self.__name__ # Don't reveal filesystem paths
-
- def _cook_check(self):
- if self._v_last_read and not DevelopmentMode:
- return
- __traceback_info__ = self.filename
- try:
- mtime = os.path.getmtime(self.filename)
- except OSError:
- mtime = 0
- if self._v_program is not None and mtime == self._v_last_read:
- return
- f = open(self.filename, "rb")
- try:
- text = f.read(XML_PREFIX_MAX_LENGTH)
- except:
- f.close()
- raise
- t = sniff_type(text)
- if t != "text/xml":
- # For HTML, we really want the file read in text mode:
- f.close()
- f = open(self.filename)
- text = ''
- text += f.read()
- f.close()
- self.pt_edit(text, t)
- self._cook()
- if self._v_errors:
- LOG('PageTemplateFile', ERROR, 'Error in template',
- '\n'.join(self._v_errors))
- return
- self._v_last_read = mtime
-
- def document_src(self, REQUEST=None, RESPONSE=None):
- """Return expanded document source."""
-
- if RESPONSE is not None:
- # Since _cook_check() can cause self.content_type to change,
- # we have to make sure we call it before setting the
- # Content-Type header.
- self._cook_check()
- RESPONSE.setHeader('Content-Type', 'text/plain')
- return self.read()
-
- def _get__roles__(self):
- imp = getattr(aq_parent(aq_inner(self)),
- '%s__roles__' % self.__name__)
- if hasattr(imp, '__of__'):
- return imp.__of__(self)
- return imp
-
- __roles__ = ComputedAttribute(_get__roles__, 1)
-
- def getOwner(self, info=0):
- """Gets the owner of the executable object.
-
- This method is required of all objects that go into
- the security context stack. Since this object came from the
- filesystem, it is owned by no one managed by Zope.
- """
- return None
-
- def __getstate__(self):
- from ZODB.POSException import StorageError
- raise StorageError, ("Instance of AntiPersistent class %s "
- "cannot be stored." % self.__class__.__name__)
-
-
-XML_PREFIXES = [
- "<?xml", # ascii, utf-8
- "\xef\xbb\xbf<?xml", # utf-8 w/ byte order mark
- "\0<\0?\0x\0m\0l", # utf-16 big endian
- "<\0?\0x\0m\0l\0", # utf-16 little endian
- "\xfe\xff\0<\0?\0x\0m\0l", # utf-16 big endian w/ byte order mark
- "\xff\xfe<\0?\0x\0m\0l\0", # utf-16 little endian w/ byte order mark
- ]
-
-XML_PREFIX_MAX_LENGTH = max(map(len, XML_PREFIXES))
-
-def sniff_type(text):
- for prefix in XML_PREFIXES:
- if text.startswith(prefix):
- return "text/xml"
- return None
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/README.txt
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/README.txt 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/README.txt 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,7 +0,0 @@
-See <a href="http://dev.zope.org/Wikis/DevSite/Projects/ZPT">the
-ZPT project Wiki</a> for more information about Page Templates, or
-<a href="http://www.zope.org/Members/4am/ZPT">the download page</a>
-for installation instructions and the most recent version of the software.
-
-This Product requires the TAL and ZTUtils packages to be installed in
-your Python path (not Products). See the links above for more information.
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/TALES.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/TALES.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/TALES.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,297 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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
-#
-##############################################################################
-"""TALES
-
-An implementation of a generic TALES engine
-"""
-
-__version__='$Revision: 1.39 $'[11:-2]
-
-import re, sys, ZTUtils
-from weakref import ref
-from MultiMapping import MultiMapping
-from DocumentTemplate.DT_Util import ustr
-from GlobalTranslationService import getGlobalTranslationService
-from zExceptions import Unauthorized
-
-StringType = type('')
-
-NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
-_parse_expr = re.compile(r"(%s):" % NAME_RE).match
-_valid_name = re.compile('%s$' % NAME_RE).match
-
-class TALESError(Exception):
- """Error during TALES expression evaluation"""
-
-class Undefined(TALESError):
- '''Exception raised on traversal of an undefined path'''
-
-class RegistrationError(Exception):
- '''TALES Type Registration Error'''
-
-class CompilerError(Exception):
- '''TALES Compiler Error'''
-
-class Default:
- '''Retain Default'''
-Default = Default()
-
-class SafeMapping(MultiMapping):
- '''Mapping with security declarations and limited method exposure.
-
- Since it subclasses MultiMapping, this class can be used to wrap
- one or more mapping objects. Restricted Python code will not be
- able to mutate the SafeMapping or the wrapped mappings, but will be
- able to read any value.
- '''
- __allow_access_to_unprotected_subobjects__ = 1
- push = pop = None
-
- _push = MultiMapping.push
- _pop = MultiMapping.pop
-
-
-class Iterator(ZTUtils.Iterator):
- def __init__(self, name, seq, context):
- ZTUtils.Iterator.__init__(self, seq)
- self.name = name
- self._context_ref = ref(context)
-
- def next(self):
- if ZTUtils.Iterator.next(self):
- context = self._context_ref()
- if context is not None:
- context.setLocal(self.name, self.item)
- return 1
- return 0
-
-
-class ErrorInfo:
- """Information about an exception passed to an on-error handler."""
- __allow_access_to_unprotected_subobjects__ = 1
-
- def __init__(self, err, position=(None, None)):
- if isinstance(err, Exception):
- self.type = err.__class__
- self.value = err
- else:
- self.type = err
- self.value = None
- self.lineno = position[0]
- self.offset = position[1]
-
-
-class Engine:
- '''Expression Engine
-
- An instance of this class keeps a mutable collection of expression
- type handlers. It can compile expression strings by delegating to
- these handlers. It can provide an expression Context, which is
- capable of holding state and evaluating compiled expressions.
- '''
- Iterator = Iterator
-
- def __init__(self, Iterator=None):
- self.types = {}
- if Iterator is not None:
- self.Iterator = Iterator
-
- def registerType(self, name, handler):
- if not _valid_name(name):
- raise RegistrationError, 'Invalid Expression type "%s".' % name
- types = self.types
- if types.has_key(name):
- raise RegistrationError, (
- 'Multiple registrations for Expression type "%s".' %
- name)
- types[name] = handler
-
- def getTypes(self):
- return self.types
-
- def compile(self, expression):
- m = _parse_expr(expression)
- if m:
- type = m.group(1)
- expr = expression[m.end():]
- else:
- type = "standard"
- expr = expression
- try:
- handler = self.types[type]
- except KeyError:
- raise CompilerError, (
- 'Unrecognized expression type "%s".' % type)
- return handler(type, expr, self)
-
- def getContext(self, contexts=None, **kwcontexts):
- if contexts is not None:
- if kwcontexts:
- kwcontexts.update(contexts)
- else:
- kwcontexts = contexts
- return Context(self, kwcontexts)
-
- def getCompilerError(self):
- return CompilerError
-
-class Context:
- '''Expression Context
-
- An instance of this class holds context information that it can
- use to evaluate compiled expressions.
- '''
-
- _context_class = SafeMapping
- position = (None, None)
- source_file = None
-
- def __init__(self, compiler, contexts):
- self._compiler = compiler
- self.contexts = contexts
- contexts['nothing'] = None
- contexts['default'] = Default
-
- self.repeat_vars = rv = {}
- # Wrap this, as it is visible to restricted code
- contexts['repeat'] = rep = self._context_class(rv)
- contexts['loop'] = rep # alias
-
- self.global_vars = gv = contexts.copy()
- self.local_vars = lv = {}
- self.vars = self._context_class(gv, lv)
-
- # Keep track of what needs to be popped as each scope ends.
- self._scope_stack = []
-
- def getCompiler(self):
- return self._compiler
-
- def beginScope(self):
- self._scope_stack.append([self.local_vars.copy()])
-
- def endScope(self):
- scope = self._scope_stack.pop()
- self.local_vars = lv = scope[0]
- v = self.vars
- v._pop()
- v._push(lv)
- # Pop repeat variables, if any
- i = len(scope) - 1
- while i:
- name, value = scope[i]
- if value is None:
- del self.repeat_vars[name]
- else:
- self.repeat_vars[name] = value
- i = i - 1
-
- def setLocal(self, name, value):
- self.local_vars[name] = value
-
- def setGlobal(self, name, value):
- self.global_vars[name] = value
-
- def setRepeat(self, name, expr):
- expr = self.evaluate(expr)
- if not expr:
- return self._compiler.Iterator(name, (), self)
- it = self._compiler.Iterator(name, expr, self)
- old_value = self.repeat_vars.get(name)
- self._scope_stack[-1].append((name, old_value))
- self.repeat_vars[name] = it
- return it
-
- def evaluate(self, expression,
- isinstance=isinstance, StringType=StringType):
- if isinstance(expression, StringType):
- expression = self._compiler.compile(expression)
- __traceback_supplement__ = (
- TALESTracebackSupplement, self, expression)
- return expression(self)
-
- evaluateValue = evaluate
- evaluateBoolean = evaluate
-
- def evaluateText(self, expr):
- text = self.evaluate(expr)
- if text is Default or text is None:
- return text
- return ustr(text)
-
- def evaluateStructure(self, expr):
- return self.evaluate(expr)
- evaluateStructure = evaluate
-
- def evaluateMacro(self, expr):
- # XXX Should return None or a macro definition
- return self.evaluate(expr)
- evaluateMacro = evaluate
-
- def createErrorInfo(self, err, position):
- return ErrorInfo(err, position)
-
- def getDefault(self):
- return Default
-
- def setSourceFile(self, source_file):
- self.source_file = source_file
-
- def setPosition(self, position):
- self.position = position
-
- def translate(self, domain, msgid, mapping=None,
- context=None, target_language=None, default=None):
- if context is None:
- context = self.contexts.get('here')
- return getGlobalTranslationService().translate(
- domain, msgid, mapping=mapping,
- context=context,
- default=default,
- target_language=target_language)
-
-class TALESTracebackSupplement:
- """Implementation of ITracebackSupplement"""
- def __init__(self, context, expression):
- self.context = context
- self.source_url = context.source_file
- self.line = context.position[0]
- self.column = context.position[1]
- self.expression = repr(expression)
-
- def getInfo(self, as_html=0):
- import pprint
- from cgi import escape
- data = self.context.contexts.copy()
- try:
- s = pprint.pformat(data)
- except Unauthorized, e:
- s = ' - %s: %s' % (getattr(e, '__class__', type(e)), e)
- if as_html:
- s = escape(s)
- return s
- if not as_html:
- return ' - Names:\n %s' % s.replace('\n', '\n ')
- else:
- return '<b>Names:</b><pre>%s</pre>' % (escape(s))
-
-
-class SimpleExpr:
- '''Simple example of an expression type handler'''
- def __init__(self, name, expr, engine):
- self._name = name
- self._expr = expr
- def __call__(self, econtext):
- return self._name, self._expr
- def __repr__(self):
- return '<SimpleExpr %s %s>' % (self._name, `self._expr`)
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZPythonExpr.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZPythonExpr.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZPythonExpr.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,66 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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
-#
-##############################################################################
-
-"""Old Zope-specific Python Expression Handler
-
-Handler for Python expressions, using the pre-Python 2.1 restriction
-machinery from PythonScripts.
-"""
-
-__version__='$Revision: 1.8 $'[11:-2]
-
-from AccessControl import getSecurityManager
-from Products.PythonScripts.Guarded import _marker, \
- GuardedBlock, theGuard, safebin, WriteGuard, ReadGuard, UntupleFunction
-from TALES import CompilerError
-
-from PythonExpr import PythonExpr
-
-class PythonExpr(PythonExpr):
- def __init__(self, name, expr, engine):
- self.expr = expr = expr.strip().replace('\n', ' ')
- blk = GuardedBlock('def f():\n return \\\n %s\n' % expr)
- if blk.errors:
- raise CompilerError, ('Python expression error:\n%s' %
- '\n'.join(blk.errors) )
- guards = {'$guard': theGuard, '$write_guard': WriteGuard,
- '$read_guard': ReadGuard, '__debug__': __debug__}
- self._f = UntupleFunction(blk.t, guards, __builtins__=safebin)
- self._get_used_names()
-
-class _SecureModuleImporter:
- __allow_access_to_unprotected_subobjects__ = 1
- def __getitem__(self, module):
- mod = safebin['__import__'](module)
- path = module.split('.')
- for name in path[1:]:
- mod = getattr(mod, name)
- return mod
-
-from DocumentTemplate.DT_Util import TemplateDict, InstanceDict
-def validate(accessed, container, name, value, dummy):
- return getSecurityManager().validate(accessed, container, name, value)
-def call_with_ns(f, ns, arg=1):
- td = TemplateDict()
- td.validate = validate
- td.this = ns['here']
- td._push(ns['request'])
- td._push(InstanceDict(td.this, td))
- td._push(ns)
- try:
- if arg==2:
- return f(None, td)
- else:
- return f(td)
- finally:
- td._pop(3)
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZRPythonExpr.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZRPythonExpr.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZRPythonExpr.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -1,78 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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
-#
-##############################################################################
-
-"""Zope-specific Python Expression Handler
-
-Handler for Python expressions that uses the RestrictedPython package.
-"""
-
-__version__='$Revision: 1.11 $'[11:-2]
-
-from AccessControl import safe_builtins
-from AccessControl.ZopeGuards import guarded_getattr, get_safe_globals
-from RestrictedPython import compile_restricted_eval
-from TALES import CompilerError
-
-from PythonExpr import PythonExpr
-
-class PythonExpr(PythonExpr):
- _globals = get_safe_globals()
- _globals['_getattr_'] = guarded_getattr
- _globals['__debug__' ] = __debug__
-
- def __init__(self, name, expr, engine):
- self.expr = expr = expr.strip().replace('\n', ' ')
- code, err, warn, use = compile_restricted_eval(expr, str(self))
- if err:
- raise CompilerError, ('Python expression error:\n%s' %
- '\n'.join(err) )
- self._f_varnames = use.keys()
- self._code = code
-
- def __call__(self, econtext):
- __traceback_info__ = self.expr
- code = self._code
- g = self._bind_used_names(econtext)
- g.update(self._globals)
- return eval(code, g, {})
-
-class _SecureModuleImporter:
- __allow_access_to_unprotected_subobjects__ = 1
- def __getitem__(self, module):
- mod = safe_builtins['__import__'](module)
- path = module.split('.')
- for name in path[1:]:
- mod = getattr(mod, name)
- return mod
-
-from DocumentTemplate.DT_Util import TemplateDict, InstanceDict
-from AccessControl.DTML import RestrictedDTML
-class Rtd(RestrictedDTML, TemplateDict):
- this = None
-
-def call_with_ns(f, ns, arg=1):
- td = Rtd()
- # prefer 'context' to 'here'; fall back to 'None'
- this = ns.get('context', ns.get('here'))
- td.this = this
- request = ns.get('request', {})
- td._push(request)
- td._push(InstanceDict(td.this, td))
- td._push(ns)
- try:
- if arg==2:
- return f(None, td)
- else:
- return f(td)
- finally:
- td._pop(3)
Modified: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZopePageTemplate.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZopePageTemplate.py 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/ZopePageTemplate.py 2005-12-11 12:53:04 UTC (rev 40699)
@@ -10,48 +10,52 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
-"""Zope Page Template module
-Zope object encapsulating a Page Template.
-"""
+""" Zope Page Template module (wrapper for the Zope 3 ZPT implementation) """
__version__='$Revision: 1.48 $'[11:-2]
-import os, AccessControl, Acquisition, sys, types
-from types import StringType
-from Globals import DTMLFile, ImageFile, MessageDialog, package_home
-from zLOG import LOG, ERROR, INFO
+import re
+import os
+import Acquisition
+from Globals import ImageFile, package_home, InitializeClass
from OFS.SimpleItem import SimpleItem
+from OFS.content_types import guess_content_type
from DateTime.DateTime import DateTime
-from Shared.DC.Scripts.Script import Script, BindingsUI
+from Shared.DC.Scripts.Script import Script
from Shared.DC.Scripts.Signature import FuncCode
-from AccessControl import getSecurityManager
-try:
- from AccessControl import Unauthorized
-except ImportError:
- Unauthorized = "Unauthorized"
+
from OFS.History import Historical, html_diff
from OFS.Cache import Cacheable
from OFS.Traversable import Traversable
from OFS.PropertyManager import PropertyManager
-from PageTemplate import PageTemplate
-from Expressions import SecureModuleImporter
-from PageTemplateFile import PageTemplateFile
-try:
- from webdav.Lockable import ResourceLockedError
- from webdav.WriteLockInterface import WriteLockInterface
- SUPPORTS_WEBDAV_LOCKS = 1
-except ImportError:
- SUPPORTS_WEBDAV_LOCKS = 0
+from AccessControl import getSecurityManager, safe_builtins, ClassSecurityInfo
+from AccessControl.Permissions import view, ftp_access, change_page_templates, view_management_screens
+from webdav.Lockable import ResourceLockedError
+from webdav.WriteLockInterface import WriteLockInterface
+from zope.pagetemplate.pagetemplate import PageTemplate
+# regular expression to extract the encoding from the XML preamble
+encoding_reg= re.compile('<\?xml.*?encoding="(.*?)".*?\?>', re.M)
+
+class SecureModuleImporter:
+ __allow_access_to_unprotected_subobjects__ = 1
+ def __getitem__(self, module):
+ mod = safe_builtins['__import__'](module)
+ path = module.split('.')
+ for name in path[1:]:
+ mod = getattr(mod, name)
+ return mod
+
+
class Src(Acquisition.Explicit):
- " "
+ """ I am scary code """
+ index_html = None
PUT = document_src = Acquisition.Acquired
- index_html = None
def __before_publishing_traverse__(self, ob, request):
if getattr(request, '_hacked_path', 0):
@@ -62,12 +66,24 @@
return self.document_src(REQUEST)
+def sniffEncoding(text, default_encoding='utf-8'):
+ """ try to determine the encoding from html or xml """
+
+ # XXX: look at pagetemplates.py (BOM!!!)
+ if text.startswith('<?xml'):
+ mo = encoding_reg.search(text)
+ if mo:
+ return mo.group(1)
+ return default_encoding
+
+_default_content_fn = os.path.join(package_home(globals()), 'pt', 'default.html')
+
+
class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
Traversable, PropertyManager):
- "Zope wrapper for Page Template using TAL, TALES, and METAL"
+ """ Z2 wrapper class for Zope 3 page templates """
- if SUPPORTS_WEBDAV_LOCKS:
- __implements__ = (WriteLockInterface,)
+ __implements__ = (WriteLockInterface,)
meta_type = 'Page Template'
@@ -75,8 +91,6 @@
func_code = FuncCode((), 0)
_default_bindings = {'name_subpath': 'traverse_subpath'}
- _default_content_fn = os.path.join(package_home(globals()),
- 'www', 'default.html')
manage_options = (
{'label':'Edit', 'action':'pt_editForm',
@@ -87,52 +101,52 @@
+ SimpleItem.manage_options \
+ Cacheable.manage_options
- _properties=({'id':'title', 'type': 'string', 'mode': 'wd'},
+
+ _properties=({'id':'title', 'type': 'ustring', 'mode': 'w'},
{'id':'content_type', 'type':'string', 'mode': 'w'},
{'id':'expand', 'type':'boolean', 'mode': 'w'},
)
- def __init__(self, id, text=None, content_type=None):
- self.id = str(id)
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(view)
+ security.declareProtected(view, '__call__')
+
+ def __init__(self, id, text=None, content_type=None, encoding='utf-8'):
+ self.id = id
+ self.expand = 0
self.ZBindings_edit(self._default_bindings)
- if text is None:
- text = open(self._default_content_fn).read()
- self.pt_edit(text, content_type)
+ self.pt_edit(text, content_type, encoding)
- def _setPropValue(self, id, value):
- PropertyManager._setPropValue(self, id, value)
- self.ZCacheable_invalidate()
+ security.declareProtected(change_page_templates, 'pt_encoding')
+ def pt_encoding(self):
+ encoding = sniffEncoding(self.read())
+ return encoding
- security = AccessControl.ClassSecurityInfo()
+ # Use the encoding of the document as encoding for the ZMI to
+ # avoid any kind of encoding troubles
+ from ComputedAttribute import ComputedAttribute
+ management_page_charset = ComputedAttribute(pt_encoding, 1)
- security.declareObjectProtected('View')
- security.declareProtected('View', '__call__')
+ security.declareProtected(change_page_templates, 'pt_edit')
+ def pt_edit(self, text, content_type, encoding='utf-8'):
- security.declareProtected('View management screens',
- 'pt_editForm', 'manage_main', 'read',
- 'ZScriptHTML_tryForm', 'PrincipiaSearchSource',
- 'document_src', 'source_dot_xml')
+ text = text.strip()
+ if not isinstance(text, unicode):
+ text = unicode(text, encoding)
+ self.ZCacheable_invalidate()
+ PageTemplate.pt_edit(self, text, content_type)
- security.declareProtected('FTP access',
- 'manage_FTPstat','manage_FTPget','manage_FTPlist')
+ security.declareProtected(change_page_templates, 'pt_editAction')
+ def pt_editAction(self, REQUEST, title, text, content_type, encoding, expand):
+ """Change the title and document."""
- pt_editForm = PageTemplateFile('www/ptEdit', globals(),
- __name__='pt_editForm')
- pt_editForm._owner = None
- manage = manage_main = pt_editForm
+ if self.wl_isLocked():
+ raise ResourceLockedError("File is locked via WebDAV")
- source_dot_xml = Src()
+ self.expand = expand
+ self.pt_setTitle(title, encoding)
- security.declareProtected('Change Page Templates',
- 'pt_editAction', 'pt_setTitle', 'pt_edit',
- 'pt_upload', 'pt_changePrefs')
- def pt_editAction(self, REQUEST, title, text, content_type, expand):
- """Change the title and document."""
- if SUPPORTS_WEBDAV_LOCKS and self.wl_isLocked():
- raise ResourceLockedError, "File is locked via WebDAV"
- self.expand=expand
- self.pt_setTitle(title)
- self.pt_edit(text, content_type)
+ self.pt_edit(text, content_type, encoding)
REQUEST.set('text', self.read()) # May not equal 'text'!
REQUEST.set('title', self.title)
message = "Saved changes."
@@ -141,36 +155,45 @@
% '<br>'.join(self._v_warnings))
return self.pt_editForm(manage_tabs_message=message)
- def pt_setTitle(self, title):
- charset = getattr(self, 'management_page_charset', None)
- if type(title) == types.StringType and charset:
- try:
- title.decode('us-ascii')
- title = str(title)
- except UnicodeError:
- title = unicode(title, charset)
- elif type(title) != types.UnicodeType:
- title = str(title)
+
+ security.declareProtected(change_page_templates, 'pt_setTitle')
+ def pt_setTitle(self, title, encoding='utf-8'):
+ if not isinstance(title, unicode):
+ title = unicode(title, encoding)
self._setPropValue('title', title)
- def pt_upload(self, REQUEST, file='', charset=None):
+
+ def _setPropValue(self, id, value):
+ """ set a property and invalidate the cache """
+ PropertyManager._setPropValue(self, id, value)
+ self.ZCacheable_invalidate()
+
+
+ security.declareProtected(change_page_templates, 'pt_upload')
+ def pt_upload(self, REQUEST, file='', encoding='utf-8'):
"""Replace the document with the text in file."""
- if SUPPORTS_WEBDAV_LOCKS and self.wl_isLocked():
- raise ResourceLockedError, "File is locked via WebDAV"
- if type(file) is not StringType:
- if not file: raise ValueError, 'File not specified'
- file = file.read()
- if charset:
- try:
- unicode(file, 'us-ascii')
- file = str(file)
- except UnicodeDecodeError:
- file = unicode(file, charset)
- self.write(file)
- message = 'Saved changes.'
- return self.pt_editForm(manage_tabs_message=message)
+ if self.wl_isLocked():
+ raise ResourceLockedError("File is locked via WebDAV")
+ if isinstance(file, str):
+ filename = None
+ text = file
+ else:
+ if not file:
+ raise ValueError('File not specified')
+ filename = file.filename
+ text = file.read()
+
+ content_type, dummy = guess_content_type(filename, text)
+ if not content_type in ('text/html', 'text/xml'):
+ raise ValueError('Unsupported mimetype: %s' % content_type)
+
+ encoding = sniffEncoding(text, encoding)
+ self.pt_edit(text, content_type, encoding)
+ return self.pt_editForm(manage_tabs_message='Saved changes')
+
+ security.declareProtected(change_page_templates, 'pt_changePrefs')
def pt_changePrefs(self, REQUEST, height=None, width=None,
dtpref_cols="100%", dtpref_rows="20"):
"""Change editing preferences."""
@@ -197,14 +220,14 @@
"""Parameters to test the script with."""
return []
- def manage_historyCompare(self, rev1, rev2, REQUEST,
- historyComparisonResults=''):
- return ZopePageTemplate.inheritedAttribute(
- 'manage_historyCompare')(
- self, rev1, rev2, REQUEST,
- historyComparisonResults=html_diff(rev1._text, rev2._text) )
+# def manage_historyCompare(self, rev1, rev2, REQUEST,
+# historyComparisonResults=''):
+# return ZopePageTemplate.inheritedAttribute(
+# 'manage_historyCompare')(
+# self, rev1, rev2, REQUEST,
+# historyComparisonResults=html_diff(rev1._text, rev2._text) )
- def pt_getContext(self):
+ def pt_getContext(self, *args, **kw):
root = self.getPhysicalRoot()
context = self._getContext()
c = {'template': self,
@@ -215,13 +238,12 @@
'options': {},
'root': root,
'request': getattr(root, 'REQUEST', None),
- 'modules': SecureModuleImporter,
+ 'modules': SecureModuleImporter(),
}
return c
- def write(self, text):
- self.ZCacheable_invalidate()
- ZopePageTemplate.inheritedAttribute('write')(self, text)
+ security.declareProtected(view_management_screens, 'manage_main', 'read',
+ 'ZScriptHTML_tryForm')
def _exec(self, bound_names, args, kw):
"""Call a Page Template"""
@@ -236,7 +258,7 @@
except AttributeError:
pass
- security=getSecurityManager()
+ security = getSecurityManager()
bound_names['user'] = security.getUser()
# Retrieve the value from the cache.
@@ -252,8 +274,12 @@
# Execute the template in a new security context.
security.addContext(self)
+
try:
- result = self.pt_render(extra_context=bound_names)
+ # XXX: check the parameters for pt_render()! (aj)
+ result = self.pt_render(self.pt_getContext())
+
+# result = self.pt_render(extra_context=bound_names)
if keyset is not None:
# Store the result in the cache.
self.ZCacheable_set(result, keywords=keyset)
@@ -261,38 +287,54 @@
finally:
security.removeContext(self)
- security.declareProtected('Change Page Templates',
- 'PUT', 'manage_FTPput', 'write',
+ security.declareProtected(change_page_templates,
'manage_historyCopy',
'manage_beforeHistoryCopy', 'manage_afterHistoryCopy')
+ security.declareProtected(change_page_templates, 'PUT')
def PUT(self, REQUEST, RESPONSE):
""" Handle HTTP PUT requests """
self.dav__init(REQUEST, RESPONSE)
- if SUPPORTS_WEBDAV_LOCKS:
- self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
- self.write(REQUEST.get('BODY', ''))
+ self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
+ ## XXX:this should be unicode or we must pass an encoding
+ self.pt_edit(REQUEST.get('BODY', ''))
RESPONSE.setStatus(204)
return RESPONSE
+ security.declareProtected(change_page_templates, 'manage_FTPput')
manage_FTPput = PUT
+ security.declareProtected(ftp_access, 'manage_FTPstat','manage_FTPlist')
+
+ security.declareProtected(ftp_access, 'manage_FTPget')
def manage_FTPget(self):
"Get source for FTP download"
self.REQUEST.RESPONSE.setHeader('Content-Type', self.content_type)
return self.read()
+ security.declareProtected(view_management_screens, 'html')
+ def html(self):
+ return self.content_type == 'text/html'
+
+ security.declareProtected(view_management_screens, 'get_size')
def get_size(self):
return len(self.read())
+
+ security.declareProtected(view_management_screens, 'getSize')
getSize = get_size
+ security.declareProtected(view_management_screens, 'PrincipiaSearchSource')
def PrincipiaSearchSource(self):
"Support for searching - the document's contents are searched."
return self.read()
+ security.declareProtected(view_management_screens, 'document_src')
def document_src(self, REQUEST=None, RESPONSE=None):
"""Return expanded document source."""
+ print 'src', self.read()
+
+
if RESPONSE is not None:
RESPONSE.setHeader('Content-Type', 'text/plain')
if REQUEST is not None and REQUEST.get('raw'):
@@ -311,10 +353,7 @@
'title': 'This template has an error'},)
return icons
- def __setstate__(self, state):
- # This is here for backward compatibility. :-(
- ZopePageTemplate.inheritedAttribute('__setstate__')(self, state)
-
+ security.declareProtected(view, 'pt_source_file')
def pt_source_file(self):
"""Returns a file name to be compiled into the TAL code."""
try:
@@ -324,57 +363,74 @@
# acquisition context, so we don't know where it is. :-(
return None
- if not SUPPORTS_WEBDAV_LOCKS:
- def wl_isLocked(self):
- return 0
+ def wl_isLocked(self):
+ return 0
+ security.declareProtected(view_management_screens, 'getSource')
+ getSource = Src()
+ source_dot_xml = Src()
+
+InitializeClass(ZopePageTemplate)
+
+
setattr(ZopePageTemplate, 'source.xml', ZopePageTemplate.source_dot_xml)
setattr(ZopePageTemplate, 'source.html', ZopePageTemplate.source_dot_xml)
-# Product registration and Add support
-manage_addPageTemplateForm = PageTemplateFile(
- 'www/ptAdd', globals(), __name__='manage_addPageTemplateForm')
-from urllib import quote
+def _newZPT(id, filename):
+ """ factory to generate ZPT instances from the file-system
+ based templates (basically for internal purposes)
+ """
+ zpt = ZopePageTemplate(id, open(filename).read(), 'text/html')
+ zpt.__name__= id
+ return zpt
-def manage_addPageTemplate(self, id, title=None, text=None,
- REQUEST=None, submit=None):
+class FSZPT(ZopePageTemplate):
+ """ factory to generate ZPT instances from the file-system
+ based templates (basically for internal purposes)
+ """
+
+ def __init__(self, id, filename):
+ ZopePageTemplate.__init__(self, id, open(filename).read(), 'text/html')
+ self.__name__= id
+
+InitializeClass(FSZPT)
+
+
+ZopePageTemplate.pt_editForm = FSZPT('pt_editForm', os.path.join(package_home(globals()),'pt', 'ptEdit.pt'))
+# this is scary, do we need this?
+ZopePageTemplate.manage = ZopePageTemplate.manage_main = ZopePageTemplate.pt_editForm
+
+manage_addPageTemplateForm= FSZPT('manage_addPageTemplateForm', os.path.join(package_home(globals()), 'pt', 'ptAdd.pt'))
+
+def manage_addPageTemplate(self, id, title='', file=None, encoding='utf-8', submit=None, RESPONSE=None):
"Add a Page Template with optional file content."
- id = str(id)
- if REQUEST is None:
- self._setObject(id, ZopePageTemplate(id, text))
- ob = getattr(self, id)
- if title:
- ob.pt_setTitle(title)
- return ob
+ if file:
+ filename = file.filename
+ text = file.read()
+ encoding = sniffEncoding(text)
+ content_type, dummy = guess_content_type(filename, text)
else:
- file = REQUEST.form.get('file')
- headers = getattr(file, 'headers', None)
- if headers is None or not file.filename:
- zpt = ZopePageTemplate(id, text) # collector 596
- else:
- zpt = ZopePageTemplate(id, file, headers.get('content_type'))
+ text = open(_default_content_fn).read()
+ encoding = 'utf-8'
+ content_type = 'text/html'
- self._setObject(id, zpt)
+ zpt = ZopePageTemplate(id, text, content_type, encoding)
+ zpt.pt_setTitle(title, encoding)
+ self._setObject(id, zpt)
+ zpt = getattr(self, id)
- # collector 596
- if title:
- ob = getattr(self, id)
- ob.pt_setTitle(title)
-
- try:
- u = self.DestinationURL()
- except AttributeError:
- u = REQUEST['URL1']
-
+ if RESPONSE:
if submit == " Add and Edit ":
- u = "%s/%s" % (u, quote(id))
- REQUEST.RESPONSE.redirect(u+'/manage_main')
- return ''
+ RESPONSE.redirect(zpt.absolute_url() + '/manage_main')
+ else:
+ RESPONSE.redirect(self.absolute_url() + '/manage_main')
+ else:
+ return zpt
from Products.PageTemplates import misc_
-misc_['exclamation.gif'] = ImageFile('www/exclamation.gif', globals())
+misc_['exclamation.gif'] = ImageFile('pt/exclamation.gif', globals())
def initialize(context):
context.registerClass(
@@ -382,7 +438,7 @@
permission='Add Page Templates',
constructors=(manage_addPageTemplateForm,
manage_addPageTemplate),
- icon='www/zpt.gif',
+ icon='pt/zpt.gif',
)
context.registerHelp()
context.registerHelpTitle('Zope Help')
Added: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/default.html
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/default.html 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/default.html 2005-12-11 12:53:04 UTC (rev 40699)
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title tal:content="template/title">The title</title>
+ </head>
+ <body>
+
+ <h2><span tal:replace="here/title_or_id">content title or id</span>
+ <span tal:condition="template/title"
+ tal:replace="template/title">optional template title</span></h2>
+
+ This is Page Template <em tal:content="template/id">template id</em>.
+ </body>
+</html>
Added: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/exclamation.gif
===================================================================
(Binary files differ)
Property changes on: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/exclamation.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptAdd.pt
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptAdd.pt 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptAdd.pt 2005-12-11 12:53:04 UTC (rev 40699)
@@ -0,0 +1,62 @@
+<h1 tal:replace="structure here/manage_page_header">Header</h1>
+
+<h2 tal:define="form_title string:Add Page Template"
+ tal:replace="structure here/manage_form_title">Form Title</h2>
+
+<p class="form-help">
+Page Templates allow you to use simple HTML or XML attributes to
+create dynamic templates. You may choose to upload the template text
+from a local file by typing the file name or using the <em>browse</em>
+button.
+</p>
+
+<form action="manage_addPageTemplate" method="post"
+ enctype="multipart/form-data">
+<table cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="id" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ File
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="file" name="file" size="25" value="" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ Encoding
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="encoding" size="25" value="utf-8" />
+ <em>(only used for non-XML and non-HTML content)</em>
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ </td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <input class="form-element" type="submit" name="submit"
+ value=" Add " />
+ <input class="form-element" type="submit" name="submit"
+ value=" Add and Edit " />
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+
+<h1 tal:replace="structure here/manage_page_footer">Footer</h1>
Added: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptEdit.pt
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptEdit.pt 2005-12-11 12:02:36 UTC (rev 40698)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/ptEdit.pt 2005-12-11 12:53:04 UTC (rev 40699)
@@ -0,0 +1,161 @@
+<h1 tal:replace="structure context/manage_page_header">Header</h1>
+<h2 tal:define="manage_tabs_message options/manage_tabs_message | nothing"
+ tal:replace="structure context/manage_tabs">Tabs</h2>
+
+<tal:block define="global body request/other/text | request/form/text
+| context/read" />
+<form action="" method="post" tal:attributes="action request/URL1">
+<input type="hidden" name=":default_method" value="pt_changePrefs">
+<table width="100%" cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td align="left" valign="middle">
+ <div class="form-optional">
+ Title
+ </div>
+ </td>
+ <td align="left" valign="middle">
+ <input type="text" name="title" size="40"
+ tal:attributes="value request/title | context/title" />
+ </td>
+ <td align="left" valign="middle">
+ <div class="form-label"> Last Modified </div>
+ </td>
+ <td align="left" valign="middle">
+ <div class="form-text"
+ tal:content="python:context.bobobase_modification_time().strftime('%Y-%m-%d %I:%M %p')">1/1/2000
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="middle">
+ <div class="form-label">
+ Content-Type
+ </div>
+ </td>
+ <td align="left" valign="middle">
+ <select name="content_type" size="1" tal:define="ct context/content_type">
+ <option value="text/html" tal:attributes="SELECTED python: ct == 'text/html'">text/html</option>
+ <option value="text/xml" tal:attributes="SELECTED python: ct == 'text/xml'">text/xml</option>
+ </select>
+ </td>
+ <td align="left" valign="top" colspan=2>
+ <a href="source.html" tal:condition="context/html">Browse HTML source</a>
+ <a href="source.xml" tal:condition="not:context/html">Browse XML source</a>
+ <br>
+ <input type="hidden" name="expand:int:default" value="0">
+ <input type="checkbox" value="1" name="expand:int"
+ tal:attributes="checked request/expand | context/expand">
+ Expand macros when editing
+ </td>
+ </tr>
+
+
+ <tr>
+ <td align="left" valign="middle" class="form-label">Encoding</td>
+ <td>
+ <input type="text" readonly name="encoding" tal:attributes="value context/pt_encoding"/>
+ </td>
+ </tr>
+
+ <!-- XXX: check if 'None' is a proper argument for 'namespace' -->
+ <tr tal:define="errors python: context.pt_errors(None)" tal:condition="errors">
+ <tal:block define="global body python:context.document_src({'raw':1})"/>
+ <td align="left" valign="middle" class="form-label">Errors</td>
+ <td align="left" valign="middle" style="background-color: #FFDDDD"
+ colspan="3">
+<pre tal:content="python: '\n'.join(errors)">errors</pre>
+ </td>
+ </tr>
+
+ <tr tal:define="warnings context/pt_warnings" tal:condition="warnings">
+ <td align="left" valign="middle" class="form-label">Warnings</td>
+ <td align="left" valign="middle" style="background-color: #FFEEDD"
+ colspan="3">
+<pre tal:content="python: '\n'.join(warnings)">errors</pre>
+ </td>
+ </tr>
+
+
+
+ <tr>
+ <td align="left" valign="top" colspan="4"
+ tal:define="width request/dtpref_cols | string:100%;
+ relative_width python:str(width).endswith('%')">
+ <textarea name="text:text" wrap="off" style="width: 100%;" rows="20"
+ tal:condition="relative_width"
+ tal:attributes="style string:width: $width;;;
+ rows request/dtpref_rows | default"
+ tal:content="body">Template Body</textarea>
+ <textarea name="text:text" wrap="off" rows="20" cols="50"
+ tal:condition="not:relative_width"
+ tal:attributes="cols width; rows request/dtpref_rows | default"
+ tal:content="body">Template Body</textarea>
+ </td>
+ </tr>
+
+<tr>
+ <td align="left" valign="top" colspan="4">
+ <div class="form-element">
+ <em tal:condition="context/wl_isLocked">Locked by WebDAV</em>
+ <input tal:condition="not:context/wl_isLocked"
+ class="form-element" type="submit"
+ name="pt_editAction:method" value="Save Changes">
+
+ <input class="form-element" type="submit" name="height" value="Taller">
+ <input class="form-element" type="submit" name="height" value="Shorter">
+ <input class="form-element" type="submit" name="width" value="Wider">
+ <input class="form-element" type="submit" name="width" value="Narrower">
+ </div>
+ </td>
+</tr>
+</table>
+</form>
+
+<p class="form-help">
+You can upload the text for <span tal:replace="context/title_and_id" />
+using the following form.
+Choose an existing HTML or XML file from your local computer by clicking
+<em>browse</em>. You can also <a href="document_src">click context</a>
+to view or download the current text.
+</p>
+
+<form action="pt_upload" method="post"
+ enctype="multipart/form-data">
+<table cellpadding="2" cellspacing="0" border="0">
+<tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ File
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="file" name="file" size="40" value="">
+ </td>
+</tr>
+<tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Encoding
+ </div>
+ </td>
+ <td align="left" valign="top" colspan="2">
+ <input name="encoding" value="utf-8"/>
+ </td>
+ <td align="left" valign="top" colspan="1">
+ <em>(only used for non-XML and non-XHTML content)</em>
+ </td>
+</tr>
+<tr>
+ <td></td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <em tal:condition="context/wl_isLocked">Locked by WebDAV</em>
+ <input tal:condition="not:context/wl_isLocked"
+ class="form-element" type="submit" value="Upload File">
+ </div>
+ </td>
+</tr>
+</table>
+</form>
+
+<h1 tal:replace="structure context/manage_page_footer">Footer</h1>
Added: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/zpt.gif
===================================================================
(Binary files differ)
Property changes on: Zope/branches/ajung-zpt-integration/lib/python/Products/PageTemplates/pt/zpt.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
More information about the Zope-Checkins
mailing list