File: objects.html

package info (click to toggle)
jinja 1.2-3
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 1,412 kB
  • ctags: 1,171
  • sloc: python: 6,438; ansic: 397; makefile: 74
file content (222 lines) | stat: -rw-r--r-- 16,712 bytes parent folder | download | duplicates (2)
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <title>Global objects &mdash; 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">Global objects</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="#functions">Functions</a></li>
        
          <li><a href="#deferred-values">Deferred Values</a></li>
        
          <li><a href="#unsafe-methods-attributes">Unsafe Methods / Attributes</a></li>
        
          <li><a href="#bypassing-automatic-filtering">Bypassing Automatic Filtering</a></li>
        
        </ul>
      
    </div>
    
    <div id="contentwrapper">
      <p>This section covers the behavior of global objects in the Jinja namespace and
also the behavior of their attributes.</p>
<div class="section">
<h2><a id="functions" name="functions">Functions</a></h2>
<p><a class="reference" href="./filters.html">Filters</a> and <a class="reference" href="./tests.html">Tests</a> are special kind of functions you cannot call without
and argument. Global functions are different. Those are really just ordinary
python functions. You can register them on the global namespace easily:</p>
<div class="syntax"><pre><span class="k">def</span> <span class="nf">my_function</span><span class="p">():</span>
    <span class="k">return</span> <span class="p">[</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">,</span> <span class="mf">3</span><span class="p">]</span>

<span class="n">env</span><span class="o">.</span><span class="n">globals</span><span class="p">[</span><span class="s">&#39;my_function&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">my_function</span>
</pre></div>
<p>In the template you can not call it like this:</p>
<div class="syntax"><pre><span class="cp">{{</span> <span class="nv">my_function</span><span class="o">()</span> <span class="cp">}}</span><span class="x"></span>
</pre></div>
<p>Of couse you can pass any argument to it. But what if you want to access the
context or environment? In that case you have to decorate a function or mark
it (both work exactly the same, but the decorator way is probably nicer if you
have python &gt;= 2.4):</p>
<div class="syntax"><pre><span class="k">from</span> <span class="nn">cgi</span> <span class="k">import</span> <span class="n">escape</span>
<span class="k">from</span> <span class="nn">pprint</span> <span class="k">import</span> <span class="n">pformat</span>
<span class="k">from</span> <span class="nn">jinja.datastructure</span> <span class="k">import</span> <span class="n">contextcallable</span>

<span class="nd">@contextcallable</span>
<span class="k">def</span> <span class="nf">printcontext</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">result</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">context</span><span class="o">.</span><span class="n">to_dict</span><span class="p">():</span>
        <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&#39;&lt;tr&gt;&lt;th&gt;</span><span class="si">%s</span><span class="s">&lt;/th&gt;&lt;td&gt;</span><span class="si">%r</span><span class="s">&lt;/td&gt;&lt;/tr&gt;&#39;</span> <span class="o">%</span>
                      <span class="p">(</span><span class="n">escape</span><span class="p">(</span><span class="nb">unicode</span><span class="p">(</span><span class="n">key</span><span class="p">)),</span> <span class="n">escape</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="n">value</span><span class="p">))))</span>
    <span class="k">return</span> <span class="s">&#39;&lt;table&gt;</span><span class="si">%s</span><span class="s">&lt;/table&gt;&#39;</span> <span class="o">%</span> <span class="s">u&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</pre></div>
<p>If this function is registered in the environment namespace then and called
from the template it should return the content of the context as simple html
template. Of course you can modify the context too. For more informations about
the context object have a look at the <a class="reference" href="./contextenv.html">context object</a> documentation.</p>
<p>The new <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">call</span> <span class="pre">%}</span></tt> tag that exists with Jinja 1.1 onwards can not only
be used with Jinja macros but also with Python functions. If a template
designers uses the <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">call</span> <span class="pre">%}</span></tt> tag to call a function provided by the
application Jinja will call this function with a keyword argument called
<cite>caller</cite> which points to a <cite>function</cite>. If you call this function (optionally
with keyword arguments that appear in the context) you get a string back
that was the content of that block. This should explain this:</p>
<div class="syntax"><pre><span class="k">def</span> <span class="nf">make_dialog</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="n">body</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
    <span class="k">if</span> <span class="n">caller</span><span class="p">:</span>
        <span class="n">body</span> <span class="o">=</span> <span class="n">caller</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="n">title</span><span class="p">)</span>
    <span class="k">return</span> <span class="s">&#39;&lt;div class=&quot;dialog&quot;&gt;&lt;h2&gt;</span><span class="si">%s</span><span class="s">&lt;/h2&gt;</span><span class="si">%s</span><span class="s">&lt;/div&gt;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">body</span><span class="p">)</span>
</pre></div>
<p>This can be used like this in the template now:</p>
<div class="syntax"><pre><span class="cp">{%</span> <span class="k">call</span> <span class="nv">make_dialog</span><span class="o">(</span><span class="s1">&#39;Dialog Title&#39;</span><span class="o">)</span> <span class="cp">%}</span>
    This is the body of the dialog entitled &quot;<span class="cp">{{</span> <span class="nv">title</span> <span class="cp">}}</span>&quot;.
<span class="cp">{%</span> <span class="k">endcall</span> <span class="cp">%}</span>
</pre></div>
</div>
<div class="section">
<h2><a id="deferred-values" name="deferred-values">Deferred Values</a></h2>
<p>You can pass functions to the template that are called to provide values at
first access. Say you want to pass the list of recently written comments to
all templates. But not necessarily every template will render that. In that
situation you can create a function that returns that value and wrap it in an
<cite>Deferred</cite> object. The first time a template accesses the variable then the
<cite>Deferred</cite> object is resolved:</p>
<div class="syntax"><pre><span class="k">from</span> <span class="nn">jinja.datastructure</span> <span class="k">import</span> <span class="n">Deferred</span>
<span class="k">from</span> <span class="nn">yourapplication.models</span> <span class="k">import</span> <span class="n">Comments</span>

<span class="k">def</span> <span class="nf">get_recent_comments</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">name</span><span class="p">):</span>
    <span class="c"># do what ever you want here.</span>
    <span class="k">return</span> <span class="n">Comments</span><span class="o">.</span><span class="n">get_recent</span><span class="p">(</span><span class="mf">10</span><span class="p">)</span>

<span class="n">env</span><span class="o">.</span><span class="n">globals</span><span class="p">[</span><span class="s">&#39;recent_comments&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">Deferred</span><span class="p">(</span><span class="n">get_recent_comments</span><span class="p">)</span>
</pre></div>
<p>The function is always called with the same arguments. The first one is the
current environment, the second the context and the third is the name of the
variable. In this example <tt class="docutils literal"><span class="pre">recent_comments</span></tt>.</p>
<p>The value is cached until rendering/streaming finished.</p>
</div>
<div class="section">
<h2><a id="unsafe-methods-attributes" name="unsafe-methods-attributes">Unsafe Methods / Attributes</a></h2>
<p>Because Jinja is sandboxed it provides several ways to prevent unsafe attribute
access. You can mark both attributes and methods as unsafe:</p>
<div class="syntax"><pre><span class="k">from</span> <span class="nn">jinja.datastructure</span> <span class="k">import</span> <span class="n">unsafe</span>

<span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="o">...</span><span class="p">):</span>

    <span class="c"># just give access to a and b. Default is all</span>
    <span class="c"># note that this also disallows the functions from below.</span>
    <span class="c"># if you use jinja_allowed_attributes you don&#39;t have add the</span>
    <span class="c"># code below since methods are treated as attributes too.</span>
    <span class="n">jinja_allowed_attributes</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;a&#39;</span><span class="p">,</span> <span class="s">&#39;b&#39;</span><span class="p">]</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">...</span><span class="p">):</span>
        <span class="o">...</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="o">...</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">b</span> <span class="o">=</span> <span class="o">...</span>

    <span class="c"># python2.4 way of marking methods</span>
    <span class="nd">@unsafe</span>
    <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Save the model.&quot;&quot;&quot;</span>

    <span class="c"># python2.3 way for the same</span>
    <span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Delete the model.&quot;&quot;&quot;</span>
    <span class="n">delete</span><span class="o">.</span><span class="n">jinja_unsafe_call</span> <span class="o">=</span> <span class="bp">True</span>
</pre></div>
</div>
<div class="section">
<h2><a id="bypassing-automatic-filtering" name="bypassing-automatic-filtering">Bypassing Automatic Filtering</a></h2>
<p>With Jinja 1.1 it's possible to assign filters to any variable printed. Of
course there are ways to bypass that in order to make sure an object does
not get escaped etc.</p>
<p>In order to disable automatic filtering for an object you have to make
sure that it's either an subclass of <cite>unicode</cite> or implements a
<cite>__unicode__</cite> method. <cite>__str__</cite> will work too as long as the return value
only contains ASCII values. Additionally you have to add an attribute to
that object named <cite>jinja_no_finalization</cite> and set that to <cite>True</cite>.</p>
</div>

    </div>
  </div>
</body>
<!-- generated on: 2007-11-17 18:18:07.316227
     file id: objects -->
</html>