Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 1619 lines (1250 sloc) 64.877 kB
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1 ====================
2 Chapter 4: Templates
3 ====================
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
4
5 In the previous chapter, you may have noticed something peculiar in how we
6 returned the text in our example views. Namely, the HTML was hard-coded directly
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
7 in our Python code, like this::
8
9 def current_datetime(request):
10 now = datetime.datetime.now()
11 html = "<html><body>It is now %s.</body></html>" % now
12 return HttpResponse(html)
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
13
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
14 Although this technique was convenient for the purpose of explaining how views
15 work, it's not a good idea to hard-code HTML directly in your views. Here's
16 why:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
17
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
18 * Any change to the design of the page requires a change to
19 the Python code. The design of a site tends to change far more frequently
20 than the underlying Python code, so it would be convenient if
21 the design could change without needing to modify the Python code.
22
23 * Writing Python code and designing HTML are two different disciplines, and
24 most professional Web development environments split these
25 responsibilities between separate people (or even separate departments).
26 Designers and HTML/CSS coders shouldn't be required to edit Python code
27 to get their job done.
28
29 * It's most efficient if programmers can work on Python code and designers
30 can work on templates at the same time, rather than one person waiting
31 for the other to finish editing a single file that contains both Python
32 and HTML.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
33
34 For these reasons, it's much cleaner and more maintainable to separate the
35 design of the page from the Python code itself. We can do this with Django's
36 *template system*, which we discuss in this chapter.
37
38 Template System Basics
39 ======================
40
41 A Django template is a string of text that is intended to separate the
42 presentation of a document from its data. A template defines placeholders and
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
43 various bits of basic logic (template tags) that regulate how the document
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
44 should be displayed. Usually, templates are used for producing HTML, but Django
45 templates are equally capable of generating any text-based format.
46
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
47 Let's start with a simple example template. This Django template describes an
48 HTML page that thanks a person for placing an order with a company. Think of it
49 as a form letter::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
50
51 <html>
52 <head><title>Ordering notice</title></head>
53
54 <body>
55
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
56 <h1>Ordering notice</h1>
57
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
58 <p>Dear {{ person_name }},</p>
59
60 <p>Thanks for placing an order from {{ company }}. It's scheduled to
61 ship on {{ ship_date|date:"F j, Y" }}.</p>
62
63 <p>Here are the items you've ordered:</p>
64
65 <ul>
66 {% for item in item_list %}
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
67 <li>{{ item }}</li>
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
68 {% endfor %}
69 </ul>
70
71 {% if ordered_warranty %}
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
72 <p>Your warranty information will be included in the packaging.</p>
73 {% else %}
74 <p>You didn't order a warranty, so you're on your own when
75 the products inevitably stop working.</p>
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
76 {% endif %}
77
78 <p>Sincerely,<br />{{ company }}</p>
79
80 </body>
81 </html>
82
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
83 This template is basic HTML with some variables and template tags thrown in.
84 Let's step through it:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
85
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
86 * Any text surrounded by a pair of braces (e.g., ``{{ person_name }}``) is a
87 *variable*. This means "insert the value of the variable with the given
88 name." (How do we specify the values of the variables? We'll get to that in
89 a moment.)
90
91 * Any text that's surrounded by curly braces and percent signs (e.g., ``{%
92 if ordered_warranty %}``) is a *template tag*. The definition of a tag is
93 quite broad: a tag just tells the template system to "do something."
94
95 This example template contains a ``for`` tag (``{% for item in item_list
96 %}``) and an ``if`` tag (``{% if ordered_warranty %}``).
97
98 A ``for`` tag works very much like a ``for`` statement in Python, letting
99 you loop over each item in a sequence. An ``if`` tag, as you may expect,
100 acts as a logical "if" statement. In this particular case, the tag checks
101 whether the value of the ``ordered_warranty`` variable evaluates to
102 ``True``. If it does, the template system will display everything between
103 the ``{% if ordered_warranty %}`` and ``{% else %}``. If not, the
104 template system will display everything between ``{% else %}`` and
105 ``{% endif %}``. Note that the ``{% else %}`` is optional.
106
107 * Finally, the second paragraph of this template contains an example of a
108 *filter*, which is the most convenient way to alter the formatting of a
109 variable. In this example, ``{{ ship_date|date:"F j, Y" }}``, we're passing the
110 ``ship_date`` variable to the ``date`` filter, giving the ``date`` filter
111 the argument ``"F j, Y"``. The ``date`` filter formats dates in a given
112 format, as specified by that argument. Filters are attached using a pipe
113 character (``|``), as a reference to Unix pipes.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
114
115 Each Django template has access to several built-in tags and filters, many of
b89ddc3 @yoberi Update chapter04.rst
yoberi authored
116 which are discussed in the sections that follow. Appendix E contains the full
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
117 list of tags and filters, and it's a good idea to familiarize yourself with that
118 list so you know what's possible. It's also possible to create your own filters
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
119 and tags; we'll cover that in Chapter 9.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
120
121 Using the Template System
122 =========================
123
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
124 Let's dive into Django's template system so you can see how it works -- but
125 we're *not* yet going to integrate it with the views that we created in the
126 previous chapter. Our goal here is to show you how the system works
127 independently of the rest of Django. (Put another way: usually you'll be using
128 the template system within a Django view, but we want to make it clear that the
129 template system is just a Python library that you can use *anywhere*, not just
130 in Django views.)
131
132 Here is the most basic way you can use Django's template system in Python code:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
133
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
134 1. Create a ``Template`` object by providing the raw template code as a
135 string.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
136
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
137 2. Call the ``render()`` method of the ``Template`` object with a given
138 set of variables (the *context*). This returns a fully rendered
139 template as a string, with all of the variables and template tags
140 evaluated according to the context.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
141
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
142 In code, here's what that looks like::
143
144 >>> from django import template
145 >>> t = template.Template('My name is {{ name }}.')
146 >>> c = template.Context({'name': 'Adrian'})
147 >>> print t.render(c)
148 My name is Adrian.
149 >>> c = template.Context({'name': 'Fred'})
150 >>> print t.render(c)
151 My name is Fred.
152
153 The following sections describe each step in much more detail.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
154
155 Creating Template Objects
156 -------------------------
157
158 The easiest way to create a ``Template`` object is to instantiate it directly.
159 The ``Template`` class lives in the ``django.template`` module, and the
160 constructor takes one argument, the raw template code. Let's dip into the Python
161 interactive interpreter to see how this works in code.
162
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
163 From the ``mysite`` project directory created by ``django-admin.py
164 startproject`` (as covered in Chapter 2), type ``python manage.py shell`` to
165 start the interactive interpreter.
166
167 .. admonition:: A special Python prompt
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
168
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
169 If you've used Python before, you may be wondering why we're running
170 ``python manage.py shell`` instead of just ``python``. Both commands will
171 start the interactive interpreter, but the ``manage.py shell`` command has
172 one key difference: before starting the interpreter, it tells Django which
173 settings file to use. Many parts of Django, including the template system,
174 rely on your settings, and you won't be able to use them unless the
175 framework knows which settings to use.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
176
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
177 If you're curious, here's how it works behind the scenes. Django looks for
178 an environment variable called ``DJANGO_SETTINGS_MODULE``, which should be
179 set to the import path of your ``settings.py``. For example,
180 ``DJANGO_SETTINGS_MODULE`` might be set to ``'mysite.settings'``, assuming
181 ``mysite`` is on your Python path.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
182
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
183 When you run ``python manage.py shell``, the command takes care of setting
184 ``DJANGO_SETTINGS_MODULE`` for you. We're encouraging you to use
185 ``python manage.py shell`` in these examples so as to minimize the amount
186 of tweaking and configuring you have to do.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
187
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
188 As you become more familiar with Django, you'll likely stop using
189 ``manage.py shell`` and will set ``DJANGO_SETTINGS_MODULE`` manually in
190 your ``.bash_profile`` or other shell environment configuration file.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
191
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
192 Let's go through some template system basics::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
193
194 >>> from django.template import Template
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
195 >>> t = Template('My name is {{ name }}.')
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
196 >>> print t
197
198 If you're following along interactively, you'll see something like this::
199
200 <django.template.Template object at 0xb7d5f24c>
201
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
202 That ``0xb7d5f24c`` will be different every time, and it isn't relevant; it's a
203 Python thing (the Python "identity" of the ``Template`` object, if you must
204 know).
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
205
206 When you create a ``Template`` object, the template system compiles the raw
207 template code into an internal, optimized form, ready for rendering. But if your
208 template code includes any syntax errors, the call to ``Template()`` will cause
209 a ``TemplateSyntaxError`` exception::
210
211 >>> from django.template import Template
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
212 >>> t = Template('{% notatag %}')
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
213 Traceback (most recent call last):
214 File "<stdin>", line 1, in ?
215 ...
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
216 django.template.TemplateSyntaxError: Invalid block tag: 'notatag'
217
218 The term "block tag" here refers to ``{% notatag %}``. "Block tag" and
219 "template tag" are synonymous.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
220
221 The system raises a ``TemplateSyntaxError`` exception for any of the following
222 cases:
223
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
224 * Invalid tags
225 * Invalid arguments to valid tags
226 * Invalid filters
227 * Invalid arguments to valid filters
228 * Invalid template syntax
229 * Unclosed tags (for tags that require closing tags)
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
230
231 Rendering a Template
232 --------------------
233
234 Once you have a ``Template`` object, you can pass it data by giving it a
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
235 *context*. A context is simply a set of template variable names and their
236 associated values. A template uses this to populate its variables and
237 evaluate its tags.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
238
239 A context is represented in Django by the ``Context`` class, which lives in the
240 ``django.template`` module. Its constructor takes one optional argument: a
241 dictionary mapping variable names to variable values. Call the ``Template``
242 object's ``render()`` method with the context to "fill" the template::
243
244 >>> from django.template import Context, Template
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
245 >>> t = Template('My name is {{ name }}.')
246 >>> c = Context({'name': 'Stephane'})
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
247 >>> t.render(c)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
248 u'My name is Stephane.'
249
250 One thing we should point out here is that the return value of ``t.render(c)``
251 is a Unicode object -- not a normal Python string. You can tell this by the
252 ``u`` in front of the string. Django uses Unicode objects instead of normal
253 strings throughout the framework. If you understand the repercussions of that,
254 be thankful for the sophisticated things Django does behind the scenes to make
255 it work. If you don't understand the repercussions of that, don't worry for
256 now; just know that Django's Unicode support makes it relatively painless for
257 your applications to support a wide variety of character sets beyond the basic
258 "A-Z" of the English language.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
259
260 .. admonition:: Dictionaries and Contexts
261
262 A Python dictionary is a mapping between known keys and variable
263 values. A ``Context`` is similar to a dictionary, but a ``Context``
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
264 provides additional functionality, as covered in Chapter 9.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
265
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
266 Variable names must begin with a letter (A-Z or a-z) and may contain more
267 letters, digits, underscores, and dots. (Dots are a special case we'll get to in a moment.)
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
268 Variable names are case sensitive.
269
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
270 Here's an example of template compilation and rendering, using a template
271 similar to the example in the beginning of this chapter::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
272
273 >>> from django.template import Template, Context
274 >>> raw_template = """<p>Dear {{ person_name }},</p>
275 ...
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
276 ... <p>Thanks for placing an order from {{ company }}. It's scheduled to
277 ... ship on {{ ship_date|date:"F j, Y" }}.</p>
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
278 ...
279 ... {% if ordered_warranty %}
280 ... <p>Your warranty information will be included in the packaging.</p>
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
281 ... {% else %}
282 ... <p>You didn't order a warranty, so you're on your own when
283 ... the products inevitably stop working.</p>
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
284 ... {% endif %}
285 ...
286 ... <p>Sincerely,<br />{{ company }}</p>"""
287 >>> t = Template(raw_template)
288 >>> import datetime
289 >>> c = Context({'person_name': 'John Smith',
290 ... 'company': 'Outdoor Equipment',
291 ... 'ship_date': datetime.date(2009, 4, 2),
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
292 ... 'ordered_warranty': False})
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
293 >>> t.render(c)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
294 u"<p>Dear John Smith,</p>\n\n<p>Thanks for placing an order from Outdoor
295 Equipment. It's scheduled to\nship on April 2, 2009.</p>\n\n\n<p>You
296 didn't order a warranty, so you're on your own when\nthe products
297 inevitably stop working.</p>\n\n\n<p>Sincerely,<br />Outdoor Equipment
298 </p>"
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
299
300 Let's step through this code one statement at a time:
301
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
302 * First, we import the classes ``Template`` and ``Context``, which both
303 live in the module ``django.template``.
304
305 * We save the raw text of our template into the variable
306 ``raw_template``. Note that we use triple quote marks to designate the
307 string, because it wraps over multiple lines; in contrast, strings
308 within single quote marks cannot be wrapped over multiple lines.
309
310 * Next, we create a template object, ``t``, by passing ``raw_template`` to
311 the ``Template`` class constructor.
312
313 * We import the ``datetime`` module from Python's standard library,
314 because we'll need it in the following statement.
315
316 * Then, we create a ``Context`` object, ``c``. The ``Context``
317 constructor takes a Python dictionary, which maps variable names to
318 values. Here, for example, we specify that the ``person_name``
319 is ``'John Smith'``, ``company`` is ``'Outdoor Equipment'``, and so forth.
320
321 * Finally, we call the ``render()`` method on our template object, passing
322 it the context. This returns the rendered template -- i.e., it replaces
323 template variables with the actual values of the variables, and it
324 executes any template tags.
325
326 Note that the "You didn't order a warranty" paragraph was displayed
327 because the ``ordered_warranty`` variable evaluated to ``False``. Also
328 note the date, ``April 2, 2009``, which is displayed according to the
329 format string ``'F j, Y'``. (We'll explain format strings for the
330 ``date`` filter in a little while.)
331
332 If you're new to Python, you may wonder why this output includes
333 newline characters (``'\n'``) rather than displaying the line breaks.
334 That's happening because of a subtlety in the Python interactive
335 interpreter: the call to ``t.render(c)`` returns a string, and by default
336 the interactive interpreter displays the *representation* of the string,
337 rather than the printed value of the string. If you want to see the
338 string with line breaks displayed as true line breaks rather than ``'\n'``
339 characters, use the ``print`` statement: ``print t.render(c)``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
340
341 Those are the fundamentals of using the Django template system: just write a
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
342 template string, create a ``Template`` object, create a ``Context``, and call
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
343 the ``render()`` method.
344
345 Multiple Contexts, Same Template
346 --------------------------------
347
348 Once you have a ``Template`` object, you can render multiple contexts through
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
349 it. For example::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
350
351 >>> from django.template import Template, Context
352 >>> t = Template('Hello, {{ name }}')
353 >>> print t.render(Context({'name': 'John'}))
354 Hello, John
355 >>> print t.render(Context({'name': 'Julie'}))
356 Hello, Julie
357 >>> print t.render(Context({'name': 'Pat'}))
358 Hello, Pat
359
360 Whenever you're using the same template source to render multiple
361 contexts like this, it's more efficient to create the ``Template``
362 object *once*, and then call ``render()`` on it multiple times::
363
364 # Bad
365 for name in ('John', 'Julie', 'Pat'):
366 t = Template('Hello, {{ name }}')
367 print t.render(Context({'name': name}))
368
369 # Good
370 t = Template('Hello, {{ name }}')
371 for name in ('John', 'Julie', 'Pat'):
372 print t.render(Context({'name': name}))
373
374 Django's template parsing is quite fast. Behind the scenes, most of the parsing
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
375 happens via a call to a single regular expression. This is in stark
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
376 contrast to XML-based template engines, which incur the overhead of an XML
377 parser and tend to be orders of magnitude slower than Django's template
378 rendering engine.
379
380 Context Variable Lookup
381 -----------------------
382
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
383 In the examples so far, we've passed simple values in the contexts -- mostly
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
384 strings, plus a ``datetime.date`` example. However, the template system
385 elegantly handles more complex data structures, such as lists, dictionaries, and
386 custom objects.
387
388 The key to traversing complex data structures in Django templates is the dot
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
389 character (``.``). Use a dot to access dictionary keys, attributes, methods,
390 or indices of an object.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
391
392 This is best illustrated with a few examples. For instance, suppose
393 you're passing a Python dictionary to a template. To access the values
394 of that dictionary by dictionary key, use a dot::
395
396 >>> from django.template import Template, Context
397 >>> person = {'name': 'Sally', 'age': '43'}
398 >>> t = Template('{{ person.name }} is {{ person.age }} years old.')
399 >>> c = Context({'person': person})
400 >>> t.render(c)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
401 u'Sally is 43 years old.'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
402
403 Similarly, dots also allow access of object attributes. For example, a Python
404 ``datetime.date`` object has ``year``, ``month``, and ``day`` attributes, and
405 you can use a dot to access those attributes in a Django template::
406
407 >>> from django.template import Template, Context
408 >>> import datetime
409 >>> d = datetime.date(1993, 5, 2)
410 >>> d.year
411 1993
412 >>> d.month
413 5
414 >>> d.day
415 2
416 >>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
417 >>> c = Context({'date': d})
418 >>> t.render(c)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
419 u'The month is 5 and the year is 1993.'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
420
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
421 This example uses a custom class, demonstrating that variable dots also allow
422 attribute access on arbitrary objects::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
423
424 >>> from django.template import Template, Context
425 >>> class Person(object):
426 ... def __init__(self, first_name, last_name):
427 ... self.first_name, self.last_name = first_name, last_name
428 >>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
429 >>> c = Context({'person': Person('John', 'Smith')})
430 >>> t.render(c)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
431 u'Hello, John Smith.'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
432
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
433 Dots can also refer to *methods* on objects. For example, each Python string
434 has the methods ``upper()`` and ``isdigit()``, and you can call those in Django
435 templates using the same dot syntax::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
436
437 >>> from django.template import Template, Context
438 >>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
439 >>> t.render(Context({'var': 'hello'}))
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
440 u'hello -- HELLO -- False'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
441 >>> t.render(Context({'var': '123'}))
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
442 u'123 -- 123 -- True'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
443
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
444 Note that you do *not* include parentheses in the method calls. Also, it's not
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
445 possible to pass arguments to the methods; you can only call methods that have
446 no required arguments. (We explain this philosophy later in this chapter.)
447
448 Finally, dots are also used to access list indices, for example::
449
450 >>> from django.template import Template, Context
451 >>> t = Template('Item 2 is {{ items.2 }}.')
452 >>> c = Context({'items': ['apples', 'bananas', 'carrots']})
453 >>> t.render(c)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
454 u'Item 2 is carrots.'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
455
456 Negative list indices are not allowed. For example, the template variable
457 ``{{ items.-1 }}`` would cause a ``TemplateSyntaxError``.
458
459 .. admonition:: Python Lists
460
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
461 A reminder: Python lists have 0-based indices. The first item is at index 0,
462 the second is at index 1, and so on.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
463
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
464 Dot lookups can be summarized like this: when the template system
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
465 encounters a dot in a variable name, it tries the following lookups, in this
466 order:
467
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
468 * Dictionary lookup (e.g., ``foo["bar"]``)
469 * Attribute lookup (e.g., ``foo.bar``)
470 * Method call (e.g., ``foo.bar()``)
471 * List-index lookup (e.g., ``foo[2]``)
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
472
473 The system uses the first lookup type that works. It's short-circuit logic.
474
475 Dot lookups can be nested multiple levels deep. For instance, the following
476 example uses ``{{ person.name.upper }}``, which translates into a dictionary
477 lookup (``person['name']``) and then a method call (``upper()``)::
478
479 >>> from django.template import Template, Context
480 >>> person = {'name': 'Sally', 'age': '43'}
481 >>> t = Template('{{ person.name.upper }} is {{ person.age }} years old.')
482 >>> c = Context({'person': person})
483 >>> t.render(c)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
484 u'SALLY is 43 years old.'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
485
486 Method Call Behavior
487 ~~~~~~~~~~~~~~~~~~~~
488
489 Method calls are slightly more complex than the other lookup types. Here are
490 some things to keep in mind:
491
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
492 * If, during the method lookup, a method raises an exception, the exception
493 will be propagated, unless the exception has an attribute
494 ``silent_variable_failure`` whose value is ``True``. If the exception
495 *does* have a ``silent_variable_failure`` attribute, the variable will
496 render as an empty string, for example::
497
498 >>> t = Template("My name is {{ person.first_name }}.")
499 >>> class PersonClass3:
500 ... def first_name(self):
501 ... raise AssertionError, "foo"
502 >>> p = PersonClass3()
503 >>> t.render(Context({"person": p}))
504 Traceback (most recent call last):
505 ...
506 AssertionError: foo
507
508 >>> class SilentAssertionError(AssertionError):
509 ... silent_variable_failure = True
510 >>> class PersonClass4:
511 ... def first_name(self):
512 ... raise SilentAssertionError
513 >>> p = PersonClass4()
514 >>> t.render(Context({"person": p}))
515 u'My name is .'
516
517 * A method call will only work if the method has no required arguments.
518 Otherwise, the system will move to the next lookup type (list-index
519 lookup).
520
521 * Obviously, some methods have side effects, and it would be foolish at
522 best, and possibly even a security hole, to allow the template system to
523 access them.
524
525 Say, for instance, you have a ``BankAccount`` object that has a
526 ``delete()`` method. If a template includes something like
527 ``{{ account.delete }}``, where ``account`` is a ``BankAccount`` object,
528 the object would be deleted when the template is rendered!
529
530 To prevent this, set the function attribute ``alters_data`` on the
531 method::
532
533 def delete(self):
534 # Delete the account
535 delete.alters_data = True
536
537 The template system won't execute any method marked in this way.
538 Continuing the above example, if a template includes
539 ``{{ account.delete }}`` and the ``delete()`` method has the
540 ``alters_data=True``, then the ``delete()`` method will not be executed
541 when the template is rendered. Instead, it will fail silently.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
542
543 How Invalid Variables Are Handled
544 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
545
546 By default, if a variable doesn't exist, the template system renders it as an
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
547 empty string, failing silently. For example::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
548
549 >>> from django.template import Template, Context
550 >>> t = Template('Your name is {{ name }}.')
551 >>> t.render(Context())
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
552 u'Your name is .'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
553 >>> t.render(Context({'var': 'hello'}))
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
554 u'Your name is .'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
555 >>> t.render(Context({'NAME': 'hello'}))
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
556 u'Your name is .'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
557 >>> t.render(Context({'Name': 'hello'}))
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
558 u'Your name is .'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
559
560 The system fails silently rather than raising an exception because it's
561 intended to be resilient to human error. In this case, all of the
562 lookups failed because variable names have the wrong case or name. In the real
563 world, it's unacceptable for a Web site to become inaccessible due to a
564 small template syntax error.
565
566 Playing with Context Objects
567 ----------------------------
568
569 Most of the time, you'll instantiate ``Context`` objects by passing in a
570 fully populated dictionary to ``Context()``. But you can add and delete items
571 from a ``Context`` object once it's been instantiated, too, using standard
572 Python dictionary syntax::
573
574 >>> from django.template import Context
575 >>> c = Context({"foo": "bar"})
576 >>> c['foo']
577 'bar'
578 >>> del c['foo']
579 >>> c['foo']
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
580 Traceback (most recent call last):
581 ...
582 KeyError: 'foo'
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
583 >>> c['newvariable'] = 'hello'
584 >>> c['newvariable']
585 'hello'
586
587 Basic Template Tags and Filters
588 ===============================
589
590 As we've mentioned already, the template system ships with built-in tags and
591 filters. The sections that follow provide a rundown of the most common tags and
592 filters.
593
594 Tags
595 ----
596
597 if/else
598 ~~~~~~~
599
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
600 The ``{% if %}`` tag evaluates a variable, and if that variable is "True"
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
601 (i.e., it exists, is not empty, and is not a false Boolean value), the system
602 will display everything between ``{% if %}`` and ``{% endif %}``, for example::
603
604 {% if today_is_weekend %}
605 <p>Welcome to the weekend!</p>
606 {% endif %}
607
608 An ``{% else %}`` tag is optional::
609
610 {% if today_is_weekend %}
611 <p>Welcome to the weekend!</p>
612 {% else %}
613 <p>Get back to work.</p>
614 {% endif %}
615
616 .. admonition:: Python "Truthiness"
617
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
618 In Python and in the Django template system, these objects evaluate to
619 ``False`` in a Boolean context:
620
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
621 * An empty list (``[]``)
622 * An empty tuple (``()``)
623 * An empty dictionary (``{}``)
624 * An empty string (``''``)
625 * Zero (``0``)
626 * The special object ``None``
627 * The object ``False`` (obviously)
628 * Custom objects that define their own Boolean context behavior
629 (this is advanced Python usage)
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
630
631 Everything else evaluates to ``True``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
632
633 The ``{% if %}`` tag accepts ``and``, ``or``, or ``not`` for testing multiple
634 variables, or to negate a given variable. For example::
635
636 {% if athlete_list and coach_list %}
637 Both athletes and coaches are available.
638 {% endif %}
639
640 {% if not athlete_list %}
641 There are no athletes.
642 {% endif %}
643
644 {% if athlete_list or coach_list %}
645 There are some athletes or some coaches.
646 {% endif %}
647
648 {% if not athlete_list or coach_list %}
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
649 There are no athletes or there are some coaches.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
650 {% endif %}
651
652 {% if athlete_list and not coach_list %}
653 There are some athletes and absolutely no coaches.
654 {% endif %}
655
656 ``{% if %}`` tags don't allow ``and`` and ``or`` clauses within the same tag,
657 because the order of logic would be ambiguous. For example, this is invalid::
658
659 {% if athlete_list and coach_list or cheerleader_list %}
660
661 The use of parentheses for controlling order of operations is not supported. If
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
662 you find yourself needing parentheses, consider performing logic outside the
663 template and passing the result of that as a dedicated template variable. Or,
664 just use nested ``{% if %}`` tags, like this::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
665
666 {% if athlete_list %}
667 {% if coach_list or cheerleader_list %}
668 We have athletes, and either coaches or cheerleaders!
669 {% endif %}
670 {% endif %}
671
672 Multiple uses of the same logical operator are fine, but you can't
673 combine different operators. For example, this is valid::
674
675 {% if athlete_list or coach_list or parent_list or teacher_list %}
676
677 There is no ``{% elif %}`` tag. Use nested ``{% if %}`` tags to accomplish
678 the same thing::
679
680 {% if athlete_list %}
681 <p>Here are the athletes: {{ athlete_list }}.</p>
682 {% else %}
683 <p>No athletes are available.</p>
684 {% if coach_list %}
685 <p>Here are the coaches: {{ coach_list }}.</p>
686 {% endif %}
687 {% endif %}
688
689 Make sure to close each ``{% if %}`` with an ``{% endif %}``. Otherwise, Django
690 will throw a ``TemplateSyntaxError``.
691
692 for
693 ~~~
694
695 The ``{% for %}`` tag allows you to loop over each item in a sequence. As in
696 Python's ``for`` statement, the syntax is ``for X in Y``, where ``Y`` is the
697 sequence to loop over and ``X`` is the name of the variable to use for a
698 particular cycle of the loop. Each time through the loop, the template system
699 will render everything between ``{% for %}`` and ``{% endfor %}``.
700
701 For example, you could use the following to display a list of athletes given a
702 variable ``athlete_list``::
703
704 <ul>
705 {% for athlete in athlete_list %}
706 <li>{{ athlete.name }}</li>
707 {% endfor %}
708 </ul>
709
710 Add ``reversed`` to the tag to loop over the list in reverse::
711
712 {% for athlete in athlete_list reversed %}
713 ...
714 {% endfor %}
715
716 It's possible to nest ``{% for %}`` tags::
717
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
718 {% for athlete in athlete_list %}
719 <h1>{{ athlete.name }}</h1>
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
720 <ul>
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
721 {% for sport in athlete.sports_played %}
722 <li>{{ sport }}</li>
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
723 {% endfor %}
724 </ul>
725 {% endfor %}
726
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
727 A common pattern is to check the size of the list before looping over it, and
728 outputting some special text if the list is empty::
729
730 {% if athlete_list %}
731 {% for athlete in athlete_list %}
732 <p>{{ athlete.name }}</p>
733 {% endfor %}
734 {% else %}
735 <p>There are no athletes. Only computer programmers.</p>
736 {% endif %}
737
738 Because this pattern is so common, the ``for`` tag supports an optional
739 ``{% empty %}`` clause that lets you define what to output if the list is
740 empty. This example is equivalent to the previous one::
741
742 {% for athlete in athlete_list %}
743 <p>{{ athlete.name }}</p>
744 {% empty %}
745 <p>There are no athletes. Only computer programmers.</p>
746 {% endfor %}
747
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
748 There is no support for "breaking out" of a loop before the loop is finished.
749 If you want to accomplish this, change the variable you're looping over so that
750 it includes only the values you want to loop over. Similarly, there is no
751 support for a "continue" statement that would instruct the loop processor to
752 return immediately to the front of the loop. (See the section "Philosophies and
753 Limitations" later in this chapter for the reasoning behind this design
754 decision.)
755
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
756 Within each ``{% for %}`` loop, you get access to a template variable called
757 ``forloop``. This variable has a few attributes that give you information about
758 the progress of the loop:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
759
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
760 * ``forloop.counter`` is always set to an integer representing the number
761 of times the loop has been entered. This is one-indexed, so the first
762 time through the loop, ``forloop.counter`` will be set to ``1``.
763 Here's an example::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
764
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
765 {% for item in todo_list %}
766 <p>{{ forloop.counter }}: {{ item }}</p>
767 {% endfor %}
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
768
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
769 * ``forloop.counter0`` is like ``forloop.counter``, except it's
770 zero-indexed. Its value will be set to ``0`` the first time through the
771 loop.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
772
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
773 * ``forloop.revcounter`` is always set to an integer representing the
774 number of remaining items in the loop. The first time through the loop,
775 ``forloop.revcounter`` will be set to the total number of items in the
776 sequence you're traversing. The last time through the loop,
777 ``forloop.revcounter`` will be set to ``1``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
778
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
779 * ``forloop.revcounter0`` is like ``forloop.revcounter``, except it's
780 zero-indexed. The first time through the loop, ``forloop.revcounter0``
781 will be set to the number of elements in the sequence minus 1. The last
782 time through the loop, it will be set to ``0``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
783
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
784 * ``forloop.first`` is a Boolean value set to ``True`` if this is the first
785 time through the loop. This is convenient for special-casing::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
786
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
787 {% for object in objects %}
788 {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
789 {{ object }}
790 </li>
791 {% endfor %}
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
792
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
793 * ``forloop.last`` is a Boolean value set to ``True`` if this is the last
794 time through the loop. A common use for this is to put pipe
795 characters between a list of links::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
796
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
797 {% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
798
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
799 The above template code might output something like this::
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
800
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
801 Link1 | Link2 | Link3 | Link4
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
802
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
803 Another common use for this is to put a comma between words in a list::
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
804
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
805 Favorite places:
806 {% for p in places %}{{ p }}{% if not forloop.last %}, {% endif %}{% endfor %}
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
807
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
808 * ``forloop.parentloop`` is a reference to the ``forloop`` object for the
809 *parent* loop, in case of nested loops. Here's an example::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
810
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
811 {% for country in countries %}
812 <table>
813 {% for city in country.city_list %}
814 <tr>
815 <td>Country #{{ forloop.parentloop.counter }}</td>
816 <td>City #{{ forloop.counter }}</td>
817 <td>{{ city }}</td>
818 </tr>
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
819 {% endfor %}
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
820 </table>
821 {% endfor %}
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
822
823 The magic ``forloop`` variable is only available within loops. After the
824 template parser has reached ``{% endfor %}``, ``forloop`` disappears.
825
826 .. admonition:: Context and the forloop Variable
827
828 Inside the ``{% for %}`` block, the existing variables are moved
829 out of the way to avoid overwriting the magic ``forloop``
830 variable. Django exposes this moved context in
831 ``forloop.parentloop``. You generally don't need to worry about
832 this, but if you supply a template variable named ``forloop``
833 (though we advise against it), it will be named
834 ``forloop.parentloop`` while inside the ``{% for %}`` block.
835
836 ifequal/ifnotequal
837 ~~~~~~~~~~~~~~~~~~
838
839 The Django template system deliberately is not a full-fledged programming
840 language and thus does not allow you to execute arbitrary Python statements.
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
841 (More on this idea in the section "Philosophies and Limitations.") However,
842 it's quite a common template requirement to compare two values and display
843 something if they're equal -- and Django provides an ``{% ifequal %}`` tag for
844 that purpose.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
845
846 The ``{% ifequal %}`` tag compares two values and displays everything between
847 ``{% ifequal %}`` and ``{% endifequal %}`` if the values are equal.
848
849 This example compares the template variables ``user`` and ``currentuser``::
850
851 {% ifequal user currentuser %}
852 <h1>Welcome!</h1>
853 {% endifequal %}
854
855 The arguments can be hard-coded strings, with either single or double quotes,
856 so the following is valid::
857
858 {% ifequal section 'sitenews' %}
859 <h1>Site News</h1>
860 {% endifequal %}
861
862 {% ifequal section "community" %}
863 <h1>Community</h1>
864 {% endifequal %}
865
866 Just like ``{% if %}``, the ``{% ifequal %}`` tag supports an optional
867 ``{% else %}``::
868
869 {% ifequal section 'sitenews' %}
870 <h1>Site News</h1>
871 {% else %}
872 <h1>No News Here</h1>
873 {% endifequal %}
874
875 Only template variables, strings, integers, and decimal numbers are allowed as
876 arguments to ``{% ifequal %}``. These are valid examples::
877
878 {% ifequal variable 1 %}
879 {% ifequal variable 1.23 %}
880 {% ifequal variable 'foo' %}
881 {% ifequal variable "foo" %}
882
883 Any other types of variables, such as Python dictionaries, lists, or Booleans,
884 can't be hard-coded in ``{% ifequal %}``. These are invalid examples::
885
886 {% ifequal variable True %}
887 {% ifequal variable [1, 2, 3] %}
888 {% ifequal variable {'key': 'value'} %}
889
890 If you need to test whether something is true or false, use the ``{% if %}``
891 tags instead of ``{% ifequal %}``.
892
893 Comments
894 ~~~~~~~~
895
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
896 Just as in HTML or Python, the Django template language allows for comments. To
897 designate a comment, use ``{# #}``::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
898
899 {# This is a comment #}
900
901 The comment will not be output when the template is rendered.
902
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
903 Comments using this syntax cannot span multiple lines. This limitation improves
904 template parsing performance. In the following template, the rendered output
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
905 will look exactly the same as the template (i.e., the comment tag will
906 not be parsed as a comment)::
907
908 This is a {# this is not
909 a comment #}
910 test.
911
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
912 If you want to use multi-line comments, use the ``{% comment %}`` template tag,
913 like this::
914
915 {% comment %}
916 This is a
917 multi-line comment.
918 {% endcomment %}
919
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
920 Filters
921 -------
922
923 As explained earlier in this chapter, template filters are simple ways of
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
924 altering the value of variables before they're displayed. Filters use a pipe
925 character, like this::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
926
927 {{ name|lower }}
928
929 This displays the value of the ``{{ name }}`` variable after being filtered
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
930 through the ``lower`` filter, which converts text to lowercase.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
931
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
932 Filters can be *chained* -- that is, they can be used in tandem such that the
933 output of one filter is applied to the next. Here's an example that takes the
934 first element in a list and converts it to uppercase::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
935
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
936 {{ my_list|first|upper }}
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
937
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
938 Some filters take arguments. A filter argument comes after a colon and is
939 always in double quotes. For example::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
940
941 {{ bio|truncatewords:"30" }}
942
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
943 This displays the first 30 words of the ``bio`` variable.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
944
b89ddc3 @yoberi Update chapter04.rst
yoberi authored
945 The following are a few of the most important filters. Appendix E covers the rest.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
946
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
947 * ``addslashes``: Adds a backslash before any backslash, single quote, or
948 double quote. This is useful if the produced text is included in
949 a JavaScript string.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
950
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
951 * ``date``: Formats a ``date`` or ``datetime`` object according to a
952 format string given in the parameter, for example::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
953
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
954 {{ pub_date|date:"F j, Y" }}
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
955
b89ddc3 @yoberi Update chapter04.rst
yoberi authored
956 Format strings are defined in Appendix E.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
957
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
958 * ``length``: Returns the length of the value. For a list, this returns the
959 number of elements. For a string, this returns the number of characters.
960 (Python experts, take note that this works on any Python object that
961 knows how to determine its length -- i.e., any object that has a
962 ``__len__()`` method.)
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
963
964 Philosophies and Limitations
965 ============================
966
967 Now that you've gotten a feel for the Django template language, we should point
968 out some of its intentional limitations, along with some philosophies behind why
969 it works the way it works.
970
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
971 More than any other component of Web applications, template syntax is highly
972 subjective, and programmers' opinions vary wildly. The fact that Python alone
973 has dozens, if not hundreds, of open source template-language implementations
974 supports this point. Each was likely created because its developer deemed all
975 existing template languages inadequate. (In fact, it is said to be a rite of
976 passage for a Python developer to write his or her own template language! If
977 you haven't done this yet, consider it. It's a fun exercise.)
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
978
979 With that in mind, you might be interested to know that Django doesn't require
980 that you use its template language. Because Django is intended to be a
981 full-stack Web framework that provides all the pieces necessary for Web
982 developers to be productive, many times it's *more convenient* to use Django's
983 template system than other Python template libraries, but it's not a strict
984 requirement in any sense. As you'll see in the upcoming section "Using Templates
985 in Views", it's very easy to use another template language with Django.
986
987 Still, it's clear we have a strong preference for the way Django's template
988 language works. The template system has roots in how Web development is done at
989 World Online and the combined experience of Django's creators. Here are a few of
990 those philosophies:
991
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
992 * *Business logic should be separated from presentation logic*. Django's
993 developers see a template system as a tool that controls presentation and
994 presentation-related logic -- and that's it. The template system shouldn't
995 support functionality that goes beyond this basic goal.
996
997 For that reason, it's impossible to call Python code directly within
998 Django templates. All "programming" is fundamentally limited to the scope
999 of what template tags can do. It *is* possible to write custom template
1000 tags that do arbitrary things, but the out-of-the-box Django template
1001 tags intentionally do not allow for arbitrary Python code execution.
1002
1003 * *Syntax should be decoupled from HTML/XML*. Although Django's template
1004 system is used primarily to produce HTML, it's intended to be just as
1005 usable for non-HTML formats, such as plain text. Some other template
1006 languages are XML based, placing all template logic within XML tags or
1007 attributes, but Django deliberately avoids this limitation. Requiring
1008 valid XML to write templates introduces a world of human mistakes and
1009 hard-to-understand error messages, and using an XML engine to parse
1010 templates incurs an unacceptable level of overhead in template processing.
1011
1012 * *Designers are assumed to be comfortable with HTML code*. The template
1013 system isn't designed so that templates necessarily are displayed nicely
1014 in WYSIWYG editors such as Dreamweaver. That is too severe a limitation
1015 and wouldn't allow the syntax to be as friendly as it is. Django expects
1016 template authors to be comfortable editing HTML directly.
1017
1018 * *Designers are assumed not to be Python programmers*. The template system
1019 authors recognize that Web page templates are most often written by
1020 *designers*, not *programmers*, and therefore should not assume Python
1021 knowledge.
1022
1023 However, the system also intends to accommodate small teams in which the
1024 templates *are* created by Python programmers. It offers a way to extend
1025 the system's syntax by writing raw Python code. (More on this in Chapter
1026 9.)
1027
1028 * *The goal is not to invent a programming language*. The goal is to offer
1029 just enough programming-esque functionality, such as branching and
1030 looping, that is essential for making presentation-related decisions.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1031
1032 Using Templates in Views
1033 ========================
1034
1035 You've learned the basics of using the template system; now let's use this
1036 knowledge to create a view. Recall the ``current_datetime`` view in
1037 ``mysite.views``, which we started in the previous chapter. Here's what it looks
1038 like::
1039
1040 from django.http import HttpResponse
1041 import datetime
1042
1043 def current_datetime(request):
1044 now = datetime.datetime.now()
1045 html = "<html><body>It is now %s.</body></html>" % now
1046 return HttpResponse(html)
1047
1048 Let's change this view to use Django's template system. At first, you might
1049 think to do something like this::
1050
1051 from django.template import Template, Context
1052 from django.http import HttpResponse
1053 import datetime
1054
1055 def current_datetime(request):
1056 now = datetime.datetime.now()
1057 t = Template("<html><body>It is now {{ current_date }}.</body></html>")
1058 html = t.render(Context({'current_date': now}))
1059 return HttpResponse(html)
1060
1061 Sure, that uses the template system, but it doesn't solve the problems we
1062 pointed out in the introduction of this chapter. Namely, the template is still
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1063 embedded in the Python code, so true separation of data and presentation isn't
1064 achieved. Let's fix that by putting the template in a *separate file*, which
1065 this view will load.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1066
1067 You might first consider saving your template somewhere on your
1068 filesystem and using Python's built-in file-opening functionality to read
1069 the contents of the template. Here's what that might look like, assuming the
1070 template was saved as the file ``/home/djangouser/templates/mytemplate.html``::
1071
1072 from django.template import Template, Context
1073 from django.http import HttpResponse
1074 import datetime
1075
1076 def current_datetime(request):
1077 now = datetime.datetime.now()
1078 # Simple way of using templates from the filesystem.
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1079 # This is BAD because it doesn't account for missing files!
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1080 fp = open('/home/djangouser/templates/mytemplate.html')
1081 t = Template(fp.read())
1082 fp.close()
1083 html = t.render(Context({'current_date': now}))
1084 return HttpResponse(html)
1085
1086 This approach, however, is inelegant for these reasons:
1087
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1088 * It doesn't handle the case of a missing file. If the file
1089 ``mytemplate.html`` doesn't exist or isn't readable, the ``open()`` call
1090 will raise an ``IOError`` exception.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1091
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1092 * It hard-codes your template location. If you were to use this
1093 technique for every view function, you'd be duplicating the template
1094 locations. Not to mention it involves a lot of typing!
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1095
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1096 * It includes a lot of boring boilerplate code. You've got better things to
1097 do than to write calls to ``open()``, ``fp.read()``, and ``fp.close()``
1098 each time you load a template.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1099
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1100 To solve these issues, we'll use *template loading* and *template directories*.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1101
1102 Template Loading
1103 ================
1104
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1105 Django provides a convenient and powerful API for loading templates from the
1106 filesystem, with the goal of removing redundancy both in your template-loading
1107 calls and in your templates themselves.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1108
1109 In order to use this template-loading API, first you'll need to tell the
1110 framework where you store your templates. The place to do this is in your
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1111 settings file -- the ``settings.py`` file that we mentioned last chapter, when
1112 we introduced the ``ROOT_URLCONF`` setting.
1113
1114 If you're following along, open your ``settings.py`` and find the
1115 ``TEMPLATE_DIRS`` setting. By default, it's an empty tuple, likely containing
1116 some auto-generated comments::
1117
1118 TEMPLATE_DIRS = (
1119 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
1120 # Always use forward slashes, even on Windows.
1121 # Don't forget to use absolute paths, not relative paths.
1122 )
1123
1124 This setting tells Django's template-loading mechanism where to look for
1125 templates. Pick a directory where you'd like to store your templates and add it
1126 to ``TEMPLATE_DIRS``, like so::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1127
1128 TEMPLATE_DIRS = (
1129 '/home/django/mysite/templates',
1130 )
1131
1132 There are a few things to note:
1133
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1134 * You can specify any directory you want, as long as the directory and
1135 templates within that directory are readable by the user account under
1136 which your Web server runs. If you can't think of an appropriate
1137 place to put your templates, we recommend creating a ``templates``
1138 directory within your project (i.e., within the ``mysite`` directory you
1139 created in Chapter 2).
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1140
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1141 * If your ``TEMPLATE_DIRS`` contains only one directory, don't forget the
1142 comma at the end of the directory string!
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1143
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1144 Bad::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1145
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1146 # Missing comma!
1147 TEMPLATE_DIRS = (
1148 '/home/django/mysite/templates'
1149 )
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1150
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1151 Good::
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1152
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1153 # Comma correctly in place.
1154 TEMPLATE_DIRS = (
1155 '/home/django/mysite/templates',
1156 )
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1157
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1158 The reason for this is that Python requires commas within single-element
1159 tuples to disambiguate the tuple from a parenthetical expression. This is
1160 a common newbie gotcha.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1161
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1162 * If you're on Windows, include your drive letter and use Unix-style
1163 forward slashes rather than backslashes, as follows::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1164
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1165 TEMPLATE_DIRS = (
1166 'C:/www/django/templates',
1167 )
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1168
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1169 * It's simplest to use absolute paths (i.e., directory paths that start at
1170 the root of the filesystem). If you want to be a bit more flexible and
1171 decoupled, though, you can take advantage of the fact that Django
1172 settings files are just Python code by constructing the contents of
1173 ``TEMPLATE_DIRS`` dynamically. For example::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1174
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1175 import os.path
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1176
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1177 TEMPLATE_DIRS = (
1178 os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
1179 )
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1180
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1181 This example uses the "magic" Python variable ``__file__``, which is
1182 automatically set to the file name of the Python module in which the code
1183 lives. It gets the name of the directory that contains ``settings.py``
1184 (``os.path.dirname``), then joins that with ``templates`` in a
1185 cross-platform way (``os.path.join``), then ensures that everything uses
1186 forward slashes instead of backslashes (in case of Windows).
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1187
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1188 While we're on the topic of dynamic Python code in settings files, we
1189 should point out that it's very important to avoid Python errors in your
1190 settings file. If you introduce a syntax error, or a runtime error, your
1191 Django-powered site will likely crash.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1192
1193 With ``TEMPLATE_DIRS`` set, the next step is to change the view code to
1194 use Django's template-loading functionality rather than hard-coding the
1195 template paths. Returning to our ``current_datetime`` view, let's change it
1196 like so::
1197
1198 from django.template.loader import get_template
1199 from django.template import Context
1200 from django.http import HttpResponse
1201 import datetime
1202
1203 def current_datetime(request):
1204 now = datetime.datetime.now()
1205 t = get_template('current_datetime.html')
1206 html = t.render(Context({'current_date': now}))
1207 return HttpResponse(html)
1208
1209 In this example, we're using the function
1210 ``django.template.loader.get_template()`` rather than loading the template from
1211 the filesystem manually. The ``get_template()`` function takes a template name
1212 as its argument, figures out where the template lives on the filesystem, opens
1213 that file, and returns a compiled ``Template`` object.
1214
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1215 Our template in this example is ``current_datetime.html``, but there's nothing
1216 special about that ``.html`` extension. You can give your templates whatever
1217 extension makes sense for your application, or you can leave off extensions
1218 entirely.
1219
1220 To determine the location of the template on your filesystem,
1221 ``get_template()`` combines your template directories from ``TEMPLATE_DIRS``
1222 with the template name that you pass to ``get_template()``. For example, if
1223 your ``TEMPLATE_DIRS`` is set to ``'/home/django/mysite/templates'``, the above
1224 ``get_template()`` call would look for the template
1225 ``/home/django/mysite/templates/current_datetime.html``.
1226
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1227 If ``get_template()`` cannot find the template with the given name, it raises
1228 a ``TemplateDoesNotExist`` exception. To see what that looks like, fire up the
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1229 Django development server again by running ``python manage.py runserver``
1230 within your Django project's directory. Then, point your browser at the page
1231 that activates the ``current_datetime`` view (e.g.,
1232 ``http://127.0.0.1:8000/time/``). Assuming your ``DEBUG`` setting is set to
1233 ``True`` and you haven't yet created a ``current_datetime.html`` template, you
1234 should see a Django error page highlighting the ``TemplateDoesNotExist`` error.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1235
1236 .. figure:: graphics/chapter04/missing_template.png
1237 :alt: Screenshot of a "TemplateDoesNotExist" error.
1238
1239 Figure 4-1: The error page shown when a template cannot be found.
1240
1241 This error page is similar to the one we explained in Chapter 3, with one
1242 additional piece of debugging information: a "Template-loader postmortem"
1243 section. This section tells you which templates Django tried to load, along with
1244 the reason each attempt failed (e.g., "File does not exist"). This information
1245 is invaluable when you're trying to debug template-loading errors.
1246
1247 Moving along, create the ``current_datetime.html`` file within your template
1248 directory using the following template code::
1249
1250 <html><body>It is now {{ current_date }}.</body></html>
1251
1252 Refresh the page in your Web browser, and you should see the fully rendered
1253 page.
1254
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1255 render()
a6db1b2 @RaphaelKimmig fix underline too long
RaphaelKimmig authored
1256 --------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1257
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1258 We've shown you how to load a template, fill a ``Context`` and return an
1259 ``HttpResponse`` object with the result of the rendered template. We've
1260 optimized it to use ``get_template()`` instead of hard-coding templates and
1261 template paths. But it still requires a fair amount of typing to do those
1262 things. Because this is such a common idiom, Django provides a shortcut that
1263 lets you load a template, render it and return an ``HttpResponse`` -- all in
1264 one line of code.
1265
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1266 This shortcut is a function called ``render()``, which lives in the
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1267 module ``django.shortcuts``. Most of the time, you'll be using
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1268 ``render()`` rather than loading templates and creating ``Context``
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1269 and ``HttpResponse`` objects manually -- unless your employer judges your work
1270 by total lines of code written, that is.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1271
1272 Here's the ongoing ``current_datetime`` example rewritten to use
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1273 ``render()``::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1274
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1275 from django.shortcuts import render
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1276 import datetime
1277
1278 def current_datetime(request):
1279 now = datetime.datetime.now()
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1280 return render(request, 'current_datetime.html', {'current_date': now})
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1281
1282 What a difference! Let's step through the code changes:
1283
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1284 * We no longer have to import ``get_template``, ``Template``, ``Context``,
1285 or ``HttpResponse``. Instead, we import
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1286 ``django.shortcuts.render``. The ``import datetime`` remains.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1287
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1288 * Within the ``current_datetime`` function, we still calculate ``now``, but
1289 the template loading, context creation, template rendering, and
1290 ``HttpResponse`` creation are all taken care of by the
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1291 ``render()`` call. Because ``render()`` returns
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1292 an ``HttpResponse`` object, we can simply ``return`` that value in the
1293 view.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1294
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1295 The first argument to ``render()`` is the request, the second is the name of
1296 the template to use. The third argument, if given, should be a dictionary to
1297 use in creating a ``Context`` for that template. If you don't provide a third
1298 argument, ``render()`` will use an empty dictionary.
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1299
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1300 Subdirectories in get_template()
1301 --------------------------------
1302
1303 It can get unwieldy to store all of your templates in a single directory. You
1304 might like to store templates in subdirectories of your template directory, and
1305 that's fine. In fact, we recommend doing so; some more advanced Django
1306 features (such as the generic views system, which we cover in
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1307 Chapter 11) expect this template layout as a default convention.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1308
1309 Storing templates in subdirectories of your template directory is easy.
1310 In your calls to ``get_template()``, just include
1311 the subdirectory name and a slash before the template name, like so::
1312
1313 t = get_template('dateapp/current_datetime.html')
1314
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1315 Because ``render()`` is a small wrapper around ``get_template()``,
1316 you can do the same thing with the second argument to ``render()``,
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1317 like this::
1318
a4724d5 @RaphaelKimmig replace render_to_response with render
RaphaelKimmig authored
1319 return render(request, 'dateapp/current_datetime.html', {'current_date': now})
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1320
1321 There's no limit to the depth of your subdirectory tree. Feel free to use
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1322 as many subdirectories as you like.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1323
1324 .. note::
1325
1326 Windows users, be sure to use forward slashes rather than backslashes.
1327 ``get_template()`` assumes a Unix-style file name designation.
1328
1329 The ``include`` Template Tag
1330 ----------------------------
1331
1332 Now that we've covered the template-loading mechanism, we can introduce a
1333 built-in template tag that takes advantage of it: ``{% include %}``. This tag
1334 allows you to include the contents of another template. The argument to the tag
1335 should be the name of the template to include, and the template name can be
1336 either a variable or a hard-coded (quoted) string, in either single or double
1337 quotes. Anytime you have the same code in multiple templates,
1338 consider using an ``{% include %}`` to remove the duplication.
1339
1340 These two examples include the contents of the template ``nav.html``. The
1341 examples are equivalent and illustrate that either single or double quotes
1342 are allowed::
1343
1344 {% include 'nav.html' %}
1345 {% include "nav.html" %}
1346
1347 This example includes the contents of the template ``includes/nav.html``::
1348
1349 {% include 'includes/nav.html' %}
1350
1351 This example includes the contents of the template whose name is contained in
1352 the variable ``template_name``::
1353
1354 {% include template_name %}
1355
1356 As in ``get_template()``, the file name of the template is determined by adding
1357 the template directory from ``TEMPLATE_DIRS`` to the requested template name.
1358
1359 Included templates are evaluated with the context of the template
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1360 that's including them. For example, consider these two templates::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1361
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1362 # mypage.html
1363
1364 <html>
1365 <body>
1366 {% include "includes/nav.html" %}
1367 <h1>{{ title }}</h1>
1368 </body>
1369 </html>
1370
1371 # includes/nav.html
1372
1373 <div id="nav">
1374 You are in: {{ current_section }}
1375 </div>
1376
1377 If you render ``mypage.html`` with a context containing ``current_section``,
1378 then the variable will be available in the "included" template, as you would
1379 expect.
1380
1381 If, in an ``{% include %}`` tag, a template with the given name isn't found,
1382 Django will do one of two things:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1383
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1384 * If ``DEBUG`` is set to ``True``, you'll see the
1385 ``TemplateDoesNotExist`` exception on a Django error page.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1386
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1387 * If ``DEBUG`` is set to ``False``, the tag will fail
1388 silently, displaying nothing in the place of the tag.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1389
1390 Template Inheritance
1391 ====================
1392
1393 Our template examples so far have been tiny HTML snippets, but in the real
1394 world, you'll be using Django's template system to create entire HTML pages.
1395 This leads to a common Web development problem: across a Web site, how does
1396 one reduce the duplication and redundancy of common page areas, such as
1397 sitewide navigation?
1398
1399 A classic way of solving this problem is to use *server-side includes*,
1400 directives you can embed within your HTML pages to "include" one Web page
1401 inside another. Indeed, Django supports that approach, with the
1402 ``{% include %}`` template tag just described. But the preferred way of
1403 solving this problem with Django is to use a more elegant strategy called
1404 *template inheritance*.
1405
1406 In essence, template inheritance lets you build a base "skeleton" template that
1407 contains all the common parts of your site and defines "blocks" that child
1408 templates can override.
1409
1410 Let's see an example of this by creating a more complete template for our
1411 ``current_datetime`` view, by editing the ``current_datetime.html`` file::
1412
1413 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
1414 <html lang="en">
1415 <head>
1416 <title>The current time</title>
1417 </head>
1418 <body>
1419 <h1>My helpful timestamp site</h1>
1420 <p>It is now {{ current_date }}.</p>
1421
1422 <hr>
1423 <p>Thanks for visiting my site.</p>
1424 </body>
1425 </html>
1426
1427 That looks just fine, but what happens when we want to create a template for
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1428 another view -- say, the ``hours_ahead`` view from Chapter 3? If we want again
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1429 to make a nice, valid, full HTML template, we'd create something like::
1430
1431 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
1432 <html lang="en">
1433 <head>
1434 <title>Future time</title>
1435 </head>
1436 <body>
1437 <h1>My helpful timestamp site</h1>
1438 <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
1439
1440 <hr>
1441 <p>Thanks for visiting my site.</p>
1442 </body>
1443 </html>
1444
1445 Clearly, we've just duplicated a lot of HTML. Imagine if we had a more
1446 typical site, including a navigation bar, a few style sheets, perhaps some
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1447 JavaScript -- we'd end up putting all sorts of redundant HTML into each
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1448 template.
1449
1450 The server-side include solution to this problem is to factor out the
1451 common bits in both templates and save them in separate template snippets,
1452 which are then included in each template. Perhaps you'd store the top
1453 bit of the template in a file called ``header.html``::
1454
1455 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
1456 <html lang="en">
1457 <head>
1458
1459 And perhaps you'd store the bottom bit in a file called ``footer.html``::
1460
1461 <hr>
1462 <p>Thanks for visiting my site.</p>
1463 </body>
1464 </html>
1465
1466 With an include-based strategy, headers and footers are easy. It's the
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1467 middle ground that's messy. In this example, both pages feature a title --
1468 ``<h1>My helpful timestamp site</h1>`` -- but that title can't fit into
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1469 ``header.html`` because the ``<title>`` on both pages is different. If we
1470 included the ``<h1>`` in the header, we'd have to include the ``<title>``,
1471 which wouldn't allow us to customize it per page. See where this is going?
1472
1473 Django's template inheritance system solves these problems. You can think of it
1474 as an "inside-out" version of server-side includes. Instead of defining the
1475 snippets that are *common*, you define the snippets that are *different*.
1476
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1477 The first step is to define a *base template* -- a skeleton of your page that
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1478 *child templates* will later fill in. Here's a base template for our ongoing
1479 example::
1480
1481 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
1482 <html lang="en">
1483 <head>
1484 <title>{% block title %}{% endblock %}</title>
1485 </head>
1486 <body>
1487 <h1>My helpful timestamp site</h1>
1488 {% block content %}{% endblock %}
1489 {% block footer %}
1490 <hr>
1491 <p>Thanks for visiting my site.</p>
1492 {% endblock %}
1493 </body>
1494 </html>
1495
1496 This template, which we'll call ``base.html``, defines a simple HTML skeleton
1497 document that we'll use for all the pages on the site. It's the job of child
1498 templates to override, or add to, or leave alone the contents of the blocks.
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1499 (If you're following along, save this file to your template directory as
1500 ``base.html``.)
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1501
1502 We're using a template tag here that you haven't seen before: the
1503 ``{% block %}`` tag. All the ``{% block %}`` tags do is tell the template
1504 engine that a child template may override those portions of the template.
1505
1506 Now that we have this base template, we can modify our existing
1507 ``current_datetime.html`` template to use it::
1508
1509 {% extends "base.html" %}
1510
1511 {% block title %}The current time{% endblock %}
1512
1513 {% block content %}
1514 <p>It is now {{ current_date }}.</p>
1515 {% endblock %}
1516
1517 While we're at it, let's create a template for the ``hours_ahead`` view from
1518 Chapter 3. (If you're following along with code, we'll leave it up to you to
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1519 change ``hours_ahead`` to use the template system instead of hard-coded HTML.)
1520 Here's what that could look like::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1521
1522 {% extends "base.html" %}
1523
1524 {% block title %}Future time{% endblock %}
1525
1526 {% block content %}
1527 <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
1528 {% endblock %}
1529
1530 Isn't this beautiful? Each template contains only the code that's *unique* to
1531 that template. No redundancy needed. If you need to make a site-wide design
1532 change, just make the change to ``base.html``, and all of the other templates
1533 will immediately reflect the change.
1534
1535 Here's how it works. When you load the template ``current_datetime.html``,
1536 the template engine sees the ``{% extends %}`` tag, noting that
1537 this template is a child template. The engine immediately loads the
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1538 parent template -- in this case, ``base.html``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1539
1540 At that point, the template engine notices the three ``{% block %}`` tags
1541 in ``base.html`` and replaces those blocks with the contents of the child
1542 template. So, the title we've defined in ``{% block title %}`` will be
1543 used, as will the ``{% block content %}``.
1544
1545 Note that since the child template doesn't define the ``footer`` block,
1546 the template system uses the value from the parent template instead.
1547 Content within a ``{% block %}`` tag in a parent template is always
1548 used as a fallback.
1549
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1550 Inheritance doesn't affect the template context. In other words, any template
1551 in the inheritance tree will have access to every one of your template
1552 variables from the context.
1553
1554 You can use as many levels of inheritance as needed. One common way of using
1555 inheritance is the following three-level approach:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1556
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1557 1. Create a ``base.html`` template that holds the main look and feel of
1558 your site. This is the stuff that rarely, if ever, changes.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1559
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1560 2. Create a ``base_SECTION.html`` template for each "section" of your site
1561 (e.g., ``base_photos.html`` and ``base_forum.html``). These templates
1562 extend ``base.html`` and include section-specific styles/design.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1563
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1564 3. Create individual templates for each type of page, such as a forum page
1565 or a photo gallery. These templates extend the appropriate section
1566 template.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1567
1568 This approach maximizes code reuse and makes it easy to add items to shared
1569 areas, such as section-wide navigation.
1570
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1571 Here are some guidelines for working with template inheritance:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1572
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1573 * If you use ``{% extends %}`` in a template, it must be the first
1574 template tag in that template. Otherwise, template inheritance won't
1575 work.
1576
1577 * Generally, the more ``{% block %}`` tags in your base templates, the
1578 better. Remember, child templates don't have to define all parent blocks,
1579 so you can fill in reasonable defaults in a number of blocks, and then
1580 define only the ones you need in the child templates. It's better to have
1581 more hooks than fewer hooks.
1582
1583 * If you find yourself duplicating code in a number of templates, it
1584 probably means you should move that code to a ``{% block %}`` in a
1585 parent template.
1586
1587 * If you need to get the content of the block from the parent template,
1588 use ``{{ block.super }}``, which is a "magic" variable providing the
1589 rendered text of the parent template. This is useful if you want to add
1590 to the contents of a parent block instead of completely overriding it.
1591
1592 * You may not define multiple ``{% block %}`` tags with the same name in
1593 the same template. This limitation exists because a block tag works in
1594 "both" directions. That is, a block tag doesn't just provide a hole to
1595 fill, it also defines the content that fills the hole in the *parent*.
1596 If there were two similarly named ``{% block %}`` tags in a template,
1597 that template's parent wouldn't know which one of the blocks' content to
1598 use.
1599
1600 * The template name you pass to ``{% extends %}`` is loaded using the same
1601 method that ``get_template()`` uses. That is, the template name is
1602 appended to your ``TEMPLATE_DIRS`` setting.
1603
1604 * In most cases, the argument to ``{% extends %}`` will be a string, but it
1605 can also be a variable, if you don't know the name of the parent template
1606 until runtime. This lets you do some cool, dynamic stuff.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1607
1608 What's next?
1609 ============
1610
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1611 You now have the basics of Django's template system under your belt. What's next?
1612
1613 Many modern Web sites are *database-driven*: the content of the Web site is
1614 stored in a relational database. This allows a clean separation of data and logic
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1615 (in the same way views and templates allow the separation of logic and display.)
1616
fdc4800 @jacobian Fixed a bunch of reST markup errors.
jacobian authored
1617 The :doc:`next chapter <chapter05>` covers the tools Django gives you to
1618 interact with a database.
Something went wrong with that request. Please try again.