annotate PageTemplates/TALES.py @ 1028:16498e77e3ff

allow overiding of the index args roundup/cgi/templating.py
author Richard Jones <richard@users.sourceforge.net>
date Tue, 03 Sep 2002 07:33:01 +0000
parents a3a8ac7b8c40
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
984
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4 #
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # This software is subject to the provisions of the Zope Public License,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # FOR A PARTICULAR PURPOSE
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
11 #
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
12 ##############################################################################
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13 """TALES
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
15 An implementation of a generic TALES engine
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16 """
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
17
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18 __version__='$Revision: 1.1 $'[11:-2]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20 import re, sys, ZTUtils
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 from MultiMapping import MultiMapping
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
22
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23 StringType = type('')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
25 NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26 _parse_expr = re.compile(r"(%s):" % NAME_RE).match
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 _valid_name = re.compile('%s$' % NAME_RE).match
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 class TALESError(Exception):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30 """Error during TALES expression evaluation"""
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 class Undefined(TALESError):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 '''Exception raised on traversal of an undefined path'''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 class RegistrationError(Exception):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36 '''TALES Type Registration Error'''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 class CompilerError(Exception):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 '''TALES Compiler Error'''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 class Default:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 '''Retain Default'''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 Default = Default()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 _marker = []
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47 class SafeMapping(MultiMapping):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 '''Mapping with security declarations and limited method exposure.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 Since it subclasses MultiMapping, this class can be used to wrap
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 one or more mapping objects. Restricted Python code will not be
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 able to mutate the SafeMapping or the wrapped mappings, but will be
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 able to read any value.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 '''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 __allow_access_to_unprotected_subobjects__ = 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 push = pop = None
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 _push = MultiMapping.push
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 _pop = MultiMapping.pop
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 def has_get(self, key, _marker=[]):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62 v = self.get(key, _marker)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 return v is not _marker, v
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65 class Iterator(ZTUtils.Iterator):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 def __init__(self, name, seq, context):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 ZTUtils.Iterator.__init__(self, seq)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 self.name = name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 self._context = context
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 def next(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 if ZTUtils.Iterator.next(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 self._context.setLocal(self.name, self.item)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 return 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 return 0
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 class ErrorInfo:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 """Information about an exception passed to an on-error handler."""
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 __allow_access_to_unprotected_subobjects__ = 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 def __init__(self, err, position=(None, None)):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 if isinstance(err, Exception):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 self.type = err.__class__
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 self.value = err
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 self.type = err
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 self.value = None
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 self.lineno = position[0]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 self.offset = position[1]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 class Engine:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 '''Expression Engine
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 An instance of this class keeps a mutable collection of expression
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 type handlers. It can compile expression strings by delegating to
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 these handlers. It can provide an expression Context, which is
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 capable of holding state and evaluating compiled expressions.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 '''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 Iterator = Iterator
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 def __init__(self, Iterator=None):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 self.types = {}
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 if Iterator is not None:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 self.Iterator = Iterator
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 def registerType(self, name, handler):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 if not _valid_name(name):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 raise RegistrationError, 'Invalid Expression type "%s".' % name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 types = self.types
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 if types.has_key(name):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 raise RegistrationError, (
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 'Multiple registrations for Expression type "%s".' %
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 types[name] = handler
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 def getTypes(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 return self.types
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 def compile(self, expression):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 m = _parse_expr(expression)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 if m:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 type = m.group(1)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 expr = expression[m.end():]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 type = "standard"
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 expr = expression
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 try:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 handler = self.types[type]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 except KeyError:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 raise CompilerError, (
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 'Unrecognized expression type "%s".' % type)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 return handler(type, expr, self)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 def getContext(self, contexts=None, **kwcontexts):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 if contexts is not None:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 if kwcontexts:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 kwcontexts.update(contexts)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 kwcontexts = contexts
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 return Context(self, kwcontexts)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 def getCompilerError(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 return CompilerError
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 class Context:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 '''Expression Context
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
150 An instance of this class holds context information that it can
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 use to evaluate compiled expressions.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 '''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154 _context_class = SafeMapping
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155 position = (None, None)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 source_file = None
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 def __init__(self, engine, contexts):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159 self._engine = engine
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 self.contexts = contexts
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 contexts['nothing'] = None
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162 contexts['default'] = Default
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 self.repeat_vars = rv = {}
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 # Wrap this, as it is visible to restricted code
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 contexts['repeat'] = rep = self._context_class(rv)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 contexts['loop'] = rep # alias
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169 self.global_vars = gv = contexts.copy()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 self.local_vars = lv = {}
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 self.vars = self._context_class(gv, lv)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 # Keep track of what needs to be popped as each scope ends.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 self._scope_stack = []
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176 def beginScope(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 self._scope_stack.append([self.local_vars.copy()])
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 def endScope(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180 scope = self._scope_stack.pop()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
181 self.local_vars = lv = scope[0]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 v = self.vars
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183 v._pop()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
184 v._push(lv)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185 # Pop repeat variables, if any
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 i = len(scope) - 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 while i:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 name, value = scope[i]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 if value is None:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 del self.repeat_vars[name]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 self.repeat_vars[name] = value
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193 i = i - 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 def setLocal(self, name, value):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 self.local_vars[name] = value
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198 def setGlobal(self, name, value):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199 self.global_vars[name] = value
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201 def setRepeat(self, name, expr):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202 expr = self.evaluate(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
203 if not expr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
204 return self._engine.Iterator(name, (), self)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205 it = self._engine.Iterator(name, expr, self)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206 old_value = self.repeat_vars.get(name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207 self._scope_stack[-1].append((name, old_value))
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208 self.repeat_vars[name] = it
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
209 return it
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
210
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
211 def evaluate(self, expression,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
212 isinstance=isinstance, StringType=StringType):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
213 if isinstance(expression, StringType):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
214 expression = self._engine.compile(expression)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 __traceback_supplement__ = (
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216 TALESTracebackSupplement, self, expression)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
217 v = expression(self)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 return v
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 evaluateValue = evaluate
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 def evaluateBoolean(self, expr):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 return not not self.evaluate(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225 def evaluateText(self, expr, None=None):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 text = self.evaluate(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
227 if text is Default or text is None:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
228 return text
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
229 return str(text)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 def evaluateStructure(self, expr):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 return self.evaluate(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
233 evaluateStructure = evaluate
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
234
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
235 def evaluateMacro(self, expr):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
236 # XXX Should return None or a macro definition
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237 return self.evaluate(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 evaluateMacro = evaluate
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240 def createErrorInfo(self, err, position):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241 return ErrorInfo(err, position)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243 def getDefault(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 return Default
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246 def setSourceFile(self, source_file):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247 self.source_file = source_file
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249 def setPosition(self, position):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250 self.position = position
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
254 class TALESTracebackSupplement:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255 """Implementation of ITracebackSupplement"""
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256 def __init__(self, context, expression):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 self.context = context
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258 self.source_url = context.source_file
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259 self.line = context.position[0]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 self.column = context.position[1]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 self.expression = repr(expression)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 def getInfo(self, as_html=0):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264 import pprint
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265 data = self.context.contexts.copy()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 s = pprint.pformat(data)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267 if not as_html:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268 return ' - Names:\n %s' % string.replace(s, '\n', '\n ')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 from cgi import escape
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271 return '<b>Names:</b><pre>%s</pre>' % (escape(s))
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272 return None
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
273
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
275
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
276 class SimpleExpr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277 '''Simple example of an expression type handler'''
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 def __init__(self, name, expr, engine):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 self._name = name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 self._expr = expr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281 def __call__(self, econtext):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282 return self._name, self._expr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
283 def __repr__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
284 return '<SimpleExpr %s %s>' % (self._name, `self._expr`)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285

Roundup Issue Tracker: http://roundup-tracker.org/