blob: d872dc1f5ab2550b4cc276cde8eca4efc837cffb [file] [log] [blame]
===================
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.