| =================== |
| Streaming Interface |
| =================== |
| |
| With Jinja 1.1 onwards it's possible to stream the template output. This is |
| usually a bad idea because it's slower than `render()` but there are some |
| situations where it's useful. |
| |
| If you for example generate a file with a couple of megabytes you may want |
| to pass the stream to the WSGI interface in order to keep the amount of |
| memory used low and deliver the output to the browser as fast as possible. |
| |
| The streaming interface is straightforward. Instead of using `render()` you |
| can call `stream()` which does pretty much the same but doesn't return a |
| string but a `TemplateStream`: |
| |
| .. sourcecode:: pycon |
| |
| >>> tmpl = env.from_string("<ul>{% for item in seq %}\n <li>{{ loop.index " |
| ... "}} - {{ item }}</li>\n{%- endfor %}</ul>") |
| >>> stream = tmpl.stream(seq=range(4)) |
| >>> stream.next() |
| '<ul>' |
| >>> stream.next() |
| u'\n <li>1 - 0</li>' |
| >>> stream.next() |
| u'\n <li>2 - 1</li>' |
| >>> stream.next() |
| u'\n <li>3 - 2</li>' |
| >>> stream.next() |
| u'\n <li>4 - 3</li>' |
| >>> stream.next() |
| '</ul>' |
| |
| As you can see each iteration is threated as template event here. But also |
| other tags trigger events. Basically every tag yields one event, the |
| `print` tag too. The only exception is the variable substitution syntax which |
| is inserted into the template text data. |
| |
| Because some protocols like `WSGI` flush after each iteration if passed as |
| response iterable it's better to buffer some events internally. You can do |
| this by enable buffering using `enable_buffering` and passing it the buffer |
| size which must be greater than one: |
| |
| .. sourcecode:: pycon |
| |
| >>> stream.enable_buffering(size=3) |
| >>> stream.next() |
| u'<ul>\n <li>1 - 0</li>\n <li>2 - 1</li>' |
| >>> stream.next() |
| u'\n <li>3 - 2</li>\n <li>4 - 3</li></ul>' |
| |
| This will buffer 3 events before yielding. Disabling buffering works using the |
| `disable_buffering` method. You can enable and disable buffering on the fly also |
| if you have already iterated over that stream. To check if you are in buffered |
| or unbuffered mode you can use the `.buffered` property: |
| |
| .. sourcecode:: pycon |
| |
| >>> stream.buffered |
| False |
| >>> stream.enable_buffering(20) |
| >>> stream.buffered |
| True |
| >>> stream.disable_buffering() |
| >>> stream.buffered |
| False |
| |
| .. admonition:: Note |
| |
| Jinja uses buffering internally for some constructs like macros. A macro |
| call is yielded as one event, independently of the internal structure. |
| |
| The same applies to recursive for loops and `{% filter %}` tags. |