Filtering and Buffering {@name=filtering}
=================================

### Expression Filtering

As described in the Syntax chapter, the "`|`" operator can be applied to a "`${}`" expression to apply escape filters to the output:

    ${"this is some text" | u}

The above expression applies URL escaping to the expression, and produces `this+is+some+text`.

The built-in escape flags are:

* `u` : URL escaping, provided by `urllib.quote_plus(string.encode('utf-8'))`
* `h` : HTML escaping, provided by `cgi.escape(string, True)`
* `x` : XML escaping
* `trim` : whitespace trimming, provided by `string.strip()`
* `entity` : produces HTML entity references for applicable strings, derived from `htmlentitydefs`
* `unicode` : produces a Python unicode string (this function is applied by default).
* `decode.<some encoding>` : decode input into a Python unicode with the specified encoding

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

    ${"  <tag>some value</tag> " | h,trim}

The above produces `&lt;tag&gt;some value&lt;/tag&gt;`, 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 `|` operator draw upon the local namespace of the template in which they appear, meaning you can define escaping functions locally:
    
    <%!
        def myescape(text):
            return "<TAG>" + text + "</TAG>"
    %>
    
    Heres some tagged text: ${"text" | myescape}
    
Or from any Python module:

    <%!
        import myfilters
    %>
    
    Heres some tagged text: ${"text" | myfilters.tagfilter}
    
A page can apply a default set of filters to all expression tags using the `expression_filter` argument to the `%page` tag:

    <%page expression_filter="h"/>
    
    Escaped text:  ${"<html>some html</html>"}
    
Result:

    Escaped text: &lt;html&gt;some html&lt;/html&gt;

#### The default_filters Argument {@name=defaultfilters}

**New in version 0.1.2**

In addition to the `expression_filter` argument, the `default_filters` argument to both `Template` and `TemplateLookup` can specify filtering at the programmatic level.  This array-based argument defaults to `["unicode"]`:

    {python}
    t = TemplateLookup(directories=['/tmp'], default_filters=['unicode'])

To replace the usual `unicode` function with a specific encoding, the `decode` filter can be substituted:

    {python}
    t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8'])
    
Any string name can be added to `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.

    {python}
    t = Template(templatetext, default_filters=['unicode', 'myfilter'])
    
To ease the usage of `default_filters` with custom filters, you can also add imports (or other code) to all templates using the `imports` argument:

    {python}
    t = TemplateLookup(directories=['/tmp'], 
        default_filters=['unicode', 'myfilter'], 
        imports=['from mypackage import myfilter'])
    
The above will generate templates something like this:

    {python}
    # ....
    from mypackage import myfilter

    def render_body(context):
        context.write(myfilter(unicode("some text")))


### Filtering Defs

The `%def` tag has a filter argument which will apply the given list of filter functions to the output of the `%def`:

    <%def name="foo()" filter="h, trim">
        <b>this is bold</b>
    </%def>
    
When the filter attribute is applied to a def as above, the def is automatically **buffered** as well.  This is described next.

### Buffering

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 `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. `${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 `${somedef()}` is simply the empty string `''`.  By the time you receive this empty string, the output of `somedef()` has been sent to the underlying buffer.

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

    ${" results " + somedef() + " more results "}
    
If the `somedef()` function produced the content "`somedef's results`", the above template would produce this output:

    somedef's results results more results
    
This is because `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 `%def` itself:

    <%def name="somedef()" buffered="true">
        somedef's results
    </%def>
    
The above definition will generate code similar to this:

    def somedef():
        context.push_buffer()
        try:
            context.write("somedef's results")
        finally:
            buf = context.pop_buffer()
        return buf.getvalue()
        
So that the content of `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 `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 `capture` function.  This function performs an operation similar to the above buffering operation except it is specified by the caller.

    ${" results " + capture(somedef) + " more results "}
    
Note that the first argument to the `capture` function is **the function itself**, not the result of calling it.  This is because the `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 `capture` instead:

    ${capture(somedef, 17, 'hi', use_paging=True)}
    
The above call is equivalent to the unbuffered call:

    ${somedef(17, 'hi', use_paging=True)}
    
    
