Now that you understand how to apply filters, let's look at some filters that allow you to format text. Django provides several different filters that allow you to manipulate and enhance the text that is rendered to the web pages.
The following sections show some examples of some of the more common filters that you can use to format text.
Often you will parse text from an object or a web request, and you need to change the text's case. Django provides several filters for doing so. The following is a list of useful filters to change the case of text in a template:
capfirst capitalizes only the first letter in the string and leaves the rest of the string alone.
title capitalizes the first letter of each word in the string and lowercases all the remaining letters.
upper changes the entire string to uppercase.
lower changes the entire string to lowercase.
The following example shows what happens with the capfirst, title, upper, and lower filters:
{{ title|capfirst}}<p> {{ title|title}}<p> {{ title|upper}}<p> {{ title|lower}}<p>
When these filters are applied to a variable title with a value of teST titLE, the following HTML code is rendered:
TeST titLE<p> Test Title<p> TEST TITLE<p> test title
By the Way
Notice that the capfirst filter results in TeST titLE. You could pipe the title variable through the lower filter first to render title as Test title:
{{ title|lower|capfirst}}<p>
The escape filter allows you to escape HTML code in a string so that the code appears in the view as text. The web browser does not parse the HTML code in the text. This can be useful if you want to display HTML code as part of the view.
The HTML characters in the string are replaced with the HTML escape codes. The < character is replaced with <, the > character is replaced with >, and so on. The result is that the HTML tags in the filtered block of text show up as text in the web page.
For example, the following template code results in the HTML code being displayed in the browser, as shown in Figure 9.1:
<h2>The following code:</h2><p> {% filter escape %} <li>List Item1</li> <li>List Item2</li> <li>List Item3</li> <li>List Item4</li> <li>List Item5</li> {% endfilter %} <h2>Generates this list:</h2> <li>List Item1</li> <li>List Item2</li> <li>List Item3</li> <li>List Item4</li> <li>List Item5</li>
The length filter returns the length of the object being filtered. If the object is a string, it returns the number of characters in the string. If the object is a list, it returns the number of elements in the list.
The length filter is especially useful for formatting HTML elements around the length of a string or the number of items in a list. An example of how length can be used to format HTML elements is using the length of a list to define the number of columns to span in a table. If you pass into the template a list of headers and a title, you can use the following code snippet to build the table and span the title row across all the columns that the headers form:
<table> <tr> <td colspan="{{ headers|length }}">{{ title }}</td> </tr> <tr> {% for h in headers %} <td>{{ h }}</td> {% endfor %} </tr> </table>
The linebreaks filter replaces the line breaks in plain text with the HTML line break <br />. Because the HTML parser ignores line breaks and allows the text to run together, the linebreaks filter is indispensable when you render large amounts of text.
The linebreaks filter does not accept any arguments. For example, to apply the linebreaks filter to a variable called data, use the following syntax:
{{ data|linebreaks }}
By the Way
If the linebreaks filter encounters two consecutive line breaks, it replaces them with an HTML paragraph <p>.
The stringformat filter formats the variable according to the Python string formatting syntax specified as an argument. The stringformat filter accepts only one argument—a valid Python string formatting operation with the leading % character dropped.
The best way to illustrate the string format function is with the following examples, where the value of num is 380:
int = {{ num|stringformat:"i" }} hex = {{ num|stringformat:"x" }} padded = {{ num|stringformat:"08X" }} prec2float = {{ num|stringformat:"2.f" }}
This renders the following:
int = 380 hex = 17c padded = 0000017C prec2float = 380.00
Did you Know?
You can find more information about the Python string formatting options at: http://docs.python.org/lib/typesseq-strings.html.
The striptags filter removes all (X)HTML tags from a string of text. The striptags filter can be used for several purposes. One of the best uses is to clear out HTML codes before displaying text that was retrieved from an unsecured source, such as a user form. You can protect against users adding HTML code that could pose problems.
For example, if you accept blog entries and then display them, you can use the following line of code to render the blog text without any HTML elements the user may have added:
{{ blog.text|striptags }}
Did you Know?
Django also includes the removetags filter, which allows you to remove specific HTML codes from text. The removetags filter accepts a list of space-separated codes. For example, the following line of code removes all the <li>, <p>, and <br> tags from blog.text:
{{ blog.text|removetags:"li p br"}}
The wordwrap filter allows you to specify a length at which lines of text should wrap. When the wordwrap filter renders text, it determines if the next word will exceed the maximum line length. If it will, the filter enters a line break after the current word.
For example, to render text with a maximum line length of 40, you would use the following line of code:
{{ text|wordwrap:"40" }}
The wordwrap filter adds only plain-text line breaks to the text. If you want to wrap the text inside an HTML element such as a table cell, use the linebreaks filter also:
{{ text|wordwrap:"40"|linebreaks}}
The pluralize filter is used to add a plural suffix if the value of a variable is not 1. This can be useful in adding a human element to the website by eliminating messages such as "You have 1 unread messages." Using the pluralize filter enables you to write code in your template to print the message correctly. For example:
You have {{ msgNum }} unread message{{ msgNum|pluralize }}
If the value of msgNum is 1, the template renders "You have 1 unread message." If the value of msgNum is 3, the template renders "You have 3 unread messages."
The default suffix is s, but the pluralize filter also accepts a comma-separated list. If only one argument is passed into the pluralize filter, it is treated as the alternate string to apply for plural values. The following example uses the plural suffix es instead of s:
I rode {{ busCnt }} bus{{ busCnt|pluralize:"es" }}
The pluralize filter can also handle cases when a singular suffix must be applied. If two arguments are passed into the pluralize filter, the first argument is treated as the singular suffix, and the second is treated as the plural suffix. For example, if you wanted to render the string "Updated # entry(ies)" in a more user-friendly format, you could use the following pluralize filter:
Updated {{ eNum }} entr{{ eNum|pluralize:"y,ies" }}
By the Way
The length filter can help a lot with the pluralize filter. For example, if all you have is a list of entries, you could apply the length filter to the list first to get a count to use for the pluralize filter:
entr{{ entries|length|pluralize:"y,ies" }}
The yesno filter can be applied to a variable. It accepts either a "yes,no" or "yes,no,maybe" string of arguments. The yesno filter tests the variable and renders the yes string if the variable is true, the no string if the variable is false, and the maybe string if the variable value is none. If only a "yes,no" string is passed, the filter renders the no string if the variable value is none.
For example, the following line of code renders the string It is true if the variable is true and the string It is false if the variable is not true:
{{ var|yesno:"It is true,It is false" }}
Obviously, the variable can be a Boolean True or False value, and it can be a None value. If the variable is in numeric form, a value of 0 renders the no string, and any other value renders the yes string. If the variable is a list or dictionary, if the variable is empty, the no string is rendered. If the variable has at least one entry, the yes string is rendered.
The yesno tag may seem simple, but it can be used in many creative ways to save a lot of code. The following code snippet shows an example of using the yesno tag in a for loop to build a table:
{% for i in myList %} {{ forloop.first|yesno:"<table>,"}} <tr><td>{{ i }}</td></tr> {{ forloop.last|yesno:"</table>,"}} {% endfor %}
If the <table> tags in the preceding example were placed outside the for loop, they would appear in the rendered text even if there were no items in the text to render. The yesno filter lets you place the <table> tags only if you are on the first or last item in the list.
The preceding example shows a couple of things. One is that the yesno filter accepts an empty string as one of its arguments. The other is that you can use HTML code in the string.
Try It Yourself: Add Text Formatting Filters to TemplatesIn this section, you will extend the person_details.py template to include the friends and blogs fields of the Person object. You will also use text formatting filters to enhance the text that is rendered by the template: Follow these steps to modify the person_details.py template:
By the Way If you haven't already created some more users, you might need to do so. You might want to use the admin interface to create the new objects. To add blog entries, you may need to enable the admin interface for the blog class, as discussed in Hour 3, "Adding Models and Objects to Your Website." Listing 9.1 shows the complete person_details.py file. Listing 9.1. Full Contents of iFriends/template/person_details.py
|