Mercurial > p > roundup > code
annotate PageTemplates/Expressions.py @ 1042:adcfdeac4e76
not sure how useful this is...
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Wed, 04 Sep 2002 04:47:28 +0000 |
| parents | a3a8ac7b8c40 |
| children |
| 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 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
14 """Page Template Expression Engine |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
15 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
16 Page Template-specific implementation of TALES, with handlers |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
17 for Python expressions, string literals, and paths. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
18 """ |
|
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 __version__='$Revision: 1.1 $'[11:-2] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
21 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
22 import re, sys |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
23 from TALES import Engine, CompilerError, _valid_name, NAME_RE, \ |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
24 Undefined, Default, _parse_expr |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
25 from string import strip, split, join, replace, lstrip |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
26 from Acquisition import aq_base, aq_inner, aq_parent |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
27 |
|
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 _engine = None |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
30 def getEngine(): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
31 global _engine |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
32 if _engine is None: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
33 from PathIterator import Iterator |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
34 _engine = Engine(Iterator) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
35 installHandlers(_engine) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
36 return _engine |
|
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 def installHandlers(engine): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
39 reg = engine.registerType |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
40 pe = PathExpr |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
41 for pt in ('standard', 'path', 'exists', 'nocall'): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
42 reg(pt, pe) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
43 reg('string', StringExpr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
44 reg('python', PythonExpr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45 reg('not', NotExpr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
46 reg('defer', DeferExpr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
47 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
48 if sys.modules.has_key('Zope'): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
49 import AccessControl |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
50 from AccessControl import getSecurityManager |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
51 try: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
52 from AccessControl import Unauthorized |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
53 except ImportError: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
54 Unauthorized = "Unauthorized" |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
55 if hasattr(AccessControl, 'full_read_guard'): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
56 from ZRPythonExpr import PythonExpr, _SecureModuleImporter, \ |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
57 call_with_ns |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
58 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
59 from ZPythonExpr import PythonExpr, _SecureModuleImporter, \ |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
60 call_with_ns |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
61 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
62 from PythonExpr import getSecurityManager, PythonExpr |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
63 try: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
64 from zExceptions import Unauthorized |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
65 except ImportError: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
66 Unauthorized = "Unauthorized" |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
67 def call_with_ns(f, ns, arg=1): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
68 if arg==2: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
69 return f(None, ns) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
70 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
71 return f(ns) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
72 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
73 class _SecureModuleImporter: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
74 """Simple version of the importer for use with trusted code.""" |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
75 __allow_access_to_unprotected_subobjects__ = 1 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
76 def __getitem__(self, module): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
77 __import__(module) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
78 return sys.modules[module] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
79 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
80 SecureModuleImporter = _SecureModuleImporter() |
|
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 Undefs = (Undefined, AttributeError, KeyError, |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
83 TypeError, IndexError, Unauthorized) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
84 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
85 def render(ob, ns): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
86 """ |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
87 Calls the object, possibly a document template, or just returns it if |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
88 not callable. (From DT_Util.py) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
89 """ |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
90 if hasattr(ob, '__render_with_namespace__'): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
91 ob = call_with_ns(ob.__render_with_namespace__, ns) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
92 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
93 base = aq_base(ob) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
94 if callable(base): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
95 try: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
96 if getattr(base, 'isDocTemp', 0): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
97 ob = call_with_ns(ob, ns, 2) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
98 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
99 ob = ob() |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
100 except AttributeError, n: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
101 if str(n) != '__call__': |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
102 raise |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
103 return ob |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
104 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
105 class SubPathExpr: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
106 def __init__(self, path): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
107 self._path = path = split(strip(path), '/') |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
108 self._base = base = path.pop(0) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
109 if not _valid_name(base): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
110 raise CompilerError, 'Invalid variable name "%s"' % base |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
111 # Parse path |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
112 self._dp = dp = [] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
113 for i in range(len(path)): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
114 e = path[i] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
115 if e[:1] == '?' and _valid_name(e[1:]): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
116 dp.append((i, e[1:])) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
117 dp.reverse() |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
118 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
119 def _eval(self, econtext, |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
120 list=list, isinstance=isinstance, StringType=type('')): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
121 vars = econtext.vars |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
122 path = self._path |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
123 if self._dp: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
124 path = list(path) # Copy! |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
125 for i, varname in self._dp: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
126 val = vars[varname] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
127 if isinstance(val, StringType): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
128 path[i] = val |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
129 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
130 # If the value isn't a string, assume it's a sequence |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
131 # of path names. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
132 path[i:i+1] = list(val) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
133 __traceback_info__ = base = self._base |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
134 if base == 'CONTEXTS': |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
135 ob = econtext.contexts |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
136 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
137 ob = vars[base] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
138 if isinstance(ob, DeferWrapper): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
139 ob = ob() |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
140 if path: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
141 ob = restrictedTraverse(ob, path, getSecurityManager()) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
142 return ob |
|
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 class PathExpr: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
145 def __init__(self, name, expr, engine): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
146 self._s = expr |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
147 self._name = name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
148 paths = split(expr, '|') |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
149 self._subexprs = [] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
150 add = self._subexprs.append |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
151 for i in range(len(paths)): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
152 path = lstrip(paths[i]) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
153 if _parse_expr(path): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
154 # This part is the start of another expression type, |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
155 # so glue it back together and compile it. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
156 add(engine.compile(lstrip(join(paths[i:], '|')))) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
157 break |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
158 add(SubPathExpr(path)._eval) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
159 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
160 def _exists(self, econtext): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
161 for expr in self._subexprs: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
162 try: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
163 expr(econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
164 except Undefs: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
165 pass |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
166 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
167 return 1 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
168 return 0 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
169 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
170 def _eval(self, econtext, |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
171 isinstance=isinstance, StringType=type(''), render=render): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
172 for expr in self._subexprs[:-1]: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
173 # Try all but the last subexpression, skipping undefined ones. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
174 try: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
175 ob = expr(econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
176 except Undefs: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
177 pass |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
178 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
179 break |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
180 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
181 # On the last subexpression allow exceptions through. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
182 ob = self._subexprs[-1](econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
183 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
184 if self._name == 'nocall' or isinstance(ob, StringType): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
185 return ob |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
186 # Return the rendered object |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
187 return render(ob, econtext.vars) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
188 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
189 def __call__(self, econtext): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
190 if self._name == 'exists': |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
191 return self._exists(econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
192 return self._eval(econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
193 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
194 def __str__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
195 return '%s expression %s' % (self._name, `self._s`) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
196 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
197 def __repr__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
198 return '%s:%s' % (self._name, `self._s`) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
199 |
|
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 _interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/%(n)s)*)}' % {'n': NAME_RE}) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
202 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
203 class StringExpr: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
204 def __init__(self, name, expr, engine): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
205 self._s = expr |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
206 if '%' in expr: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
207 expr = replace(expr, '%', '%%') |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
208 self._vars = vars = [] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
209 if '$' in expr: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
210 parts = [] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
211 for exp in split(expr, '$$'): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
212 if parts: parts.append('$') |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
213 m = _interp.search(exp) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
214 while m is not None: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
215 parts.append(exp[:m.start()]) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
216 parts.append('%s') |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
217 vars.append(PathExpr('path', m.group(1) or m.group(2), |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
218 engine)) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
219 exp = exp[m.end():] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
220 m = _interp.search(exp) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
221 if '$' in exp: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
222 raise CompilerError, ( |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
223 '$ must be doubled or followed by a simple path') |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
224 parts.append(exp) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
225 expr = join(parts, '') |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
226 self._expr = expr |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
227 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
228 def __call__(self, econtext): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
229 vvals = [] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
230 for var in self._vars: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
231 v = var(econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
232 if isinstance(v, Exception): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
233 raise v |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
234 vvals.append(v) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
235 return self._expr % tuple(vvals) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
236 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
237 def __str__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
238 return 'string expression %s' % `self._s` |
|
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 __repr__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
241 return 'string:%s' % `self._s` |
|
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 class NotExpr: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
244 def __init__(self, name, expr, compiler): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
245 self._s = expr = lstrip(expr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
246 self._c = compiler.compile(expr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
247 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
248 def __call__(self, econtext): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
249 return not econtext.evaluateBoolean(self._c) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
250 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
251 def __repr__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
252 return 'not:%s' % `self._s` |
|
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 DeferWrapper: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
255 def __init__(self, expr, econtext): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
256 self._expr = expr |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
257 self._econtext = econtext |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
258 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
259 def __str__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
260 return str(self()) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
261 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
262 def __call__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
263 return self._expr(self._econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
264 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
265 class DeferExpr: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
266 def __init__(self, name, expr, compiler): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
267 self._s = expr = lstrip(expr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
268 self._c = compiler.compile(expr) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
269 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
270 def __call__(self, econtext): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
271 return DeferWrapper(self._c, econtext) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
272 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
273 def __repr__(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
274 return 'defer:%s' % `self._s` |
|
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 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
277 def restrictedTraverse(self, path, securityManager, |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
278 get=getattr, has=hasattr, N=None, M=[], |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
279 TupleType=type(()) ): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
280 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
281 REQUEST = {'path': path} |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
282 REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy! |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
283 if not path[0]: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
284 # If the path starts with an empty string, go to the root first. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
285 self = self.getPhysicalRoot() |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
286 if not securityManager.validateValue(self): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
287 raise Unauthorized, name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
288 path.pop(0) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
289 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
290 path.reverse() |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
291 validate = securityManager.validate |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
292 object = self |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
293 #print 'TRAVERSE', (object, path) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
294 while path: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
295 __traceback_info__ = REQUEST |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
296 name = path.pop() |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
297 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
298 if isinstance(name, TupleType): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
299 object = apply(object, name) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
300 continue |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
301 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
302 if name[0] == '_': |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
303 # Never allowed in a URL. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
304 raise AttributeError, name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
305 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
306 if name=='..': |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
307 o = get(object, 'aq_parent', M) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
308 if o is not M: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
309 if not validate(object, object, name, o): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
310 raise Unauthorized, name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
311 object=o |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
312 continue |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
313 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
314 t = get(object, '__bobo_traverse__', N) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
315 if t is not N: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
316 o=t(REQUEST, name) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
317 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
318 container = None |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
319 if has(o, 'im_self'): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
320 container = o.im_self |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
321 elif (has(get(object, 'aq_base', object), name) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
322 and get(object, name) == o): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
323 container = object |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
324 if not validate(object, container, name, o): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
325 raise Unauthorized, name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
326 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
327 # Try an attribute. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
328 o = get(object, name, M) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
329 # print '...', (object, name, M, o) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
330 if o is not M: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
331 # Check access to the attribute. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
332 if has(object, 'aq_acquire'): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
333 object.aq_acquire( |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
334 name, validate2, validate) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
335 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
336 if not validate(object, object, name, o): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
337 raise Unauthorized, name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
338 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
339 # Try an item. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
340 try: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
341 # XXX maybe in Python 2.2 we can just check whether |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
342 # the object has the attribute "__getitem__" |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
343 # instead of blindly catching exceptions. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
344 # print 'Try an item', (object, name) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
345 o = object[name] |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
346 except AttributeError, exc: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
347 if str(exc).find('__getitem__') >= 0: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
348 # The object does not support the item interface. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
349 # Try to re-raise the original attribute error. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
350 # XXX I think this only happens with |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
351 # ExtensionClass instances. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
352 get(object, name) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
353 raise |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
354 except TypeError, exc: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
355 if str(exc).find('unsubscriptable') >= 0: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
356 # The object does not support the item interface. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
357 # Try to re-raise the original attribute error. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
358 # XXX This is sooooo ugly. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
359 get(object, name) |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
360 raise |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
361 else: |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
362 # Check access to the item. |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
363 if not validate(object, object, name, o): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
364 raise Unauthorized, name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
365 #print '... object is now', `o` |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
366 object = o |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
367 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
368 return object |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
369 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
370 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
371 def validate2(orig, inst, name, v, real_validate): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
372 if not real_validate(orig, inst, name, v): |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
373 raise Unauthorized, name |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
374 return 1 |
|
a3a8ac7b8c40
Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
375 |
