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
|
import os
import sys
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 webob import Response
from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import ITemplateFactory
class Z3CPTTemplateFactory(object):
classProvides(ITemplateFactory)
implements(IView)
def __init__(self, path):
from z3c.pt import PageTemplateFile
self.template = PageTemplateFile(path)
def __call__(self, *arg, **kw):
result = self.template.render(**kw)
response = Response(result)
return response
class XSLTemplateFactory(object):
classProvides(ITemplateFactory)
implements(IView)
def __init__(self, path):
self.path = path
def __call__(self, *arg, **kw):
node = kw.get("node")
processor = get_processor(self.path)
result = str(processor(node))
response = Response(result)
return response
# Manage XSLT processors on a per-thread basis
import threading
from lxml import etree
xslt_pool = threading.local()
def get_processor(xslt_fn):
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 package_path(package):
return os.path.abspath(os.path.dirname(package.__file__))
def registerTemplate(template, path):
try:
sm = getSiteManager()
except ComponentLookupError:
pass
else:
sm.registerUtility(template, IView, name=path)
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 Response object. """
# XXX use pkg_resources
if not os.path.isabs(path):
package_globals = sys._getframe(1).f_globals
package_name = package_globals['__name__']
package = sys.modules[package_name]
prefix = package_path(package)
path = os.path.join(prefix, path)
template = queryUtility(IView, path)
if template is None:
if not os.path.exists(path):
raise ValueError('Missing template file: %s' % path)
template = Z3CPTTemplateFactory(path)
registerTemplate(template, path)
return template(**kw)
def render_transform(path, **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."""
# Render using XSLT
if not os.path.isabs(path):
package_globals = sys._getframe(1).f_globals
package_name = package_globals['__name__']
package = sys.modules[package_name]
prefix = package_path(package)
path = os.path.join(prefix, path)
template = queryUtility(IView, path)
node = kw.get("node")
if template is None:
if not os.path.exists(path):
raise ValueError('Missing template file: %s' % path)
template = XSLTemplateFactory(path)
registerTemplate(template, path)
return template(**kw)
|