Skip to content

Commit a42ca49

Browse files
committed
Fixed some issues with TemplateResult.
.get("__body__") on TemplateResult used to return None. Same issue was there for .values() and .items() as __body__ has special treatment. This has been fixed.
1 parent 6758807 commit a42ca49

File tree

1 file changed

+68
-17
lines changed

1 file changed

+68
-17
lines changed

web/template.py

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,46 +1206,97 @@ def fail(self, node, *args):
12061206
e = SecurityError("%s:%d - execution of '%s' statements is denied" % (self.filename, lineno, nodename))
12071207
self.errors.append(e)
12081208

1209-
class TemplateResult(storage, DictMixin):
1209+
class TemplateResult(object, DictMixin):
12101210
"""Dictionary like object for storing template output.
12111211
1212-
A template can specify key-value pairs in the output using
1213-
`var` statements. Each `var` statement adds a new key to the
1214-
template output and the main output is stored with key
1215-
__body__.
1212+
The result of a template execution is usally a string, but sometimes it
1213+
contains attributes set using $var. This class provides a simple
1214+
dictionary like interface for storing the output of the template and the
1215+
attributes. The output is stored with a special key __body__. Convering
1216+
the the TemplateResult to string or unicode returns the value of __body__.
1217+
1218+
When the template is in execution, the output is generated part by part
1219+
and those parts are combined at the end. Parts are added to the
1220+
TemplateResult by calling the `extend` method and the parts are combined
1221+
seemlessly when __body__ is accessed.
12161222
12171223
>>> d = TemplateResult(__body__='hello, world', x='foo')
12181224
>>> d
12191225
<TemplateResult: {'__body__': 'hello, world', 'x': 'foo'}>
12201226
>>> print d
12211227
hello, world
1228+
>>> d.x
1229+
'foo'
12221230
>>> d = TemplateResult()
12231231
>>> d.extend([u'hello', u'world'])
12241232
>>> d
12251233
<TemplateResult: {'__body__': u'helloworld'}>
12261234
"""
12271235
def __init__(self, *a, **kw):
1228-
storage.__init__(self, *a, **kw)
1229-
self.setdefault("__body__", None)
1236+
self.__dict__["_d"] = dict(*a, **kw)
1237+
self._d.setdefault("__body__", u'')
1238+
1239+
self.__dict__['_parts'] = []
1240+
self.__dict__["extend"] = self._parts.extend
1241+
1242+
self._d.setdefault("__body__", None)
1243+
1244+
def keys(self):
1245+
return self._d.keys()
1246+
1247+
def _prepare_body(self):
1248+
"""Prepare value of __body__ by joining parts.
1249+
"""
1250+
if self._parts:
1251+
value = u"".join(self._parts)
1252+
self._parts[:] = []
1253+
body = self._d.get('__body__')
1254+
if body:
1255+
self._d['__body__'] = body + value
1256+
else:
1257+
self._d['__body__'] = value
1258+
1259+
def __getitem__(self, name):
1260+
if name == "__body__":
1261+
self._prepare_body()
1262+
return self._d[name]
1263+
1264+
def __setitem__(self, name, value):
1265+
if name == "__body__":
1266+
self._prepare_body()
1267+
return self._d.__setitem__(name, value)
1268+
1269+
def __delitem__(self, name):
1270+
if name == "__body__":
1271+
self._prepare_body()
1272+
return self._d.__delitem__(name)
12301273

1231-
# avoiding self._data because it adds as item instead of attr.
1232-
self.__dict__["_data"] = []
1233-
self.__dict__["extend"] = self._data.extend
1274+
def __getattr__(self, key):
1275+
try:
1276+
return self[key]
1277+
except KeyError, k:
1278+
raise AttributeError, k
12341279

1235-
def __getitem__(self, name):
1236-
if name == "__body__" and storage.__getitem__(self, '__body__') is None:
1237-
self["__body__"] = u"".join(self._data)
1238-
return storage.__getitem__(self, name)
1280+
def __setattr__(self, key, value):
1281+
self[key] = value
12391282

1240-
def __unicode__(self):
1283+
def __delattr__(self, key):
1284+
try:
1285+
del self[key]
1286+
except KeyError, k:
1287+
raise AttributeError, k
1288+
1289+
def __unicode__(self):
1290+
self._prepare_body()
12411291
return self["__body__"]
12421292

12431293
def __str__(self):
1294+
self._prepare_body()
12441295
return self["__body__"].encode('utf-8')
12451296

12461297
def __repr__(self):
1247-
self["__body__"] # initialize __body__ if not already initialized
1248-
return "<TemplateResult: %s>" % dict.__repr__(self)
1298+
self._prepare_body()
1299+
return "<TemplateResult: %s>" % self._d
12491300

12501301
def test():
12511302
r"""Doctest for testing template module.

0 commit comments

Comments
 (0)