1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Filter Functions — Jinja Documentation</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css">
<style type="text/css">
.syntax { background: #ffffff; }
.syntax .c { color: #888888 } /* Comment */
.syntax .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.syntax .k { color: #008800; font-weight: bold } /* Keyword */
.syntax .cm { color: #888888 } /* Comment.Multiline */
.syntax .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.syntax .c1 { color: #888888 } /* Comment.Single */
.syntax .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.syntax .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.syntax .ge { font-style: italic } /* Generic.Emph */
.syntax .gr { color: #aa0000 } /* Generic.Error */
.syntax .gh { color: #303030 } /* Generic.Heading */
.syntax .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.syntax .go { color: #888888 } /* Generic.Output */
.syntax .gp { color: #555555 } /* Generic.Prompt */
.syntax .gs { font-weight: bold } /* Generic.Strong */
.syntax .gu { color: #606060 } /* Generic.Subheading */
.syntax .gt { color: #aa0000 } /* Generic.Traceback */
.syntax .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.syntax .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.syntax .kp { color: #008800 } /* Keyword.Pseudo */
.syntax .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.syntax .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.syntax .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.syntax .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.syntax .na { color: #336699 } /* Name.Attribute */
.syntax .nb { color: #003388 } /* Name.Builtin */
.syntax .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.syntax .no { color: #003366; font-weight: bold } /* Name.Constant */
.syntax .nd { color: #555555 } /* Name.Decorator */
.syntax .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.syntax .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.syntax .nl { color: #336699; font-style: italic } /* Name.Label */
.syntax .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.syntax .py { color: #336699; font-weight: bold } /* Name.Property */
.syntax .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.syntax .nv { color: #336699 } /* Name.Variable */
.syntax .ow { color: #008800 } /* Operator.Word */
.syntax .w { color: #bbbbbb } /* Text.Whitespace */
.syntax .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.syntax .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.syntax .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.syntax .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.syntax .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.syntax .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.syntax .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.syntax .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.syntax .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.syntax .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.syntax .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.syntax .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.syntax .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.syntax .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.syntax .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.syntax .bp { color: #003388 } /* Name.Builtin.Pseudo */
.syntax .vc { color: #336699 } /* Name.Variable.Class */
.syntax .vg { color: #dd7700 } /* Name.Variable.Global */
.syntax .vi { color: #3333bb } /* Name.Variable.Instance */
.syntax .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
</style>
</head>
<body>
<div id="content">
<h1 class="heading"><span>Jinja</span></h1>
<h2 class="subheading">Filter Functions</h2>
<div id="toc">
<h2>Navigation</h2>
<ul>
<li><a href="index.html">back to index</a></li>
</ul>
<h2>Contents</h2>
<ul class="contents">
<li><a href="#writing-filters">Writing Filters</a></li>
</ul>
</div>
<div id="contentwrapper">
<p>Filters are a powerful feature of Jinja taken from django which probably took
it from UNIX. The idea is that you "pipe" a value through some filters to
do something with it. For example convert it to upper case, escape it or
replace a substring.</p>
<p>Jinja comes with some builtin filters explained in the <a class="reference" href="./builtins.html">designer documentation</a>.</p>
<div class="section">
<h2><a id="writing-filters" name="writing-filters">Writing Filters</a></h2>
<p>A filter basically is a factory function, a function that returns another
function. We do this because filters can get an unlimited amount of positional
arguments and aditionally should gain access to the environment, context and
piped value. A simple filter looks like this:</p>
<div class="syntax"><pre><span class="k">def</span> <span class="nf">do_join</span><span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="s">u''</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">wrapped</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span>
<span class="n">tmp</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">env</span><span class="o">.</span><span class="n">to_unicode</span><span class="p">(</span><span class="n">item</span><span class="p">))</span>
<span class="k">return</span> <span class="n">d</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span>
<span class="k">return</span> <span class="n">wrapped</span>
</pre></div>
<p>Now you have to register that filter on an environment:</p>
<div class="syntax"><pre><span class="n">env</span><span class="o">.</span><span class="n">filters</span><span class="p">[</span><span class="s">'join'</span><span class="p">]</span> <span class="o">=</span> <span class="n">do_join</span>
</pre></div>
<p>In fact this filter is already bundled so you won't see any effect. But it
should explain how such a filter looks like. The template designer can just
trigger the outer code (i.e. call <cite>join</cite> with or without arguments). The
returned function is then processed by the jinja template engine once all
filters are created.</p>
<p>If you want to create filters that just operate on a string (in fact unicode
objects) you can use the <cite>stringfilter</cite> decorator:</p>
<div class="syntax"><pre><span class="k">from</span> <span class="nn">jinja.filters</span> <span class="k">import</span> <span class="n">stringfilter</span>
<span class="nd">@stringfilter</span>
<span class="k">def</span> <span class="nf">do_strip</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
</pre></div>
<p>The wrapped function is created internally by the decorator, any positional
arguments are forwarded to the filter function. The first argument is always
the value already converted into a string.</p>
<p>If you're using Jinja with django and want to use the django filters in Jinja
have a look at the <a class="reference" href="./devrecipies.html">developer recipies</a> page.</p>
<p><em>new in Jinja 1.1</em> additionally to the <cite>stringfilter</cite> decorator there is now
a similar decorator that works exactly the same but does not convert values
to unicode:</p>
<div class="syntax"><pre><span class="k">from</span> <span class="nn">jinja.filters</span> <span class="k">import</span> <span class="n">simplefilter</span>
<span class="nd">@simplefilter</span>
<span class="k">def</span> <span class="nf">do_add</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">to_add</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span> <span class="o">+</span> <span class="n">to_add</span>
</pre></div>
</div>
</div>
</div>
</body>
<!-- generated on: 2007-11-17 18:18:05.145210
file id: filters -->
</html>
|