# -*- coding: utf-8 -*- <%inherit file="content_layout.html"/> <%page args="toc, extension, paged"/> <%namespace name="formatting" file="formatting.html"/> <%namespace name="nav" file="nav.html"/> <%def name="title()">Mako Documentation - Filtering and Buffering <%! filename = 'filtering' %> ## This file is generated. Edit the .txt files instead of this one. <%call expr="formatting.section(path='filtering',paged=paged,extension=extension,toc=toc)"> <%call expr="formatting.section(path='filtering_expression',paged=paged,extension=extension,toc=toc)">

As described in the Syntax chapter, the "<%text filter='h'>|" operator can be applied to a "<%text filter='h'>${}" expression to apply escape filters to the output:

<%call expr="formatting.code()"><%text>${"this is some text" | u}

The above expression applies URL escaping to the expression, and produces <%text filter='h'>this+is+some+text.

The built-in escape flags are:

To apply more than one filter, separate them by a comma:

<%call expr="formatting.code()"><%text>${" some value " | h,trim}

The above produces <%text filter='h'><tag>some value</tag>, with no leading or trailing whitespace. The HTML escaping function is applied first, the "trim" function second.

Naturally, you can make your own filters too. A filter is just a Python function that accepts a single string argument, and returns the filtered result. The expressions after the <%text filter='h'>| operator draw upon the local namespace of the template in which they appear, meaning you can define escaping functions locally:

<%call expr="formatting.code()"><%text><%! def myescape(text): return "" + text + "" %> Heres some tagged text: ${"text" | myescape}

Or from any Python module:

<%call expr="formatting.code()"><%text><%! import myfilters %> Heres some tagged text: ${"text" | myfilters.tagfilter}

A page can apply a default set of filters to all expression tags using the <%text filter='h'>expression_filter argument to the <%text filter='h'>%page tag:

<%call expr="formatting.code()"><%text><%page expression_filter="h"/> Escaped text: ${"some html"}

Result:

<%call expr="formatting.code()"><%text>Escaped text: <html>some html</html> <%call expr="formatting.section(path='filtering_expression_defaultfilters',paged=paged,extension=extension,toc=toc)">

In addition to the <%text filter='h'>expression_filter argument, the <%text filter='h'>default_filters argument to both <%text filter='h'>Template and <%text filter='h'>TemplateLookup can specify filtering for all expression tags at the programmatic level. This array-based argument, when given its default argument of <%text filter='h'>None, will be internally set to <%text filter='h'>["unicode"] (or <%text filter='h'>["str"] on Python 3), except when <%text filter='h'>disable_unicode=True is set in which case it defaults to <%text filter='h'>["str"]:

<%call expr="formatting.code(syntaxtype='python')"><%text> t = TemplateLookup(directories=['/tmp'], default_filters=['unicode'])

To replace the usual <%text filter='h'>unicode/<%text filter='h'>str function with a specific encoding, the <%text filter='h'>decode filter can be substituted:

<%call expr="formatting.code(syntaxtype='python')"><%text> t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8'])

To disable <%text filter='h'>default_filters entirely, set it to an empty list:

<%call expr="formatting.code(syntaxtype='python')"><%text> t = TemplateLookup(directories=['/tmp'], default_filters=[])

Any string name can be added to <%text filter='h'>default_filters where it will be added to all expressions as a filter. The filters are applied from left to right, meaning the leftmost filter is applied first.

<%call expr="formatting.code(syntaxtype='python')"><%text> t = Template(templatetext, default_filters=['unicode', 'myfilter'])

To ease the usage of <%text filter='h'>default_filters with custom filters, you can also add imports (or other code) to all templates using the <%text filter='h'>imports argument:

<%call expr="formatting.code(syntaxtype='python')"><%text> t = TemplateLookup(directories=['/tmp'], default_filters=['unicode', 'myfilter'], imports=['from mypackage import myfilter'])

The above will generate templates something like this:

<%call expr="formatting.code(syntaxtype='python')"><%text> # .... from mypackage import myfilter def render_body(context): context.write(myfilter(unicode("some text"))) <%call expr="formatting.section(path='filtering_expression_turning',paged=paged,extension=extension,toc=toc)">

In all cases the special <%text filter='h'>n filter, used locally within an expression, will disable all filters declared in the <%text filter='h'><%page> tag as well <%text filter='h'>default_filters. Such as:

<%call expr="formatting.code()"><%text>${'myexpression' | n}

Will render <%text filter='h'>myexpression with no filtering of any kind, and

<%call expr="formatting.code()"><%text>${'myexpression' | n, trim}

will render <%text filter='h'>myexpression using the <%text filter='h'>trim filter only.

<%call expr="formatting.section(path='filtering_filtering',paged=paged,extension=extension,toc=toc)">

The <%text filter='h'>%def tag has a filter argument which will apply the given list of filter functions to the output of the <%text filter='h'>%def:

<%call expr="formatting.code()"><%text><%def name="foo()" filter="h, trim"> this is bold

When the filter attribute is applied to a def as above, the def is automatically buffered as well. This is described next.

<%call expr="formatting.section(path='filtering_buffering',paged=paged,extension=extension,toc=toc)">

One of Mako's central design goals is speed. To this end, all of the textual content within a template and its various callables is by default piped directly to the single buffer that is stored within the <%text filter='h'>Context object. While this normally is easy to miss, it has certain side effects. The main one is that when you call a def using the normal expression syntax, i.e. <%text filter='h'>${somedef()}, it may appear that the return value of the function is the content it produced, which is then delivered to your template just like any other expression substitution, except that normally, this is not the case; the return value of <%text filter='h'>${somedef()} is simply the empty string <%text filter='h'>''. By the time you receive this empty string, the output of <%text filter='h'>somedef() has been sent to the underlying buffer.

You may not want this effect, if for example you are doing something like this:

<%call expr="formatting.code()"><%text>${" results " + somedef() + " more results "}

If the <%text filter='h'>somedef() function produced the content "<%text filter='h'>somedef's results", the above template would produce this output:

<%call expr="formatting.code()"><%text>somedef's results results more results

This is because <%text filter='h'>somedef() fully executes before the expression returns the results of its concatenation; the concatenation in turn receives just the empty string as its middle expression.

Mako provides two ways to work around this. One is by applying buffering to the <%text filter='h'>%def itself:

<%call expr="formatting.code()"><%text><%def name="somedef()" buffered="True"> somedef's results

The above definition will generate code similar to this:

<%call expr="formatting.code()"><%text>def somedef(): context.push_buffer() try: context.write("somedef's results") finally: buf = context.pop_buffer() return buf.getvalue()

So that the content of <%text filter='h'>somedef() is sent to a second buffer, which is then popped off the stack and its value returned. The speed hit inherent in buffering the output of a def is also apparent.

Note that the <%text filter='h'>filter argument on %def also causes the def to be buffered. This is so that the final content of the %def can be delivered to the escaping function in one batch, which reduces method calls and also produces more deterministic behavior for the filtering function itself, which can possibly be useful for a filtering function that wishes to apply a transformation to the text as a whole.

The other way to buffer the output of a def or any Mako callable is by using the built-in <%text filter='h'>capture function. This function performs an operation similar to the above buffering operation except it is specified by the caller.

<%call expr="formatting.code()"><%text>${" results " + capture(somedef) + " more results "}

Note that the first argument to the <%text filter='h'>capture function is the function itself, not the result of calling it. This is because the <%text filter='h'>capture function takes over the job of actually calling the target function, after setting up a buffered environment. To send arguments to the function, just send them to <%text filter='h'>capture instead:

<%call expr="formatting.code()"><%text>${capture(somedef, 17, 'hi', use_paging=True)}

The above call is equivalent to the unbuffered call:

<%call expr="formatting.code()"><%text>${somedef(17, 'hi', use_paging=True)} <%call expr="formatting.section(path='filtering_decorating',paged=paged,extension=extension,toc=toc)">

This is a feature that's new as of version 0.2.5. Somewhat like a filter for a %def but more flexible, the <%text filter='h'>decorator argument to <%text filter='h'>%def allows the creation of a function that will work in a similar manner to a Python decorator. The function can control whether or not the function executes. The original intent of this function is to allow the creation of custom cache logic, but there may be other uses as well.

<%text filter='h'>decorator is intended to be used with a regular Python function, such as one defined in a library module. Here we'll illustrate the python function defined in the template for simplicities' sake:

<%call expr="formatting.code()"><%text><%! def bar(fn): def decorate(context, *args, **kw): context.write("BAR") fn(*args, **kw) context.write("BAR") return '' return decorate %> <%def name="foo()" decorator="bar"> this is foo ${foo()}

The above template will return, with more whitespace than this, <%text filter='h'>"BAR this is foo BAR". The function is the render callable itself (or possibly a wrapper around it), and by default will write to the context. To capture its output, use the <%text filter='h'>capture callable in the <%text filter='h'>mako.runtime module (available in templates as just <%text filter='h'>runtime):

<%call expr="formatting.code()"><%text><%! def bar(fn): def decorate(context, *args, **kw): return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR" return decorate %> <%def name="foo()" decorator="bar"> this is foo ${foo()}

The decorator can be used with top-level defs as well as nested defs. Note that when calling a top-level def from the <%text filter='h'>Template api, i.e. <%text filter='h'>template.get_def('somedef').render(), the decorator has to write the output to the <%text filter='h'>context, i.e. as in the first example. The return value gets discarded.