1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
import os
from webob import Response
from zope.component import queryUtility
from zope.component.interfaces import ComponentLookupError
from zope.component import getSiteManager
from zope.interface import classProvides
from zope.interface import implements
from repoze.bfg.path import caller_path
from repoze.bfg.interfaces import ITemplateFactory
from repoze.bfg.interfaces import ITemplate
from repoze.bfg.interfaces import INodeTemplate
from repoze.bfg.interfaces import ISettings
class Z3CPTTemplateFactory(object):
classProvides(ITemplateFactory)
implements(ITemplate)
def __init__(self, path, auto_reload=False):
from z3c.pt import PageTemplateFile
try:
self.template = PageTemplateFile(path, auto_reload=auto_reload)
except TypeError:
# z3c.pt before 1.0
self.template = PageTemplateFile(path)
def __call__(self, **kw):
result = self.template.render(**kw)
return result
class XSLTemplateFactory(object):
classProvides(ITemplateFactory)
implements(INodeTemplate)
def __init__(self, path, auto_reload=False):
self.path = path
self.auto_reload = auto_reload
def __call__(self, node, **kw):
processor = get_processor(self.path, self.auto_reload)
result = str(processor(node, **kw))
return result
# Manage XSLT processors on a per-thread basis
import threading
from lxml import etree
xslt_pool = threading.local()
def get_processor(xslt_fn, auto_reload=False):
if not auto_reload:
try:
return xslt_pool.processors[xslt_fn]
except AttributeError:
xslt_pool.processors = {}
except KeyError:
pass
# Make a processor and add it to the pool
source = etree.ElementTree(file=xslt_fn)
proc = etree.XSLT(source)
xslt_pool.processors[xslt_fn] = proc
return proc
def registerTemplate(type, template, path):
try:
sm = getSiteManager()
except ComponentLookupError:
pass
else:
sm.registerUtility(template, type, name=path)
def _get_template(path, **kw):
# XXX use pkg_resources
template = queryUtility(ITemplate, path)
if template is None:
if not os.path.exists(path):
raise ValueError('Missing template file: %s' % path)
settings = queryUtility(ISettings)
auto_reload = settings and settings.reload_templates
template = Z3CPTTemplateFactory(path, auto_reload)
registerTemplate(ITemplate, template, path)
return template
def get_template(path):
""" Return a z3c.pt template object at the package-relative path
(may also be absolute) """
path = caller_path(path)
return _get_template(path).template
def render_template(path, **kw):
""" Render a z3c.pt (ZPT) template at the package-relative path
(may also be absolute) using the kwargs in ``*kw`` as top-level
names and return a string. """
path = caller_path(path)
template = get_template(path)
return template(**kw)
def render_template_to_response(path, **kw):
""" Render a z3c.pt (ZPT) template at the package-relative path
(may also be absolute) using the kwargs in ``*kw`` as top-level
names and return a Response object. """
path = caller_path(path)
result = render_template(path, **kw)
return Response(result)
def render_transform(path, node, **kw):
""" Render a XSL template at the package-relative path (may also
be absolute) using the kwargs in ``*kw`` as top-level names and
return a string."""
# Render using XSLT
path = caller_path(path)
template = queryUtility(INodeTemplate, path)
if template is None:
if not os.path.exists(path):
raise ValueError('Missing template file: %s' % path)
template = XSLTemplateFactory(path)
registerTemplate(INodeTemplate, template, path)
return template(node, **kw)
def render_transform_to_response(path, node, **kw):
""" Render a XSL template at the package-relative path (may also
be absolute) using the kwargs in ``*kw`` as top-level names and
return a Response object."""
path = caller_path(path)
result = render_transform(path, node, **kw)
return Response(result)
|