Chapter 8. Using Built-in Template Tags to Enhance Views

<feature><title>What You’ll Learn in This Hour</title> <objective>

How to use for loops to generate HTML code from lists

</objective>
<objective>

How to use if logic to add conditional HTML code to templates

</objective>
<objective>

How to add dynamic links to templates

</objective>
<objective>

How to reduce template code by using the with tag

</objective>
<objective>

How to add cycling behavior to enhance table views

</objective>
</feature>

Django has several tags that allow you to implement some basic logic in your templates that helps you reduce the amount of HTML code that you need to write. This hour covers using Django’s built-in template tags to create more complex and useful templates.

Implementing Loops

One of the most common tags that you will use will be the for tag to implement for loops inside your HTML documents. The for tag allows you to navigate through a list of strings or objects and generate HTML code for each item in the list.

For example, if you have a list of several URLs for which you want to write HTML links in a template, you could implement a for tag similar to the following code snippet, where links is a list object:

{% for lnk in links %}
    <li><a href="{{ lnk }}"> {{ lnk }}</a></li>
{% endfor %}

Using this code in your template renders the list of links in the HTTP response. It doesn’t matter how many links you need to put in the list. You do not need to add code to your HTML template to do so.

By the Way

You can add as many lines of code inside the for tag section as are needed and then add the {% endfor %} tag to close the section.

The for tag can also handle dictionary objects. Use the following syntax:

{% for key, value in dict %}

For example, if you have a dictionary containing people’s names as the key and phone numbers as the value, you could use the following code snippet in a template to render the list of names and phone numbers:

{% for name, phone in phoneList %}
    <h2>Name:  {{ name }} </h2>
    <li>Phone:  {{ phone }} </li>
{% endfor %}

Did you Know?

You can access the items in a list in reverse order by using the reversed tag in a for tag statement. For example, the following code displays the entries in the books list in reverse order:

{% for title in books reversed %}

Django also allows you to use for loops to process lists of lists as long as you can unpack the values in each sublist into a set of names. For example, if you have a list of GPS coordinates that are formatted as a [location, lat, long] list, you could use the following code snippet in a template to render the list of GPS locations:

{% for location, lat, long in gpsList %}
    <h2>Location:  {{ location }} </h2>
    <li>Coordinates:  {{ lat }}:{{ long }}</li>
{% endfor %}

Django provides the forloop variable in loop operations. It can provide you with information such as counters and parent loops. Table 8.1 lists the available fields in the forloop variable object.

Table 8.1. Fields Available in the forloop Variable

Variable

Description

forloop.counter

The loop’s current iteration (1-based index)

forloop.counter0

The loop’s current iteration (0-based index)

forloop.revcounter

The number of iterations from the end of the loop (1-based index)

forloop.revcounter0

The number of iterations from the end of the loop (0-based index)

forloop.first

Is true if this is the first iteration through the loop

forloop.last

Is true if this is the last iteration through the loop

forloop.parentloop

Accesses the forloop object in the loop before the current one (used when nesting loops)

Implementing if Logic

Django also provides rudimentary if logic to the template parser. You can use the if, ifchanged, ifequal, and ifnotequal tags to determine how and if content should be displayed. The following sections describe the different types of if tags and their uses.

Using if

The if tag evaluates a variable and determines if it is true. If the variable evaluates to true, the template engine renders the code inside the if block. You need to add an endif tag to end the block. You can also use the optional else tag with all the if tags to provide alternative template code.

For example, suppose your template is expecting a list of cars called carList. You could use the following code snippet to determine if the car list is empty and note that in the web page, instead of just having a blank section in the web page:

{% if carList %}
    {% for car in carList %}
        <li>{{ car.model }}</li>
    {% endfor %}
(% else %}
    No cars in list.
{% endif %}

You can use a not operator in the if tags to change the if logic. For example, the preceding code snippet could also be written as follows:

{% if not carList %}
   No cars in list.
 (% else %}
     {% for car in carList %}
        <li>{{ car.model }}</li>
    {% endfor %}
{% endif %}

You can also use or and and operators in the if tags to chain together logic. For example, if you want to display a list only if both teacherList and studentList have entries, you could use the following code snippet:

{% if studentList and teacherList %}
    <h2>Students</h2>
    {% for s in studentList %}
        <li>{{ student }}</li>
    {% endfor %}
    <h2>Students</h2>
    {% for s in studentList %}
        <li>{{ student }}</li>
    {% endfor %}
{% endif %}

Using ifchanged

The ifchanged tag is used inside for loops to determine if a variable value has changed since the last iteration. If the value has changed, the template engine renders the code inside the ifchanged block. You need to add an endifchanged tag to end the block.

For example, if your template is parsing blog entries that contain a date field, you could use the following code to note the change in dates:

{% for b in blogList %}
    {% ifchanged b.date.date %}
        <h2>Date: {{ b.date.date }} </h2>
    {% endifchanged %}
    <h1>{{ b.title }}</h1>
    {{ b.text }}
{% endfor %}

Did you Know?

The ifchanged tag can also determine if its own rendered contents have changed. Instead of specifying variable(s) inside the tag statement, you just need to add the variable(s) inside the ifchanged block. If they change, the content changes from the last state and is rendered again by the template engine. For example:

{% ifchanged %}<h3>{{ b.date }}</h3> {% endifchanged %}

Using ifequal

The ifequal tag determines if two arguments are equal. The arguments can be either variables or hard-coded strings. If the arguments match, the template engine renders the code inside the ifequal block. You need to add an endifequal tag to end the block.

For example, if your template is parsing a list of users, and you want only users who have a last name of Arthur, you could use the following code snippet:

{% for user in userList %}
    <h1>Arthurs</h1>
    {% ifequal user.last "Arthur" %}
        <li>{{ user.first }}</li>
    {% endifequal %}
{% endfor %}

Using ifnotequal

The ifnotequal tag determines if two arguments are not equal. The arguments can be either variables or hard-coded strings. If the arguments do not match, the template engine renders the code inside the ifnotequal block. You need to add an endifnotequal tag to end the block.

For example, if your template is parsing a list of blogs, and you want to exclude blogs with the title of “test,” you could use the following code snippet:

{% for blog in blogList %}
    {% ifnotequal blog.title "test" %}
        <h1>{{ blog.title }}</h1>
        {{ blog.text }}
    {% endifnotequal %}
{% endfor %}

Adding Links with the url Tag

Django provides the url tag to help you add links to your web pages. If possible, it is best to avoid hard-coded links. If you modify the URLconf file and thus change the URL pattern, you might wind up needing to change every place in your code that you hard-coded the link.

To solve this problem, the url tag allows you to specify the view function, including arguments, directly. The url tag results in an absolute URL being placed in the rendered HTML document.

The first argument inside the url tag is a path to a view function, such as the path to the details() function in the views.py file of the People application in the iFriends project:

iFriends.People.views.details

Additional arguments are optional and should be separated by commas with no spaces. Arguments are considered positional unless you specify a keyword=value. For example:

{url mySite.arch.views.list arg1,arg2,year=2008 %}

By the Way

If you are using named URL patterns, you can refer to the name of the pattern in the url tag instead of using the path to the view.

The arguments specified in the url tag must correspond to what is defined in the URLconf file. If they do not, no URL is returned.

Watch Out!

The url tag searches for the first match in the URLconf file. If multiple patterns are pointing to the same view, either use named patterns, or make certain that the first one in the list is the one you want.

Reducing Code Using the with Tag

Another template tag that you will find useful is with. The with tag allows you to assign a complex variable name a simpler one. This is most helpful when you have to reference the object several times.

For example, consider the business.accounting.contact_info subobject. Referencing that object several times would take a lot of keystrokes. The following example shows how to use the with tag to reduce the code necessary to reference the object:

{% with business.accounting.contact_info as ci %}
Phone: {{ ci.phone }}
Email: {{ ci.email }}
Website: {{ci.URL }}
{% endwith %}

Adding Cycle Logic to Tables

The cycle tag is a useful tool if you need to modify values as you cycle through a list. The cycle tag accepts a comma-separated list of arguments that will be cycled through.

For example, if you were creating a large table in your template and you wanted each row of the template to use a different background color, you could use the cycle tag to set the bgcolor value of the rows. The following code generates the web page shown in Figure 8.5:

<table width=100%>
{% for line in report %}
    {% if forloop.first %}
    <tr bgcolor="aaaaaa">
    {% else %}
    <tr bgcolor="{% cycle eeeeee,cccccc %}">
    {% endif %}
    {% for item in line %}
        <td>{{ item }}</td>
    {% endfor %}
    </tr>
{% endfor %}
</table>
Table generated with alternating dark and light lines using the cycle tag.

Figure 8.5. Table generated with alternating dark and light lines using the cycle tag.

Summary

In this hour, you learned how to use template tags to add logic in your templates. You learned how to generate several lines of HTML code from a list using the for tag. You also learned how to add HTML code conditionally using the if, ifchanged, ifequal, and ifnotequal tags.

Using loops, conditions, and other tags enables you to write simpler and more useable code and makes it easier to modify and update your website.

Q&A

Q.

Can I still use the {{ and {% character sets as text in my web pages?

A.

Yes. Django provides the templatetag tag to output character sets defined by the template to the rendered HTML. The following code shows how to use templatetag to output the {% character set:

{% templatetag openblock %}

Q.

Is there a way to add text to a template without displaying it in the rendered file?

A.

Yes. You can use the comment and endcomment tags. Anything between them will not get rendered.

Q.

Is there a way to quickly remove extra white spaces from the rendered text so that the HTTP response is smaller?

A.

Use the spaceless and endspaceless tags. The white spaces, including end-of-line characters, are removed from the HTML code between those tags.

Workshop

The workshop consists of a set of questions and answers designed to solidify your understanding of the material covered in this hour. Try answering the questions before looking at the answers.

Quiz

1.

Which template tag would you use to recursively add HTML code for items in a list?

2.

What method should you use to add links to other views in a template?

3.

Which tag could you use to reduce the number of keystrokes necessary to write a template when you have objects with long names?

Quiz Answers

1.

The for tag.

2.

You should use the url tag method so that you can directly reference the view.

3.

The with tag.

Exercises

1.

Use the cycle tag to modify the person_index.html file so that every other line in the list is a different color.

2.

Use the url tag to modify the iFriends_base.html file so that the word Home that appears in the website banner is actually a link to the iFriends.People.views.index view.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.138.144