summaryrefslogtreecommitdiff
path: root/src/zope/pagetemplate/pagetemplate.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/zope/pagetemplate/pagetemplate.py')
-rw-r--r--src/zope/pagetemplate/pagetemplate.py75
1 files changed, 57 insertions, 18 deletions
diff --git a/src/zope/pagetemplate/pagetemplate.py b/src/zope/pagetemplate/pagetemplate.py
index f9ed040..2abd728 100644
--- a/src/zope/pagetemplate/pagetemplate.py
+++ b/src/zope/pagetemplate/pagetemplate.py
@@ -21,16 +21,20 @@ from zope.tal.htmltalparser import HTMLTALParser
from zope.tal.talgenerator import TALGenerator
from zope.tal.talinterpreter import TALInterpreter
from zope.tales.engine import Engine
+from zope.component import queryUtility
# Don't use cStringIO here! It's not unicode aware.
from StringIO import StringIO
from zope.pagetemplate.interfaces import IPageTemplateSubclassing
+from zope.pagetemplate.interfaces import IPageTemplateEngine
+from zope.pagetemplate.interfaces import IPageTemplateProgram
from zope.interface import implements
-
+from zope.interface import classProvides
_default_options = {}
_error_start = '<!-- Page Template Diagnostics'
+
class PageTemplate(object):
"""Page Templates using TAL, TALES, and METAL.
@@ -61,14 +65,13 @@ class PageTemplate(object):
content_type = 'text/html'
expand = 1
_v_errors = ()
- _v_program = None
- _v_macros = None
_v_cooked = 0
+ _v_program = None
_text = ''
def macros(self):
self._cook_check()
- return self._v_macros
+ return self._v_program.macros
macros = property(macros)
@@ -106,12 +109,12 @@ class PageTemplate(object):
if self._v_errors:
raise PTRuntimeError(str(self._v_errors))
- output = StringIO(u'')
context = self.pt_getEngineContext(namespace)
- TALInterpreter(self._v_program, self._v_macros,
- context, output, tal=not source, showtal=showtal,
- strictinsert=0, sourceAnnotations=sourceAnnotations)()
- return output.getvalue()
+
+ return self._v_program(
+ context, tal=not source, showtal=showtal,
+ sourceAnnotations=sourceAnnotations
+ )
def pt_errors(self, namespace):
self._cook_check()
@@ -175,23 +178,23 @@ class PageTemplate(object):
Cooking must not fail due to compilation errors in templates.
"""
- engine = self.pt_getEngine()
+
+ pt_engine = self.pt_getEngine()
source_file = self.pt_source_file()
- if self.content_type == 'text/html':
- gen = TALGenerator(engine, xml=0, source_file=source_file)
- parser = HTMLTALParser(gen)
- else:
- gen = TALGenerator(engine, source_file=source_file)
- parser = TALParser(gen)
self._v_errors = ()
+
try:
- parser.parseString(self._text)
- self._v_program, self._v_macros = parser.getCode()
+ engine = queryUtility(
+ IPageTemplateEngine, default=PageTemplateEngine
+ )
+ self._v_program = engine.cook(
+ source_file, self._text, pt_engine, self.content_type)
except:
etype, e = sys.exc_info()[:2]
self._v_errors = ["Compilation failed",
"%s.%s: %s" % (etype.__module__, etype.__name__, e)]
+
self._v_cooked = 1
@@ -200,6 +203,42 @@ class PTRuntimeError(RuntimeError):
pass
+class PageTemplateEngine(object):
+ """Page template engine that uses the TAL interpreter to render."""
+
+ implements(IPageTemplateProgram)
+ classProvides(IPageTemplateEngine)
+
+ def __init__(self, program, macros):
+ self.macros = macros
+
+ # Internal
+ self._program = program
+
+ def __call__(self, context, **options):
+ output = StringIO(u'')
+ interpreter = TALInterpreter(
+ self._program, self.macros, context,
+ stream=output, strictinsert=0, **options
+ )
+ interpreter()
+ return output.getvalue()
+
+ @classmethod
+ def cook(cls, source_file, text, engine, content_type):
+ if content_type == 'text/html':
+ gen = TALGenerator(engine, xml=0, source_file=source_file)
+ parser = HTMLTALParser(gen)
+ else:
+ gen = TALGenerator(engine, source_file=source_file)
+ parser = TALParser(gen)
+
+ parser.parseString(text)
+ program, macros = parser.getCode()
+
+ return cls(program, macros)
+
+
class PageTemplateTracebackSupplement(object):
#implements(ITracebackSupplement)