Computer scienceBackendFlaskTemplates

Jinja filters

8 minutes read

When creating a web application, data is generated or stored in a standardized format. But when it's displayed to users, we need to transform it into a different form. This is when Jinja filters come in.

Filters

Filters are modifiers to manipulate the data inside variables. They can be used to change the data appearance, filter some values, or even generate new ones. To apply a filter, simply put a vertical bar (|) between the variable name and the filter name in the template.

Here is a simple filter, reverse, which, as the name suggests, reverses the order of letters in a string.

Filters are similar to usual Python functions, the only difference is their syntax. The following is the Python equivalent of the reverse filter:

def reverse(text):
  return text[::-1]

reverse("rats")

Function

Filter

filter(value)

{{value | filter}}

filter(value, other_args)

{{value | filter(other_args)}}

filter2(filter1(value))

{{value | filter1 | filter2 }}

Why use filters? Why not just define functions from scratch and call them in the backend every time we need to alter data? There are several reasons:

  1. Filters make life easier. They are not buggy. These filters are tested thoroughly and are used by many people;

  2. They are easy to use. Even beginners can easily manipulate them;

  3. Filters offer a way to alter the way data is presented on the go without having to change the backend.

Built-in and custom filters

Jinja comes with plenty of built-in filters. Reverse is just one of them.

Another one is join. Given variable var1 = [1,2,3] this is what using the filter inside a template would look like: {{var1 | join("|")}}. The output result rendered on a page then will be 1|2|3.

For a full list of Jinja's built-in filters, as well as their detailed description, you can visit Jinja's official documentation page. Here is a short list of some important ones.

capitalize

Capitalizes the first letter of the word

default

Checks if the value is undefined

dictsort

Sorts a dictionary

format

Used for formatting string

map

Applies a filter on a sequence

join

Concatenates a sequence

replace

Replaces a sub-string with a new value

trim

Removes leading and trailing white space.

You can also construct your customs filters. Just follow these two steps as shown in the examples.

  • Create a function that takes the value and returns the new, desired output.

    #app.py
    
    app = Flask(__name__)
    
    def caps(text): #filter function
      return text.upper()
    
    @app.route("/")
    def index():
      return render_template("index.html")
    

    Always define your filter function before rendering the template.

  • Add the function to the Jinja environment using either of these two methods:

With a decorator: @app.template-filter('name') where 'name' will be used to refer to the filter inside the template

@app.template_filter("up") # add this to the top of the filter function
def caps(text): #filter function
  return text.upper()

Or with jinja_env.filters:

def caps(text): #filter function
  return text.upper()
env = app.jinja_env #define the jinja enviroment
env.filters["up"] = caps #add the filter to the enviroment

To apply our new filter, we put {{"filter" | up}} in the template index.html and the result will be 'FILTER'

Date-time formatter

Let's now build a common application of filters, a date-time formatter, on which we utilize a custom-made filter.

Let's say we have a date object that we get from some source in our web application. What we will do is format this date using filters to our desired format. For this example, we will get the data from the Python datetime package and transform it in the template using a custom-made filter:

App.py:

from flask import Flask,render_template
from datetime import datetime

date = datetime.now() #the date object we want to transform


app = Flask(__name__)

@app.template_filter("prettify_date")
def do_pretty(value, format): #filter
    return value.strftime(format)
    

@app.route("/")
def index():
    return render_template("home.html" ,date = date ) #pass the variable to the template



if __name__ == "__main__":
    app.run(debug = True)

We can use the following format for the data: %B %d , %Y which displays the date as month_name day, year

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Today</title>
</head>
<body>
<p>Today is : {{date | prettify_date("%B %d , %Y")}} </p>
</body>
</html>

The output of this template is January 1 , 1111

If your filter takes two or more arguments, the first one will always be the value you put before the pipe | in the template.

 filter with two or more arguments

We can also form nested filters, and they are applied from left to right!

nested filters

Conclusion

We can use filters to modify data into any format we want. They are functions with different syntaxes and can be used to generate new data as well as rearrange the ones that already exist. Here are a few main tips to follow whenever using filters:

  • Make sure your code is readable. Avoid using long nested filters in your template;

  • Whenever possible, use the built-in filters instead of creating new ones. Jinja has included various filters that can be useful for almost anything you might need.

  • If you have more several custom-made filters, it's better to create a separate filters.py or utils.py file and put everything inside it.

8 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo