@@ -1206,46 +1206,97 @@ def fail(self, node, *args):
1206
1206
e = SecurityError ("%s:%d - execution of '%s' statements is denied" % (self .filename , lineno , nodename ))
1207
1207
self .errors .append (e )
1208
1208
1209
- class TemplateResult (storage , DictMixin ):
1209
+ class TemplateResult (object , DictMixin ):
1210
1210
"""Dictionary like object for storing template output.
1211
1211
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.
1216
1222
1217
1223
>>> d = TemplateResult(__body__='hello, world', x='foo')
1218
1224
>>> d
1219
1225
<TemplateResult: {'__body__': 'hello, world', 'x': 'foo'}>
1220
1226
>>> print d
1221
1227
hello, world
1228
+ >>> d.x
1229
+ 'foo'
1222
1230
>>> d = TemplateResult()
1223
1231
>>> d.extend([u'hello', u'world'])
1224
1232
>>> d
1225
1233
<TemplateResult: {'__body__': u'helloworld'}>
1226
1234
"""
1227
1235
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 )
1230
1273
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
1234
1279
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
1239
1282
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 ()
1241
1291
return self ["__body__" ]
1242
1292
1243
1293
def __str__ (self ):
1294
+ self ._prepare_body ()
1244
1295
return self ["__body__" ].encode ('utf-8' )
1245
1296
1246
1297
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
1249
1300
1250
1301
def test ():
1251
1302
r"""Doctest for testing template module.
0 commit comments