Mercurial > p > roundup > code
annotate roundup/cgi/PageTemplates/PageTemplate.py @ 4546:d39c37fd2940 git
Repository conversion from Subversion to git.
| author | Eric S. Raymond <esr@thyrsus.com> |
|---|---|
| date | Tue, 18 Oct 2011 10:20:29 -0400 |
| parents | b43efe461b3e |
| children | 6e3e4f24c753 |
| rev | line source |
|---|---|
| 1049 | 1 ############################################################################## |
| 2 # | |
| 3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
4 # |
| 1049 | 5 # This software is subject to the provisions of the Zope Public License, |
| 6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. | |
| 7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | |
| 8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | |
| 10 # FOR A PARTICULAR PURPOSE | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
11 # |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
12 ############################################################################## |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
13 # Modified for Roundup: |
| 1049 | 14 # |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
15 # 1. changed imports to import from roundup.cgi |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
16 # 2. removed use of ExtensionClass |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
17 # 3. removed use of ComputedAttribute |
| 1049 | 18 """Page Template module |
| 19 | |
| 20 HTML- and XML-based template objects using TAL, TALES, and METAL. | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
21 """ |
|
1071
c08b3820edd1
Adhering to ZPL
Richard Jones <richard@users.sourceforge.net>
parents:
1049
diff
changeset
|
22 |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
23 __version__='$Revision: 1.5 $'[11:-2] |
| 1049 | 24 |
| 25 import sys | |
| 26 | |
| 27 from roundup.cgi.TAL.TALParser import TALParser | |
| 28 from roundup.cgi.TAL.HTMLTALParser import HTMLTALParser | |
| 29 from roundup.cgi.TAL.TALGenerator import TALGenerator | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
30 # Do not use cStringIO here! It's not unicode aware. :( |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
31 from roundup.cgi.TAL.TALInterpreter import TALInterpreter, FasterStringIO |
| 1049 | 32 from Expressions import getEngine |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
33 |
| 1049 | 34 |
| 35 class PageTemplate: | |
| 36 "Page Templates using TAL, TALES, and METAL" | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
37 |
| 1049 | 38 content_type = 'text/html' |
| 39 expand = 0 | |
| 40 _v_errors = () | |
| 41 _v_warnings = () | |
| 42 _v_program = None | |
| 43 _v_macros = None | |
| 44 _v_cooked = 0 | |
| 45 id = '(unknown)' | |
| 46 _text = '' | |
| 47 _error_start = '<!-- Page Template Diagnostics' | |
| 48 | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
49 def StringIO(self): |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
50 # Third-party products wishing to provide a full Unicode-aware |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
51 # StringIO can do so by monkey-patching this method. |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
52 return FasterStringIO() |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
53 |
| 1049 | 54 def pt_edit(self, text, content_type): |
| 55 if content_type: | |
| 56 self.content_type = str(content_type) | |
| 57 if hasattr(text, 'read'): | |
| 58 text = text.read() | |
| 59 self.write(text) | |
| 60 | |
| 61 def pt_getContext(self): | |
| 62 c = {'template': self, | |
| 63 'options': {}, | |
| 64 'nothing': None, | |
| 65 'request': None, | |
| 66 'modules': ModuleImporter, | |
| 67 } | |
| 68 parent = getattr(self, 'aq_parent', None) | |
| 69 if parent is not None: | |
| 70 c['here'] = parent | |
| 71 c['container'] = self.aq_inner.aq_parent | |
| 72 while parent is not None: | |
| 73 self = parent | |
| 74 parent = getattr(self, 'aq_parent', None) | |
| 75 c['root'] = self | |
| 76 return c | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
77 |
| 1049 | 78 def pt_render(self, source=0, extra_context={}): |
| 79 """Render this Page Template""" | |
| 80 if not self._v_cooked: | |
| 81 self._cook() | |
| 82 | |
| 83 __traceback_supplement__ = (PageTemplateTracebackSupplement, self) | |
| 84 | |
| 85 if self._v_errors: | |
| 86 raise PTRuntimeError, 'Page Template %s has errors.' % self.id | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
87 output = self.StringIO() |
| 1049 | 88 c = self.pt_getContext() |
| 89 c.update(extra_context) | |
| 90 | |
| 91 TALInterpreter(self._v_program, self._v_macros, | |
| 92 getEngine().getContext(c), | |
| 93 output, | |
| 94 tal=not source, strictinsert=0)() | |
| 95 return output.getvalue() | |
| 96 | |
| 97 def __call__(self, *args, **kwargs): | |
| 98 if not kwargs.has_key('args'): | |
| 99 kwargs['args'] = args | |
| 100 return self.pt_render(extra_context={'options': kwargs}) | |
| 101 | |
| 102 def pt_errors(self): | |
| 103 if not self._v_cooked: | |
| 104 self._cook() | |
| 105 err = self._v_errors | |
| 106 if err: | |
| 107 return err | |
| 108 if not self.expand: return | |
| 109 try: | |
| 110 self.pt_render(source=1) | |
| 111 except: | |
| 112 return ('Macro expansion failed', '%s: %s' % sys.exc_info()[:2]) | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
113 |
| 1049 | 114 def pt_warnings(self): |
| 115 if not self._v_cooked: | |
| 116 self._cook() | |
| 117 return self._v_warnings | |
| 118 | |
| 119 def pt_macros(self): | |
| 120 if not self._v_cooked: | |
| 121 self._cook() | |
|
1204
b862bbf2067a
Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents:
1071
diff
changeset
|
122 __traceback_supplement__ = (PageTemplateTracebackSupplement, self) |
| 1049 | 123 if self._v_errors: |
| 124 raise PTRuntimeError, 'Page Template %s has errors.' % self.id | |
| 125 return self._v_macros | |
| 126 | |
|
1204
b862bbf2067a
Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents:
1071
diff
changeset
|
127 def __getattr__(self, name): |
|
b862bbf2067a
Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents:
1071
diff
changeset
|
128 if name == 'macros': |
|
b862bbf2067a
Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents:
1071
diff
changeset
|
129 return self.pt_macros() |
|
b862bbf2067a
Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents:
1071
diff
changeset
|
130 raise AttributeError, name |
|
b862bbf2067a
Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents:
1071
diff
changeset
|
131 |
| 1049 | 132 def pt_source_file(self): |
| 133 return None # Unknown. | |
| 134 | |
| 135 def write(self, text): | |
| 136 assert type(text) is type('') | |
| 137 if text[:len(self._error_start)] == self._error_start: | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
138 errend = text.find('-->') |
| 1049 | 139 if errend >= 0: |
| 140 text = text[errend + 4:] | |
| 141 if self._text != text: | |
| 142 self._text = text | |
| 143 self._cook() | |
| 144 | |
| 145 def read(self): | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
146 self._cook_check() |
| 1049 | 147 if not self._v_errors: |
| 148 if not self.expand: | |
| 149 return self._text | |
| 150 try: | |
| 151 return self.pt_render(source=1) | |
| 152 except: | |
| 153 return ('%s\n Macro expansion failed\n %s\n-->\n%s' % | |
| 154 (self._error_start, "%s: %s" % sys.exc_info()[:2], | |
| 155 self._text) ) | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
156 |
| 1049 | 157 return ('%s\n %s\n-->\n%s' % (self._error_start, |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
158 '\n '.join(self._v_errors), |
| 1049 | 159 self._text)) |
| 160 | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
161 def _cook_check(self): |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
162 if not self._v_cooked: |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
163 self._cook() |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
164 |
| 1049 | 165 def _cook(self): |
| 166 """Compile the TAL and METAL statments. | |
| 167 | |
| 168 Cooking must not fail due to compilation errors in templates. | |
| 169 """ | |
| 170 source_file = self.pt_source_file() | |
| 171 if self.html(): | |
| 172 gen = TALGenerator(getEngine(), xml=0, source_file=source_file) | |
| 173 parser = HTMLTALParser(gen) | |
| 174 else: | |
| 175 gen = TALGenerator(getEngine(), source_file=source_file) | |
| 176 parser = TALParser(gen) | |
| 177 | |
| 178 self._v_errors = () | |
| 179 try: | |
| 180 parser.parseString(self._text) | |
| 181 self._v_program, self._v_macros = parser.getCode() | |
| 182 except: | |
| 183 self._v_errors = ["Compilation failed", | |
| 184 "%s: %s" % sys.exc_info()[:2]] | |
| 185 self._v_warnings = parser.getWarnings() | |
| 186 self._v_cooked = 1 | |
| 187 | |
| 188 def html(self): | |
| 189 if not hasattr(getattr(self, 'aq_base', self), 'is_html'): | |
| 190 return self.content_type == 'text/html' | |
| 191 return self.is_html | |
| 192 | |
| 193 class _ModuleImporter: | |
| 194 def __getitem__(self, module): | |
| 195 mod = __import__(module) | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
196 path = module.split('.') |
| 1049 | 197 for name in path[1:]: |
| 198 mod = getattr(mod, name) | |
| 199 return mod | |
| 200 | |
| 201 ModuleImporter = _ModuleImporter() | |
| 202 | |
| 203 class PTRuntimeError(RuntimeError): | |
| 204 '''The Page Template has template errors that prevent it from rendering.''' | |
| 205 pass | |
| 206 | |
| 207 | |
| 208 class PageTemplateTracebackSupplement: | |
| 209 #__implements__ = ITracebackSupplement | |
| 210 | |
| 211 def __init__(self, pt): | |
| 212 self.object = pt | |
| 213 w = pt.pt_warnings() | |
| 214 e = pt.pt_errors() | |
| 215 if e: | |
| 216 w = list(w) + list(e) | |
| 217 self.warnings = w | |
| 218 |
