| 696 | | either a ``render()`` or ``iter_render()`` method. A compiled template is, |
|---|
| 697 | | simply, a list of ``Node`` objects. When you call ``render()`` on a compiled |
|---|
| 698 | | template object, the template calls ``render()`` on each ``Node`` in its node |
|---|
| 699 | | list, with the given context. The results are all concatenated together to |
|---|
| 700 | | form the output of the template. |
|---|
| | 696 | a ``render()`` method. A compiled template is, simply, a list of ``Node`` |
|---|
| | 697 | objects. When you call ``render()`` on a compiled template object, the template |
|---|
| | 698 | calls ``render()`` on each ``Node`` in its node list, with the given context. |
|---|
| | 699 | The results are all concatenated together to form the output of the template. |
|---|
| 1180 | | Improving rendering speed |
|---|
| 1181 | | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 1182 | | |
|---|
| 1183 | | For most practical purposes, the ``render()`` method on a ``Node`` will be |
|---|
| 1184 | | sufficient and the simplest way to implement a new tag. However, if your |
|---|
| 1185 | | template tag is expected to produce large strings via ``render()``, you can |
|---|
| 1186 | | speed up the rendering process (and reduce memory usage) using iterative |
|---|
| 1187 | | rendering via the ``iter_render()`` method. |
|---|
| 1188 | | |
|---|
| 1189 | | The ``iter_render()`` method should either be an iterator that yields string |
|---|
| 1190 | | chunks, one at a time, or a method that returns a sequence of string chunks. |
|---|
| 1191 | | The template renderer will join the successive chunks together when creating |
|---|
| 1192 | | the final output. The improvement over the ``render()`` method here is that |
|---|
| 1193 | | you do not need to create one large string containing all the output of the |
|---|
| 1194 | | ``Node``, instead you can produce the output in smaller chunks. |
|---|
| 1195 | | |
|---|
| 1196 | | By way of example, here's a trivial ``Node`` subclass that simply returns the |
|---|
| 1197 | | contents of a file it is given:: |
|---|
| 1198 | | |
|---|
| 1199 | | class FileNode(Node): |
|---|
| 1200 | | def __init__(self, filename): |
|---|
| 1201 | | self.filename = filename |
|---|
| 1202 | | |
|---|
| 1203 | | def iter_render(self): |
|---|
| 1204 | | for line in file(self.filename): |
|---|
| 1205 | | yield line |
|---|
| 1206 | | |
|---|
| 1207 | | For very large files, the full file contents will never be read entirely into |
|---|
| 1208 | | memory when this tag is used, which is a useful optimisation. |
|---|
| 1209 | | |
|---|
| 1210 | | If you define an ``iter_render()`` method on your ``Node`` subclass, you do |
|---|
| 1211 | | not need to define a ``render()`` method. The reverse is true as well: the |
|---|
| 1212 | | default ``Node.iter_render()`` method will call your ``render()`` method if |
|---|
| 1213 | | necessary. A useful side-effect of this is that you can develop a new tag |
|---|
| 1214 | | using ``render()`` and producing all the output at once, which is easy to |
|---|
| 1215 | | debug. Then you can rewrite the method as an iterator, rename it to |
|---|
| 1216 | | ``iter_render()`` and everything will still work. |
|---|
| 1217 | | |
|---|
| 1218 | | It is compulsory, however, to define *either* ``render()`` or ``iter_render()`` |
|---|
| 1219 | | in your subclass. If you omit them both, a ``TypeError`` will be raised when |
|---|
| 1220 | | the code is imported. |
|---|
| 1221 | | |
|---|