Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 1294 lines (953 sloc) 51.511 kb
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
1 =============================
2 Chapter 9: Advanced Templates
3 =============================
4
5 Although most of your interactions with Django's template language will be in
6 the role of template author, you may want to customize and extend the template
7 engine -- either to make it do something it doesn't already do, or to make your
8 job easier in some other way.
9
10 This chapter delves deep into the guts of Django's template system. It covers
11 what you need to know if you plan to extend the system or if you're just
12 curious about how it works. It also covers the auto-escaping feature, a
13 security measure you'll no doubt notice over time as you continue to use
14 Django.
15
16 If you're looking to use the Django template system as part of another
17 application (i.e., without the rest of the framework), make sure to read the
18 "Configuring the Template System in Standalone Mode" section later in the
19 chapter.
20
21 Template Language Review
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
22 ========================
23
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
24 First, let's quickly review a number of terms introduced in Chapter 4:
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
25
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
26 * A *template* is a text document, or a normal Python string, that is
27 marked up using the Django template language. A template can contain
28 template tags and variables.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
29
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
30 * A *template tag* is a symbol within a template that does something. This
31 definition is deliberately vague. For example, a template tag can produce
32 content, serve as a control structure (an ``if`` statement or ``for``
33 loop), grab content from a database, or enable access to other template
34 tags.
35
36 Template tags are surrounded by ``{%`` and ``%}``::
37
38 {% if is_logged_in %}
39 Thanks for logging in!
40 {% else %}
41 Please log in.
42 {% endif %}
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
43
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
44 * A *variable* is a symbol within a template that outputs a value.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
45
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
46 Variable tags are surrounded by ``{{`` and ``}}``::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
47
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
48 My first name is {{ first_name }}. My last name is {{ last_name }}.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
49
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
50 * A *context* is a name -> value mapping (similar to a Python
51 dictionary) that is passed to a template.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
52
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
53 * A template *renders* a context by replacing the variable "holes" with
54 values from the context and executing all template tags.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
55
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
56 For more details about the basics of these terms, refer back to Chapter 4.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
57
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
58 The rest of this chapter discusses ways of extending the template engine. First,
59 though, let's take a quick look at a few internals left out of Chapter 4 for
60 simplicity.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
61
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
62 RequestContext and Context Processors
63 =====================================
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
64
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
65 When rendering a template, you need a context. Usually this is an instance of
66 ``django.template.Context``, but Django also comes with a special subclass,
67 ``django.template.RequestContext``, that acts slightly differently.
68 ``RequestContext`` adds a bunch of variables to your template context by
69 default -- things like the ``HttpRequest`` object or information about the
70 currently logged-in user.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
71
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
72 Use ``RequestContext`` when you don't want to have to specify the same set of
73 variables in a series of templates. For example, consider these two views::
74
75 from django.template import loader, Context
76
77 def view_1(request):
78 # ...
79 t = loader.get_template('template1.html')
80 c = Context({
81 'app': 'My app',
82 'user': request.user,
83 'ip_address': request.META['REMOTE_ADDR'],
84 'message': 'I am view 1.'
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
85 })
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
86 return t.render(c)
87
88 def view_2(request):
89 # ...
90 t = loader.get_template('template2.html')
91 c = Context({
92 'app': 'My app',
93 'user': request.user,
94 'ip_address': request.META['REMOTE_ADDR'],
95 'message': 'I am the second view.'
96 })
97 return t.render(c)
98
99 (Note that we're deliberately *not* using the ``render_to_response()`` shortcut
100 in these examples -- we're manually loading the templates, constructing the
101 context objects and rendering the templates. We're "spelling out" all of the
102 steps for the purpose of clarity.)
103
104 Each view passes the same three variables -- ``app``, ``user`` and
105 ``ip_address`` -- to its template. Wouldn't it be nice if we could remove that
106 redundancy?
107
108 ``RequestContext`` and **context processors** were created to solve this
109 problem. Context processors let you specify a number of variables that get set
110 in each context automatically -- without you having to specify the variables in
111 each ``render_to_response()`` call. The catch is that you have to use
112 ``RequestContext`` instead of ``Context`` when you render a template.
113
114 The most low-level way of using context processors is to create some processors
115 and pass them to ``RequestContext``. Here's how the above example could be
116 written with context processors::
117
118 from django.template import loader, RequestContext
119
120 def custom_proc(request):
121 "A context processor that provides 'app', 'user' and 'ip_address'."
122 return {
123 'app': 'My app',
124 'user': request.user,
125 'ip_address': request.META['REMOTE_ADDR']
126 }
127
128 def view_1(request):
129 # ...
130 t = loader.get_template('template1.html')
131 c = RequestContext(request, {'message': 'I am view 1.'},
132 processors=[custom_proc])
133 return t.render(c)
134
135 def view_2(request):
136 # ...
137 t = loader.get_template('template2.html')
138 c = RequestContext(request, {'message': 'I am the second view.'},
139 processors=[custom_proc])
140 return t.render(c)
141
142 Let's step through this code:
143
144 * First, we define a function ``custom_proc``. This is a context processor
145 -- it takes an ``HttpRequest`` object and returns a dictionary of
146 variables to use in the template context. That's all it does.
147
148 * We've changed the two view functions to use ``RequestContext`` instead
149 of ``Context``. There are two differences in how the context is
150 constructed. One, ``RequestContext`` requires the first argument to be an
151 ``HttpRequest`` object -- the one that was passed into the view function
152 in the first place (``request``). Two, ``RequestContext`` takes an
153 optional ``processors`` argument, which is a list or tuple of context
154 processor functions to use. Here, we pass in ``custom_proc``, the custom
155 processor we defined above.
156
157 * Each view no longer has to include ``app``, ``user`` or ``ip_address`` in
158 its context construction, because those are provided by ``custom_proc``.
159
160 * Each view *still* has the flexibility to introduce any custom template
161 variables it might need. In this example, the ``message`` template
162 variable is set differently in each view.
163
164 In Chapter 4, we introduced the ``render_to_response()`` shortcut, which saves
165 you from having to call ``loader.get_template()``, then create a ``Context``,
166 then call the ``render()`` method on the template. In order to demonstrate the
167 lower-level workings of context processors, the above examples didn't use
168 ``render_to_response()``, . But it's possible -- and preferable -- to use
169 context processors with ``render_to_response()``. Do this with the
170 ``context_instance`` argument, like so::
171
172 from django.shortcuts import render_to_response
173 from django.template import RequestContext
174
175 def custom_proc(request):
176 "A context processor that provides 'app', 'user' and 'ip_address'."
177 return {
178 'app': 'My app',
179 'user': request.user,
180 'ip_address': request.META['REMOTE_ADDR']
181 }
182
183 def view_1(request):
184 # ...
185 return render_to_response('template1.html',
186 {'message': 'I am view 1.'},
187 context_instance=RequestContext(request, processors=[custom_proc]))
188
189 def view_2(request):
190 # ...
191 return render_to_response('template2.html',
192 {'message': 'I am the second view.'},
193 context_instance=RequestContext(request, processors=[custom_proc]))
194
195 Here, we've trimmed down each view's template rendering code to a single
196 (wrapped) line.
197
198 This is an improvement, but, evaluating the conciseness of this code, we have
199 to admit we're now almost overdosing on the *other* end of the spectrum. We've
200 removed redundancy in data (our template variables) at the cost of adding
201 redundancy in code (in the ``processors`` call). Using context processors
202 doesn't save you much typing if you have to type ``processors`` all the time.
203
204 For that reason, Django provides support for *global* context processors. The
205 ``TEMPLATE_CONTEXT_PROCESSORS`` setting (in your ``settings.py``) designates
206 which context processors should *always* be applied to ``RequestContext``. This
207 removes the need to specify ``processors`` each time you use
208 ``RequestContext``.
209
210 By default, ``TEMPLATE_CONTEXT_PROCESSORS`` is set to the following::
211
212 TEMPLATE_CONTEXT_PROCESSORS = (
213 'django.core.context_processors.auth',
214 'django.core.context_processors.debug',
215 'django.core.context_processors.i18n',
216 'django.core.context_processors.media',
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
217 )
218
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
219 This setting is a tuple of callables that use the same interface as our
220 ``custom_proc`` function above -- functions that take a request object as their
221 argument and return a dictionary of items to be merged into the context. Note
222 that the values in ``TEMPLATE_CONTEXT_PROCESSORS`` are specified as *strings*,
223 which means the processors are required to be somewhere on your Python path
224 (so you can refer to them from the setting).
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
225
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
226 Each processor is applied in order. That is, if one processor adds a variable
227 to the context and a second processor adds a variable with the same name, the
228 second will override the first.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
229
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
230 Django provides a number of simple context processors, including the ones that
231 are enabled by default:
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
232
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
233 django.core.context_processors.auth
234 -----------------------------------
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
235
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
236 If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
237 ``RequestContext`` will contain these variables:
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
238
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
239 * ``user``: A ``django.contrib.auth.models.User`` instance representing the
240 current logged-in user (or an ``AnonymousUser`` instance, if the client
241 isn't logged in).
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
242
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
243 * ``messages``: A list of messages (as strings) for the current logged-in
244 user. Behind the scenes, this variable calls
245 ``request.user.get_and_delete_messages()`` for every request. That method
246 collects the user's messages and deletes them from the database.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
247
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
248 * ``perms``: An instance of ``django.core.context_processors.PermWrapper``,
249 which represents the permissions the current logged-in user has.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
250
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
251 See Chapter 14 for more information on users, permissions, and messages.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
252
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
253 django.core.context_processors.debug
254 ------------------------------------
255
256 This processor pushes debugging information down to the template layer. If
257 ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
258 ``RequestContext`` will contain these variables:
259
260 * ``debug``: The value of your ``DEBUG`` setting (either ``True`` or
261 ``False``). You can use this variable in templates to test whether you're
262 in debug mode.
263
264 * ``sql_queries``: A list of ``{'sql': ..., 'time': ...}`` dictionaries
265 representing every SQL query that has happened so far during the request
266 and how long it took. The list is in the order in which the queries were
267 issued.
268
269 Because debugging information is sensitive, this context processor will only
270 add variables to the context if both of the following conditions are true:
271
272 * The ``DEBUG`` setting is ``True``.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
273
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
274 * The request came from an IP address in the ``INTERNAL_IPS`` setting.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
275
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
276 Astute readers will notice that the ``debug`` template variable will never have
277 the value ``False`` because, if ``DEBUG`` is ``False``, then the ``debug``
278 template variable won't be populated in the first place.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
279
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
280 django.core.context_processors.i18n
281 -----------------------------------
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
282
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
283 If this processor is enabled, every ``RequestContext`` will contain these
284 variables:
285
286 * ``LANGUAGES``: The value of the ``LANGUAGES`` setting.
287
288 * ``LANGUAGE_CODE``: ``request.LANGUAGE_CODE`` if it exists; otherwise, the
289 value of the ``LANGUAGE_CODE`` setting.
290
291 Appendix D provides more information about these two settings.
292
293 django.core.context_processors.request
294 --------------------------------------
295
296 If this processor is enabled, every ``RequestContext`` will contain a variable
297 ``request``, which is the current ``HttpRequest`` object. Note that this
298 processor is not enabled by default; you have to activate it.
299
300 You might want to use this if you find your templates needing to access
301 attributes of the current ``HttpRequest`` such as the IP address::
302
303 {{ request.REMOTE_ADDR }}
304
305 Guidelines for Writing Your Own Context Processors
306 --------------------------------------------------
307
308 Here are a few tips for rolling your own:
309
310 * Make each context processor responsible for the smallest subset of
311 functionality possible. It's easy to use multiple processors, so you
312 might as well split functionality into logical pieces for future reuse.
313
314 * Keep in mind that any context processor in ``TEMPLATE_CONTEXT_PROCESSORS``
315 will be available in *every* template powered by that settings file, so
316 try to pick variable names that are unlikely to conflict with variable
317 names your templates might be using independently. As variable names are
318 case-sensitive, it's not a bad idea to use all caps for variables that a
319 processor provides.
320
321 * It doesn't matter where on the filesystem they live, as long as they're
322 on your Python path so you can point to them from the
323 ``TEMPLATE_CONTEXT_PROCESSORS`` setting. With that said, the convention
324 is to save them in a file called ``context_processors.py`` within your
325 app or project.
326
327 Automatic HTML Escaping
328 =======================
329
330 When generating HTML from templates, there's always a risk that a variable will
331 include characters that affect the resulting HTML. For example, consider this
332 template fragment::
333
334 Hello, {{ name }}.
335
336 At first, this seems like a harmless way to display a user's name, but consider
337 what would happen if the user entered his name as this::
338
339 <script>alert('hello')</script>
340
341 With this name value, the template would be rendered as::
342
343 Hello, <script>alert('hello')</script>
344
345 ...which means the browser would pop-up a JavaScript alert box!
346
347 Similarly, what if the name contained a ``'<'`` symbol, like this?
348
349 <b>username
350
351 That would result in a rendered template like this::
352
353 Hello, <b>username
354
355 ...which, in turn, would result in the remainder of the Web page being bolded!
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
356
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
357 Clearly, user-submitted data shouldn't be trusted blindly and inserted directly
358 into your Web pages, because a malicious user could use this kind of hole to
359 do potentially bad things. This type of security exploit is called a
360 Cross Site Scripting (XSS) attack. (For more on security, see Chapter 20.)
361
362 To avoid this problem, you have two options:
363
364 * One, you can make sure to run each untrusted variable through the
365 ``escape`` filter, which converts potentially harmful HTML characters to
366 unharmful ones. This was the default solution in Django for its first few
367 years, but the problem is that it puts the onus on *you*, the developer /
368 template author, to ensure you're escaping everything. It's easy to forget
369 to escape data.
370
371 * Two, you can take advantage of Django's automatic HTML escaping. The
372 remainder of this section describes how auto-escaping works.
373
374 By default in Django, every template automatically escapes the output
375 of every variable tag. Specifically, these five characters are
376 escaped:
377
378 * ``<`` is converted to ``&lt;``
379 * ``>`` is converted to ``&gt;``
380 * ``'`` (single quote) is converted to ``&#39;``
381 * ``"`` (double quote) is converted to ``&quot;``
382 * ``&`` is converted to ``&amp;``
383
384 Again, we stress that this behavior is on by default. If you're using Django's
385 template system, you're protected.
386
387 How to Turn it Off
388 ------------------
389
390 If you don't want data to be auto-escaped, on a per-site, per-template level or
391 per-variable level, you can turn it off in several ways.
392
393 Why would you want to turn it off? Because sometimes, template variables
394 contain data that you *intend* to be rendered as raw HTML, in which case you
395 don't want their contents to be escaped. For example, you might store a blob of
396 trusted HTML in your database and want to embed that directly into your
397 template. Or, you might be using Django's template system to produce text that
398 is *not* HTML -- like an e-mail message, for instance.
399
400 For Individual Variables
401 ~~~~~~~~~~~~~~~~~~~~~~~~
402
403 To disable auto-escaping for an individual variable, use the ``safe`` filter::
404
405 This will be escaped: {{ data }}
406 This will not be escaped: {{ data|safe }}
407
408 Think of *safe* as shorthand for *safe from further escaping* or *can be
409 safely interpreted as HTML*. In this example, if ``data`` contains ``'<b>'``,
410 the output will be::
411
412 This will be escaped: &lt;b&gt;
413 This will not be escaped: <b>
414
415 For Template Blocks
416 ~~~~~~~~~~~~~~~~~~~
417
418 To control auto-escaping for a template, wrap the template (or just a
419 particular section of the template) in the ``autoescape`` tag, like so::
420
421 {% autoescape off %}
422 Hello {{ name }}
423 {% endautoescape %}
424
425 The ``autoescape`` tag takes either ``on`` or ``off`` as its argument. At
426 times, you might want to force auto-escaping when it would otherwise be
427 disabled. Here is an example template::
428
429 Auto-escaping is on by default. Hello {{ name }}
430
431 {% autoescape off %}
432 This will not be auto-escaped: {{ data }}.
433
434 Nor this: {{ other_data }}
435 {% autoescape on %}
436 Auto-escaping applies again: {{ name }}
437 {% endautoescape %}
438 {% endautoescape %}
439
440 The auto-escaping tag passes its effect on to templates that extend the
441 current one as well as templates included via the ``include`` tag, just like
442 all block tags. For example::
443
444 # base.html
445
446 {% autoescape off %}
447 <h1>{% block title %}{% endblock %}</h1>
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
448 {% block content %}
449 {% endblock %}
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
450 {% endautoescape %}
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
451
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
452 # child.html
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
453
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
454 {% extends "base.html" %}
455 {% block title %}This & that{% endblock %}
456 {% block content %}{{ greeting }}{% endblock %}
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
457
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
458 Because auto-escaping is turned off in the base template, it will also be
459 turned off in the child template, resulting in the following rendered
460 HTML when the ``greeting`` variable contains the string ``<b>Hello!</b>``::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
461
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
462 <h1>This & that</h1>
463 <b>Hello!</b>
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
464
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
465 Notes
466 -----
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
467
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
468 Generally, template authors don't need to worry about auto-escaping very much.
469 Developers on the Python side (people writing views and custom filters) need to
470 think about the cases in which data shouldn't be escaped, and mark data
471 appropriately, so things work in the template.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
472
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
473 If you're creating a template that might be used in situations where you're
474 not sure whether auto-escaping is enabled, then add an ``escape`` filter to any
475 variable that needs escaping. When auto-escaping is on, there's no danger of
476 the ``escape`` filter *double-escaping* data -- the ``escape`` filter does not
477 affect auto-escaped variables.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
478
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
479 Automatic Escaping of String Literals in Filter Arguments
480 ---------------------------------------------------------
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
481
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
482 As we mentioned earlier, filter arguments can be strings::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
483
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
484 {{ data|default:"This is a string literal." }}
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
485
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
486 All string literals are inserted *without* any automatic escaping into the
487 template -- they act as if they were all passed through the ``safe`` filter.
488 The reasoning behind this is that the template author is in control of what
489 goes into the string literal, so they can make sure the text is correctly
490 escaped when the template is written.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
491
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
492 This means you would write ::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
493
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
494 {{ data|default:"3 &lt; 2" }}
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
495
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
496 ...rather than ::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
497
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
498 {{ data|default:"3 < 2" }} <-- Bad! Don't do this.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
499
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
500 This doesn't affect what happens to data coming from the variable itself.
501 The variable's contents are still automatically escaped, if necessary, because
502 they're beyond the control of the template author.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
503
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
504 Inside Template Loading
505 =======================
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
506
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
507 Generally, you'll store templates in files on your filesystem, but you can use
508 custom *template loaders* to load templates from other sources.
509
510 Django has two ways to load templates:
511
512 * ``django.template.loader.get_template(template_name)``: ``get_template``
513 returns the compiled template (a ``Template`` object) for the template
514 with the given name. If the template doesn't exist, a
515 ``TemplateDoesNotExist`` exception will be raised.
516
517 * ``django.template.loader.select_template(template_name_list)``:
518 ``select_template`` is just like ``get_template``, except it takes a list
519 of template names. Of the list, it returns the first template that exists.
520 If none of the templates exist, a ``TemplateDoesNotExist`` exception will
521 be raised.
522
523 As covered in Chapter 4, each of these functions by default uses your
524 ``TEMPLATE_DIRS`` setting to load templates. Internally, however, these
525 functions actually delegate to a template loader for the heavy lifting.
526
527 Some of loaders are disabled by default, but you can activate them by editing
528 the ``TEMPLATE_LOADERS`` setting. ``TEMPLATE_LOADERS`` should be a tuple of
529 strings, where each string represents a template loader. These template loaders
530 ship with Django:
531
532 * ``django.template.loaders.filesystem.load_template_source``: This loader
533 loads templates from the filesystem, according to ``TEMPLATE_DIRS``. It is
534 enabled by default.
535
536 * ``django.template.loaders.app_directories.load_template_source``: This
537 loader loads templates from Django applications on the filesystem. For
538 each application in ``INSTALLED_APPS``, the loader looks for a
539 ``templates`` subdirectory. If the directory exists, Django looks for
540 templates there.
541
542 This means you can store templates with your individual applications,
543 making it easy to distribute Django applications with default templates.
544 For example, if ``INSTALLED_APPS`` contains ``('myproject.polls',
545 'myproject.music')``, then ``get_template('foo.html')`` will look for
546 templates in this order:
547
548 * ``/path/to/myproject/polls/templates/foo.html``
549 * ``/path/to/myproject/music/templates/foo.html``
550
551 Note that the loader performs an optimization when it is first imported:
552 it caches a list of which ``INSTALLED_APPS`` packages have a ``templates``
553 subdirectory.
554
555 This loader is enabled by default.
556
557 * ``django.template.loaders.eggs.load_template_source``: This loader is just
558 like ``app_directories``, except it loads templates from Python eggs
559 rather than from the filesystem. This loader is disabled by default;
560 you'll need to enable it if you're using eggs to distribute your
561 application. (Python eggs are a way of compressing Python code into a
562 single file.)
563
564 Django uses the template loaders in order according to the ``TEMPLATE_LOADERS``
565 setting. It uses each loader until a loader finds a match.
566
567 Extending the Template System
568 =============================
569
570 Now that you understand a bit more about the internals of the template system,
571 let's look at how to extend the system with custom code.
572
573 Most template customization comes in the form of custom template tags and/or
574 filters. Although the Django template language comes with many built-in tags and
575 filters, you'll probably assemble your own libraries of tags and filters that
576 fit your own needs. Fortunately, it's quite easy to define your own
577 functionality.
578
579 Creating a Template Library
580 ---------------------------
581
582 Whether you're writing custom tags or filters, the first thing to do is to
583 create a **template library** -- a small bit of infrastructure Django can hook
584 into.
585
586 Creating a template library is a two-step process:
587
588 * First, decide which Django application should house the template library.
589 If you've created an app via ``manage.py startapp``, you can put it in
590 there, or you can create another app solely for the template library.
591 We'd recommend the latter, because your filters might be useful to you
592 in future projects.
593
594 Whichever route you take, make sure to add the app to your
595 ``INSTALLED_APPS`` setting. We'll explain this shortly.
596
597 * Second, create a ``templatetags`` directory in the appropriate Django
598 application's package. It should be on the same level as ``models.py``,
599 ``views.py``, and so forth. For example::
600
601 books/
602 __init__.py
603 models.py
604 templatetags/
605 views.py
606
607 Create two empty files in the ``templatetags`` directory: an ``__init__.py``
608 file (to indicate to Python that this is a package containing Python code)
609 and a file that will contain your custom tag/filter definitions. The name
610 of the latter file is what you'll use to load the tags later. For example,
611 if your custom tags/filters are in a file called ``poll_extras.py``, you'd
612 write the following in a template::
613
614 {% load poll_extras %}
615
616 The ``{% load %}`` tag looks at your ``INSTALLED_APPS`` setting and only
617 allows the loading of template libraries within installed Django
618 applications. This is a security feature; it allows you to host Python
619 code for many template libraries on a single computer without enabling
620 access to all of them for every Django installation.
621
622 If you write a template library that isn't tied to any particular models/views,
623 it's valid and quite normal to have a Django application package that contains
624 only a ``templatetags`` package. There's no limit on how many modules you put in
625 the ``templatetags`` package. Just keep in mind that a ``{% load %}`` statement
626 will load tags/filters for the given Python module name, not the name of the
627 application.
628
629 Once you've created that Python module, you'll just have to write a bit of
630 Python code, depending on whether you're writing filters or tags.
631
632 To be a valid tag library, the module must contain a module-level variable named
633 ``register`` that is an instance of ``template.Library``. This is the data
634 structure in which all the tags and filters are registered. So, near the top of
635 your module, insert the following::
636
637 from django import template
638
639 register = template.Library()
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
640
641 .. note::
642
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
643 For a fine selection of examples, read the source code for Django's default
644 filters and tags. They're in ``django/template/defaultfilters.py`` and
645 ``django/template/defaulttags.py``, respectively. Some applications in
646 ``django.contrib`` also contain template libraries.
647
648 Once you've created this ``register`` variable, you'll use it to create template
649 filters and tags.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
650
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
651 Writing Custom Template Filters
652 -------------------------------
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
653
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
654 Custom filters are just Python functions that take one or two arguments:
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
655
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
656 * The value of the variable (input)
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
657
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
658 * The value of the argument, which can have a default value or be left out
659 altogether
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
660
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
661 For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
662 passed the contents of the variable ``var`` and the argument ``"bar"``.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
663
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
664 Filter functions should always return something. They shouldn't raise
665 exceptions, and they should fail silently. If there's an error, they should
666 return either the original input or an empty string, whichever makes more sense.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
667
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
668 Here's an example filter definition::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
669
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
670 def cut(value, arg):
671 "Removes all values of arg from the given string"
672 return value.replace(arg, '')
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
673
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
674 And here's an example of how that filter would be used to cut spaces from a
675 variable's value::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
676
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
677 {{ somevariable|cut:" " }}
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
678
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
679 Most filters don't take arguments. In this case, just leave the argument out
680 of your function::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
681
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
682 def lower(value): # Only one argument.
683 "Converts a string into all lowercase"
684 return value.lower()
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
685
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
686 When you've written your filter definition, you need to register it with your
687 ``Library`` instance, to make it available to Django's template language::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
688
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
689 register.filter('cut', cut)
690 register.filter('lower', lower)
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
691
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
692 .. SL Tested ok
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
693
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
694 The ``Library.filter()`` method takes two arguments:
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
695
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
696 * The name of the filter (a string)
697 * The filter function itself
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
698
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
699 If you're using Python 2.4 or above, you can use ``register.filter()`` as a
700 decorator instead::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
701
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
702 @register.filter(name='cut')
703 def cut(value, arg):
704 return value.replace(arg, '')
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
705
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
706 @register.filter
707 def lower(value):
708 return value.lower()
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
709
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
710 .. SL Tested ok
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
711
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
712 If you leave off the ``name`` argument, as in the second example, Django
713 will use the function's name as the filter name.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
714
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
715 Here, then, is a complete template library example, supplying the ``cut`` filter::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
716
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
717 from django import template
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
718
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
719 register = template.Library()
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
720
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
721 @register.filter(name='cut')
722 def cut(value, arg):
723 return value.replace(arg, '')
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
724
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
725 .. SL Tested ok
726
727 Writing Custom Template Tags
728 ----------------------------
729
730 Tags are more complex than filters, because tags can do nearly anything.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
731
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
732 Chapter 4 describes how the template system works in a two-step process:
733 compiling and rendering. To define a custom template tag, you need to tell
734 Django how to manage *both* of these steps when it gets to your tag.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
735
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
736 When Django compiles a template, it splits the raw template text into
737 *nodes*. Each node is an instance of ``django.template.Node`` and has
738 a ``render()`` method. Thus, a compiled template is simply a list of ``Node``
739 objects. For example, consider this template::
740
741 Hello, {{ person.name }}.
742
743 {% ifequal name.birthday today %}
744 Happy birthday!
745 {% else %}
746 Be sure to come back on your birthday
747 for a splendid surprise message.
748 {% endifequal %}
749
750 In compiled template form, this template is represented as this list of
751 nodes:
752
753 * Text node: ``"Hello, "``
754 * Variable node: ``person.name``
755 * Text node: ``".\n\n"``
756 * IfEqual node: ``name.birthday`` and ``today``
757
758 When you call ``render()`` on a compiled template, the template calls
759 ``render()`` on each ``Node`` in its node list, with the given context. The
760 results are all concatenated together to form the output of the template. Thus,
761 to define a custom template tag, you specify how the raw template tag is
762 converted into a ``Node`` (the compilation function) and what the node's
763 ``render()`` method does.
764
765 In the sections that follow, we cover all the steps in writing a custom tag.
766
767 Writing the Compilation Function
768 --------------------------------
769
770 For each template tag the parser encounters, it calls a Python function with
771 the tag contents and the parser object itself. This function is responsible for
772 returning a ``Node`` instance based on the contents of the tag.
773
774 For example, let's write a template tag, ``{% current_time %}``, that displays
775 the current date/time, formatted according to a parameter given in the tag, in
776 ``strftime`` syntax (see ``http://www.djangoproject.com/r/python/strftime/``).
777 It's a good idea to decide the tag syntax before anything else. In our case,
778 let's say the tag should be used like this::
779
780 <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
781
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
782 .. note::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
783
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
784 Yes, this template tag is redundant--Django's default ``{% now %}`` tag does
785 the same task with simpler syntax. This template tag is presented here just
786 for example purposes.
787
788 The parser for this function should grab the parameter and create a ``Node``
789 object::
790
791 from django import template
792
793 register = template.Library()
794
795 def do_current_time(parser, token):
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
796 try:
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
797 # split_contents() knows not to split quoted strings.
798 tag_name, format_string = token.split_contents()
799 except ValueError:
800 msg = '%r tag requires a single argument' % token.split_contents()[0]
801 raise template.TemplateSyntaxError(msg)
802 return CurrentTimeNode(format_string[1:-1])
803
804 There's a lot going here:
805
806 * Each template tag compilation function takes two arguments, ``parser``
807 and ``token``. ``parser`` is the template parser object. We don't use it
808 in this example. ``token`` is the token currently being parsed by the
809 parser.
810
811 * ``token.contents`` is a string of the raw contents of the tag. In our
812 example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
813
814 * The ``token.split_contents()`` method separates the arguments on spaces
815 while keeping quoted strings together. Avoid using
816 ``token.contents.split()`` (which just uses Python's standard
817 string-splitting semantics). It's not as robust, as it naively splits on
818 *all* spaces, including those within quoted strings.
819
820 * This function is responsible for raising
821 ``django.template.TemplateSyntaxError``, with helpful messages, for any
822 syntax error.
823
824 * Don't hard-code the tag's name in your error messages, because that
825 couples the tag's name to your function. ``token.split_contents()[0]``
826 will *always* be the name of your tag -- even when the tag has no
827 arguments.
828
829 * The function returns a ``CurrentTimeNode`` (which we'll create shortly)
830 containing everything the node needs to know about this tag. In this
831 case, it just passes the argument ``"%Y-%m-%d %I:%M %p"``. The
832 leading and trailing quotes from the template tag are removed with
833 ``format_string[1:-1]``.
834
835 * Template tag compilation functions *must* return a ``Node`` subclass;
836 any other return value is an error.
837
838 Writing the Template Node
839 -------------------------
840
841 The second step in writing custom tags is to define a ``Node`` subclass that
842 has a ``render()`` method. Continuing the preceding example, we need to define
843 ``CurrentTimeNode``::
844
845 import datetime
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
846
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
847 class CurrentTimeNode(template.Node):
848 def __init__(self, format_string):
849 self.format_string = str(format_string)
850
851 def render(self, context):
852 now = datetime.datetime.now()
853 return now.strftime(self.format_string)
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
854
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
855 These two functions (``__init__()`` and ``render()``) map directly to the two
856 steps in template processing (compilation and rendering). Thus, the
857 initialization function only needs to store the format string for later use,
858 and the ``render()`` function does the real work.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
859
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
860 Like template filters, these rendering functions should fail silently instead
861 of raising errors. The only time that template tags are allowed to raise
862 errors is at compilation time.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
863
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
864 Registering the Tag
865 -------------------
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
866
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
867 Finally, you need to register the tag with your module's ``Library`` instance.
868 Registering custom tags is very similar to registering custom filters (as
869 explained above). Just instantiate a ``template.Library`` instance and call
870 its ``tag()`` method. For example::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
871
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
872 register.tag('current_time', do_current_time)
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
873
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
874 The ``tag()`` method takes two arguments:
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
875
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
876 * The name of the template tag (string).
877 * The compilation function.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
878
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
879 As with filter registration, it is also possible to use ``register.tag`` as a
880 decorator in Python 2.4 and above::
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
881
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
882 @register.tag(name="current_time")
883 def do_current_time(parser, token):
884 # ...
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
885
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
886 @register.tag
887 def shout(parser, token):
888 # ...
889
890 If you leave off the ``name`` argument, as in the second example, Django
891 will use the function's name as the tag name.
892
893 Setting a Variable in the Context
894 ---------------------------------
895
896 The previous section's example simply returned a value. Often it's useful to set
897 template variables instead of returning values. That way, template authors can
898 just use the variables that your template tags set.
899
900 To set a variable in the context, use dictionary assignment on the context
901 object in the ``render()`` method. Here's an updated version of
902 ``CurrentTimeNode`` that sets a template variable, ``current_time``, instead of
903 returning it::
904
905 class CurrentTimeNode2(template.Node):
906 def __init__(self, format_string):
907 self.format_string = str(format_string)
908
909 def render(self, context):
910 now = datetime.datetime.now()
911 context['current_time'] = now.strftime(self.format_string)
912 return ''
913
914 (We'll leave the creation of a ``do_current_time2`` function, plus the
915 registration of that function to a ``current_time2`` template tag, as exercises
916 for the reader.)
917
918 Note that ``render()`` returns an empty string. ``render()`` should always
919 return a string, so if all the template tag does is set a variable,
920 ``render()`` should return an empty string.
921
922 Here's how you'd use this new version of the tag::
923
924 {% current_time2 "%Y-%M-%d %I:%M %p" %}
925 <p>The time is {{ current_time }}.</p>
926
927 But there's a problem with ``CurrentTimeNode2``: the variable name
928 ``current_time`` is hard-coded. This means you'll need to make sure your
929 template doesn't use ``{{ current_time }}`` anywhere else, because
930 ``{% current_time2 %}`` will blindly overwrite that variable's value.
931
932 A cleaner solution is to make the template tag specify the name of the variable
933 to be set, like so::
934
935 {% get_current_time "%Y-%M-%d %I:%M %p" as my_current_time %}
936 <p>The current time is {{ my_current_time }}.</p>
937
938 To do so, you'll need to refactor both the compilation function and the
939 ``Node`` class, as follows::
940
941 import re
942
943 class CurrentTimeNode3(template.Node):
944 def __init__(self, format_string, var_name):
945 self.format_string = str(format_string)
946 self.var_name = var_name
947
948 def render(self, context):
949 now = datetime.datetime.now()
950 context[self.var_name] = now.strftime(self.format_string)
951 return ''
952
953 def do_current_time(parser, token):
954 # This version uses a regular expression to parse tag contents.
955 try:
956 # Splitting by None == splitting by spaces.
957 tag_name, arg = token.contents.split(None, 1)
958 except ValueError:
959 msg = '%r tag requires arguments' % token.contents[0]
960 raise template.TemplateSyntaxError(msg)
961
962 m = re.search(r'(.*?) as (\w+)', arg)
963 if m:
964 fmt, var_name = m.groups()
965 else:
966 msg = '%r tag had invalid arguments' % tag_name
967 raise template.TemplateSyntaxError(msg)
968
969 if not (fmt[0] == fmt[-1] and fmt[0] in ('"', "'")):
970 msg = "%r tag's argument should be in quotes" % tag_name
971 raise template.TemplateSyntaxError(msg)
972
973 return CurrentTimeNode3(fmt[1:-1], var_name)
974
975 Now ``do_current_time()`` passes the format string and the variable name to
976 ``CurrentTimeNode3``.
977
978 Parsing Until Another Template Tag
979 ----------------------------------
980
981 Template tags can work as blocks containing other tags (like ``{% if %}``,
982 ``{% for %}``, etc.). To create a template tag like this, use
983 ``parser.parse()`` in your compilation function.
984
985 Here's how the standard ``{% comment %}`` tag is implemented::
986
987 def do_comment(parser, token):
988 nodelist = parser.parse(('endcomment',))
989 parser.delete_first_token()
990 return CommentNode()
991
992 class CommentNode(template.Node):
993 def render(self, context):
994 return ''
995
996 .. SL Tested ok
997
998 ``parser.parse()`` takes a tuple of names of template tags to parse until. It
999 returns an instance of ``django.template.NodeList``, which is a list of all
1000 ``Node`` objects that the parser encountered *before* it encountered any of
1001 the tags named in the tuple.
1002
1003 So in the preceding example, ``nodelist`` is a list of all nodes between
1004 ``{% comment %}`` and ``{% endcomment %}``, not counting ``{% comment %}`` and
1005 ``{% endcomment %}`` themselves.
1006
1007 After ``parser.parse()`` is called, the parser hasn't yet "consumed" the ``{%
1008 endcomment %}`` tag, so the code needs to explicitly call
1009 ``parser.delete_first_token()`` to prevent that tag from being processed
1010 twice.
1011
1012 Then ``CommentNode.render()`` simply returns an empty string. Anything
1013 between ``{% comment %}`` and ``{% endcomment %}`` is ignored.
1014
1015 Parsing Until Another Template Tag and Saving Contents
1016 ------------------------------------------------------
1017
1018 In the previous example, ``do_comment()`` discarded everything between
1019 ``{% comment %}`` and ``{% endcomment %}``. It's also
1020 possible to do something with the code between template tags instead.
1021
1022 For example, here's a custom template tag, ``{% upper %}``, that capitalizes
1023 everything between itself and ``{% endupper %}``::
1024
1025 {% upper %}
1026 This will appear in uppercase, {{ user_name }}.
1027 {% endupper %}
1028
1029 As in the previous example, we'll use ``parser.parse()``. This time, we
1030 pass the resulting ``nodelist`` to ``Node``::
1031
1032 def do_upper(parser, token):
1033 nodelist = parser.parse(('endupper',))
1034 parser.delete_first_token()
1035 return UpperNode(nodelist)
1036
1037 class UpperNode(template.Node):
1038 def __init__(self, nodelist):
1039 self.nodelist = nodelist
1040
1041 def render(self, context):
1042 output = self.nodelist.render(context)
1043 return output.upper()
1044
1045 .. SL Tested ok
1046
1047 The only new concept here is ``self.nodelist.render(context)`` in
1048 ``UpperNode.render()``. This simply calls ``render()`` on each ``Node`` in the
1049 node list.
1050
1051 For more examples of complex rendering, see the source code for ``{% if %}``,
1052 ``{% for %}``, ``{% ifequal %}``, and ``{% ifchanged %}``. They live in
1053 ``django/template/defaulttags.py``.
1054
1055 Shortcut for Simple Tags
1056 ------------------------
1057
1058 Many template tags take a single argument -- a string or a template variable
1059 reference -- and return a string after doing some processing based solely on
1060 the input argument and some external information. For example, the
1061 ``current_time`` tag we wrote earlier is of this variety. We give it a format
1062 string, and it returns the time as a string.
1063
1064 To ease the creation of these types of tags, Django provides a helper function,
1065 ``simple_tag``. This function, which is a method of ``django.template.Library``,
1066 takes a function that accepts one argument, wraps it in a ``render`` function
1067 and the other necessary bits mentioned previously, and registers it with the
1068 template system.
1069
1070 Our earlier ``current_time`` function could thus be written like this::
1071
1072 def current_time(format_string):
1073 try:
1074 return datetime.datetime.now().strftime(str(format_string))
1075 except UnicodeEncodeError:
1076 return ''
1077
1078 register.simple_tag(current_time)
1079
1080 In Python 2.4, the decorator syntax also works::
1081
1082 @register.simple_tag
1083 def current_time(token):
1084 # ...
1085
1086 Notice a couple of things to notice about the ``simple_tag`` helper function:
1087
1088 * Only the (single) argument is passed into our function.
1089
1090 * Checking for the required number of arguments has already been
1091 done by the time our function is called, so we don't need to do that.
1092
1093 * The quotes around the argument (if any) have already been stripped away,
1094 so we receive a plain Unicode string.
1095
1096 Inclusion Tags
1097 --------------
1098
1099 Another common template tag is the type that displays some data by
1100 rendering *another* template. For example, Django's admin interface uses
1101 custom template tags to display the buttons along the bottom of the
1102 "add/change" form pages. Those buttons always look the same, but the link
1103 targets change depending on the object being edited. They're a perfect case
1104 for using a small template that is filled with details from the current object.
1105
1106 These sorts of tags are called *inclusion tags*. Writing inclusion tags is
1107 probably best demonstrated by example. Let's write a tag that produces a list
1108 of books for a given ``Author`` object. We'll use the tag like this::
1109
1110 {% books_for_author author %}
1111
1112 The result will be something like this::
1113
1114 <ul>
1115 <li>The Cat In The Hat</li>
1116 <li>Hop On Pop</li>
1117 <li>Green Eggs And Ham</li>
1118 </ul>
1119
1120 First, we define the function that takes the argument and produces a
1121 dictionary of data for the result. Notice that we need to return only a
1122 dictionary, not anything more complex. This will be used as the context for
1123 the template fragment::
1124
1125 def books_for_author(author):
1126 books = Book.objects.filter(authors__id=author.id)
1127 return {'books': books}
1128
1129 Next, we create the template used to render the tag's output. Following our
1130 example, the template is very simple::
1131
1132 <ul>
1133 {% for book in books %}
1134 <li>{{ book.title }}</li>
1135 {% endfor %}
1136 </ul>
1137
1138 Finally, we create and register the inclusion tag by calling the
1139 ``inclusion_tag()`` method on a ``Library`` object.
1140
1141 Following our example, if the preceding template is in a file called
1142 ``book_snippet.html``, we register the tag like this::
1143
1144 register.inclusion_tag('book_snippet.html')(books_for_author)
1145
1146 Python 2.4 decorator syntax works as well, so we could have written this,
1147 instead::
1148
1149 @register.inclusion_tag('book_snippet.html')
1150 def books_for_author(author):
1151 # ...
1152
1153 Sometimes, your inclusion tags need access to values from the parent template's
1154 context. To solve this, Django provides a ``takes_context`` option for
1155 inclusion tags. If you specify ``takes_context`` in creating an inclusion tag,
1156 the tag will have no required arguments, and the underlying Python function
1157 will have one argument: the template context as of when the tag was called.
1158
1159 For example, say you're writing an inclusion tag that will always be used in a
1160 context that contains ``home_link`` and ``home_title`` variables that point
1161 back to the main page. Here's what the Python function would look like::
1162
1163 @register.inclusion_tag('link.html', takes_context=True)
1164 def jump_link(context):
1165 return {
1166 'link': context['home_link'],
1167 'title': context['home_title'],
1168 }
1169
1170 (Note that the first parameter to the function *must* be called ``context``.)
1171
1172 The template ``link.html`` might contain the following::
1173
1174 Jump directly to <a href="{{ link }}">{{ title }}</a>.
1175
1176 Then, anytime you want to use that custom tag, load its library and call it
1177 without any arguments, like so::
1178
1179 {% jump_link %}
1180
1181 Writing Custom Template Loaders
1182 ===============================
1183
1184 Django's built-in template loaders (described in the "Inside Template Loading"
1185 section above) will usually cover all your template-loading needs, but it's
1186 pretty easy to write your own if you need special loading logic. For example,
1187 you could load templates from a database, or directly from a Subversion
1188 repository using Subversion's Python bindings, or (as shown shortly) from a ZIP
1189 archive.
1190
1191 A template loader -- that is, each entry in the ``TEMPLATE_LOADERS`` setting
1192 -- is expected to be a callable object with this interface::
1193
1194 load_template_source(template_name, template_dirs=None)
1195
1196 The ``template_name`` argument is the name of the template to load (as passed
1197 to ``loader.get_template()`` or ``loader.select_template()``), and
1198 ``template_dirs`` is an optional list of directories to search instead of
1199 ``TEMPLATE_DIRS``.
1200
1201 If a loader is able to successfully load a template, it should return a tuple:
1202 ``(template_source, template_path)``. Here, ``template_source`` is the
1203 template string that will be compiled by the template engine, and
1204 ``template_path`` is the path the template was loaded from. That path might be
1205 shown to the user for debugging purposes, so it should quickly identify where
1206 the template was loaded from.
1207
1208 If the loader is unable to load a template, it should raise
1209 ``django.template.TemplateDoesNotExist``.
1210
1211 Each loader function should also have an ``is_usable`` function attribute.
1212 This is a Boolean that informs the template engine whether this loader
1213 is available in the current Python installation. For example, the eggs loader
1214 (which is capable of loading templates from Python eggs) sets ``is_usable``
1215 to ``False`` if the ``pkg_resources`` module isn't installed, because
1216 ``pkg_resources`` is necessary to read data from eggs.
1217
1218 An example should help clarify all of this. Here's a template loader function
1219 that can load templates from a ZIP file. It uses a custom setting,
1220 ``TEMPLATE_ZIP_FILES``, as a search path instead of ``TEMPLATE_DIRS``, and it
1221 expects each item on that path to be a ZIP file containing templates::
1222
1223 from django.conf import settings
1224 from django.template import TemplateDoesNotExist
1225 import zipfile
1226
1227 def load_template_source(template_name, template_dirs=None):
1228 "Template loader that loads templates from a ZIP file."
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
1229
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
1230 template_zipfiles = getattr(settings, "TEMPLATE_ZIP_FILES", [])
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
1231
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
1232 # Try each ZIP file in TEMPLATE_ZIP_FILES.
1233 for fname in template_zipfiles:
1234 try:
1235 z = zipfile.ZipFile(fname)
1236 source = z.read(template_name)
1237 except (IOError, KeyError):
1238 continue
1239 z.close()
1240 # We found a template, so return the source.
1241 template_path = "%s:%s" % (fname, template_name)
1242 return (source, template_path)
1243
1244 # If we reach here, the template couldn't be loaded
1245 raise TemplateDoesNotExist(template_name)
1246
1247 # This loader is always usable (since zipfile is included with Python)
1248 load_template_source.is_usable = True
1249
1250 .. SL Tested ok
1251
1252 The only step left if we want to use this loader is to add it to the
1253 ``TEMPLATE_LOADERS`` setting. If we put this code in a package called
1254 ``mysite.zip_loader``, then we add
1255 ``mysite.zip_loader.load_template_source`` to ``TEMPLATE_LOADERS``.
1256
1257 Configuring the Template System in Standalone Mode
1258 ==================================================
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
1259
1260 .. note::
1261
d40cfe7 Jacob Kaplan-Moss Restored *2.0* version of the book, not 1.0!
jacobian authored
1262 This section is only of interest to people trying to use the template
1263 system as an output component in another application. If you are using the
1264 template system as part of a Django application, the information presented
1265 here doesn't apply to you.
1266
1267 Normally, Django loads all the configuration information it needs from its own
1268 default configuration file, combined with the settings in the module given
1269 in the ``DJANGO_SETTINGS_MODULE`` environment variable. (This was explained in
1270 "A special Python prompt" in Chapter 4.) But if you're using the template
1271 system independently of the rest of Django, the environment variable approach
1272 isn't very convenient, because you probably want to configure the template
1273 system in line with the rest of your application rather than dealing with
1274 settings files and pointing to them via environment variables.
1275
1276 To solve this problem, you need to use the manual configuration option described
1277 fully in Appendix D. In a nutshell, you need to import the appropriate pieces of
1278 the template system and then, *before* you call any of the template functions,
1279 call ``django.conf.settings.configure()`` with any settings you wish to specify.
1280
1281 You might want to consider setting at least ``TEMPLATE_DIRS`` (if you are
1282 going to use template loaders), ``DEFAULT_CHARSET`` (although the default of
1283 ``utf-8`` is probably fine) and ``TEMPLATE_DEBUG``. All available settings are
1284 described in Appendix D, and any setting starting with ``TEMPLATE_`` is of
1285 obvious interest.
1286
1287 What's Next
1288 ===========
1289
1290 Continuing this section's theme of advanced topics, the `next chapter`_ covers
1291 advanced usage of Django models.
acc918f Jacob Kaplan-Moss Initial import of djangobook from private SVN repo.
jacobian authored
1292
1293 .. _next chapter: ../chapter10/
Something went wrong with that request. Please try again.