Filters for Modifying Data
00:00 In the previous lesson, I showed you how to use inheritance and inclusion to compose pieces of templates together. In this lesson, I’ll introduce you to value filters.
00:11
A filter is applied to a value, altering how it is rendered in some way. You use the pipe symbol (|
) to apply a filter, similar to how pipes chain commands together in Unix.
00:23 Some filters take arguments, and these use parentheses like a function call. If the filter doesn’t need arguments, you leave the parentheses off. Jinja2 comes with a large library of filters, and this is just some of them. In a moment, I’ll show you how to use every one of these.
00:45
Before doing that, though, there is one tag I’d like to introduce first. The {% set %}
tag allows you to define values within the template.
00:54
A common use of {% set %}
is to take one value, run it through one or more filters, and store the result for use elsewhere in the template.
01:05
Okay, another lesson, another view. It’s time to visit the library. The context has a couple of lists and a string and renders library.html
.
01:16 Let’s look at the corresponding template.
01:24
This template starts out by extending nav_base
like you learned about in the previous lesson. The first filter I’m going to show you is called batch
.
01:34
When batch
is applied to an iterable, it gives access to the contents of that iterable a chunk at a time. batch
with the argument 3
takes the content of textbooks and creates a smaller iterable with three items inside of it.
01:49
The for
loop here then puts that value in a variable named triplet
. batch
is handy when you need to do groupings.
01:57
Do you have a list that needs to turn into rows and columns in a table? Well, batch
is the answer. Since batch
returns an iterable, you can’t use its result directly.
02:08
You’re going to get a list back. What if you want to print out the contents of that list? Well, just like Python’s join()
function, Jinja2 has a join
filter.
02:18
My line here will take the three things in triplet
and join them in a string with comma-separated values.
02:27
It hears that {% set %}
tag I mentioned in practice. It’s creating a new variable called first_book
, which is based on the magicbooks
value from the context.
02:37
The magicbooks
value has the filter named first
applied, which returns the first value in an iterable. I then chain another filter after that, applying upper
to the result of the first
filter. The upper
filter is like str.upper()
, so the first_book
value contains an all-uppercase version of the first item in the magicbooks
list. And because I set it using the {% set %}
tag, I can use it like any other value in the template.
03:10
Inside of mustache braces ({{}}
), you can use dot notation (.
) to access the attributes of an object. You can also use it to access the portion of an iterable.
03:20
magicbooks.1
gives the second item in the magicbooks
list, similar to magicbooks[1]
in Python. The resulting value here then gets filtered through capitalize
.
03:34
capitalize
is like its string counterpart, giving the value a capital letter first and then everything else being in lowercase.
03:43
You can probably guess what this does based on the previous examples. last
gives the last item in an iterable, and lower
returns the all-lowercase version of the string.
03:54
The length
filter returns the length of an iterable, while the reverse
filter returns an iterable in reverse order. Here I’m once again joining the result into a comma-separated value string.
04:09
You can also sort. sort
has an optional reverse
argument, meaning to sort in descending order. The truncate
filter shortens a value.
04:19 It takes a few different parameters, so you can muck about with whether it works on word boundaries and whether you allow some tolerance and some other stuff.
04:27
In this simplest of its forms, I’m limiting the result to six characters long. If a value got truncated, a ...
gets shown. The ...
is included in the length being truncated, so in this case, you’ll get the first three characters of the first item in magicbooks
and then ...
.
04:50
The wordcount
filter applies to a single string—hence why I joined the iterable first—and counts the words inside. It’s a little dumb though, and you might not get the number you expect.
05:02
You’ll see what I mean when I render the page. The default filter provides a value if the item being referenced is not in the context. There is no other_books
value, so instead, here you would get the 'No other books'
message.
05:19
This is just a normal output of the value, but if you were paying close attention inside of the view, this value had some HTML-like stuff in the string. To protect you from messing up your page, Jinja2 automatically escapes HTML characters by default, so statement
here will show on the page the same way it did in the code.
05:41
Alternatively, if you actually want to render the HTML unescaped, the safe
filter lets you do that. Or depending on your usage, you can URL encode the content instead.
05:55 That was quite a lot. Well, let’s go take a look at the resulting page.
06:09
Still inheriting from nav_base
, so I get my title and my nav, and then inside the library, I start out with the textbooks here. The textbooks are batched into groups of three.
06:23
And now with the magic books … This is the first magic book processed through the upper
filter, the second magic book processed through capitalize
, and the last book processed through lower
.
06:37
This is the length
filter showing that there are three books in the magicbooks
list. Here is the reversed list and the sorted list, descending. Note the square brackets ([]
) here.
06:50
I didn’t turn this into a string, so it’s outputting the iterable as a list instead. In all the other cases, I used join
, and that’s the difference. Here, Grim’s Traps gets truncated. The upper limit on the truncation was six, and so you get three characters and the ellipsis.
07:10 And the last part of this section is the problematic word count. This is counting Love spells, GRIM’S TRAPS, and exorcism. Personally, I count that as five. I suspect the apostrophe is what’s throwing this off.
07:25
Inside the Other Books section, you see the default filter being applied, so you get the message because there was no other_books
value. And down at the bottom here is the three variations on the statement.
07:38 The first one is the value, which was escaped automatically. This is the string as it was shown in the Python. The second treats the string as safe HTML, and as a result you get the actual anchor tag.
07:54 And the last is the same thing, but URL encoded instead. And
08:02 that was filters. Next up is the function-like macro capability.
Become a Member to join the conversation.