1
# Copyright (c) 2004 Divmod.
2
# See LICENSE for details.
4
"""Builtin template loaders that supply a Page or renderer with a
7
Nevow provides the following DocFactory loaders by default:
9
- B{stan} - turn a stan tag tree into a DocFactory
10
- B{xmlfile} - load a well formed XML document from file
11
- B{htmlfile} - load a HTML file from disk
12
- B{xmlstr} - load a well formed XML document from a string
13
- B{htmlstr} - load a HTML document from a string
15
Unless absolutely necessary you should use either the stan loader or
16
one of the xml loaders. The html loaders should only be used for badly
17
formed HTML documents, i.e. if your HTML developer hasn't heard of
18
XHTML yet. Even then, you should probably try to educate the HTML
25
from zope.interface import implements
27
from twisted.python.reflect import getClass
28
from twisted.web import microdom
30
from nevow import inevow
31
from nevow import flat
32
from nevow.flat import flatsax
33
from nevow.util import CachedFile
37
"""A stan tags document factory"""
39
implements(inevow.IDocFactory)
45
def __init__(self, stan=None, pattern=None):
48
if pattern is not None:
49
self.pattern = pattern
52
def load(self, ctx=None, preprocessors=()):
53
if self._cache is None:
55
for proc in preprocessors:
57
stan = flat.precompile(stan, ctx)
58
if self.pattern is not None:
59
stan = inevow.IQ(stan).onePattern(self.pattern)
65
class htmlstr(object):
66
"""A document factory for HTML contained in a string"""
68
implements(inevow.IDocFactory)
72
beExtremelyLenient = True
75
def __init__(self, template=None, pattern=None, beExtremelyLenient=None):
77
"[v0.8] htmlstr is deprecated because it's buggy. Please start using xmlfile and/or xmlstr.",
80
if template is not None:
81
self.template = template
82
if pattern is not None:
83
self.pattern = pattern
84
if beExtremelyLenient is not None:
85
self.beExtremelyLenient = beExtremelyLenient
87
def load(self, ctx=None, preprocessors=()):
88
assert not preprocessors, "preprocessors not supported by htmlstr"
89
if self._cache is None:
90
doc = microdom.parseString(self.template, beExtremelyLenient=self.beExtremelyLenient)
91
doc = flat.precompile(doc, ctx)
92
if self.pattern is not None:
93
doc = inevow.IQ(doc).onePattern(self.pattern)
97
class htmlfile(object):
98
"""A document factory for an HTML disk template"""
100
implements(inevow.IDocFactory)
105
beExtremelyLenient = True
107
def __init__(self, template=None, pattern=None, templateDir=None, beExtremelyLenient=None):
109
"[v0.8] htmlfile is deprecated because it's buggy. Please start using xmlfile and/or xmlstr.",
112
if template is not None:
113
self.template = template
114
if pattern is not None:
115
self.pattern = pattern
116
if templateDir is not None:
117
self.templateDir = templateDir
118
if beExtremelyLenient is not None:
119
self.beExtremelyLenient = beExtremelyLenient
120
_filename = os.path.join(self.templateDir, self.template)
121
self._cache = CachedFile(_filename, self._reallyLoad)
123
def _reallyLoad(self, path, ctx):
124
doc = microdom.parse(path, beExtremelyLenient=self.beExtremelyLenient)
125
doc = flat.precompile(doc, ctx)
126
if self.pattern is not None:
127
doc = inevow.IQ(doc).onePattern(self.pattern)
130
def load(self, ctx=None, preprocessors=()):
131
assert not preprocessors, "preprocessors not supported by htmlfile"
132
return self._cache.load(ctx)
134
class xmlstr(object):
136
implements(inevow.IDocFactory)
144
def __init__(self, template=None, pattern=None, ignoreDocType=False, ignoreComment=False):
145
if template is not None:
146
self.template = template
147
if pattern is not None:
148
self.pattern = pattern
149
if ignoreDocType is not None:
150
self.ignoreDocType = ignoreDocType
151
if ignoreComment is not None:
152
self.ignoreComment = ignoreComment
154
def load(self, ctx=None, preprocessors=()):
156
Get an instance, possibly cached from a previous call, of this document
158
if self._cache is None:
159
doc = flatsax.parseString(self.template, self.ignoreDocType, self.ignoreComment)
160
for proc in preprocessors:
162
doc = flat.precompile(doc, ctx)
163
if self.pattern is not None:
164
doc = inevow.IQ(doc).onePattern(self.pattern)
169
class xmlfile(object):
171
implements(inevow.IDocFactory)
176
ignoreDocType = False
177
ignoreComment = False
179
def __init__(self, template=None, pattern=None, templateDir=None, ignoreDocType=None, ignoreComment=None):
181
if template is not None:
182
self.template = template
183
if pattern is not None:
184
self.pattern = pattern
185
if templateDir is not None:
186
self.templateDir = templateDir
187
if ignoreDocType is not None:
188
self.ignoreDocType = ignoreDocType
189
if ignoreComment is not None:
190
self.ignoreComment = ignoreComment
191
if self.templateDir is not None:
192
self._filename = os.path.join(self.templateDir, self.template)
194
self._filename = self.template
198
def load(self, ctx=None, preprocessors=()):
199
rendererFactoryClass = None
201
r = inevow.IRendererFactory(ctx, None)
203
rendererFactoryClass = getClass(r)
205
cacheKey = (self._filename, self.pattern, rendererFactoryClass)
206
cachedFile = self._cache.get(cacheKey)
207
if cachedFile is None:
208
cachedFile = self._cache[cacheKey] = CachedFile(self._filename, self._reallyLoad)
210
return cachedFile.load(ctx, preprocessors)
212
def _reallyLoad(self, path, ctx, preprocessors):
213
doc = flatsax.parse(open(self._filename), self.ignoreDocType, self.ignoreComment)
214
for proc in preprocessors:
216
doc = flat.precompile(doc, ctx)
218
if self.pattern is not None:
219
doc = inevow.IQ(doc).onePattern(self.pattern)