Flask by Example: Jinja Custom Filters
Filters modify variables before they are rendered (e.g., formatting dates or capitalizing text). Flask allows you to define your own custom filters to handle application-specific formatting logic.
Code
from flask import Flask
import datetime
app = Flask(__name__)
# 1. Define the filter function
def reverse_string(s):
return s[::-1]
# 2. Register the filter
app.jinja_env.filters['reverse'] = reverse_string
# Alternative: Using the decorator
@app.template_filter('format_date')
def format_date_filter(dt, fmt='%Y-%m-%d'):
if isinstance(dt, datetime.datetime):
return dt.strftime(fmt)
return dt
@app.route('/')
def index():
return render_template_string('''
<p>Original: {{ name }}</p>
<!-- 3. Using the custom filter -->
<p>Reversed: {{ name | reverse }}</p>
<!-- Chaining filters -->
<p>Reversed & Upper: {{ name | reverse | upper }}</p>
<!-- Filter with arguments -->
<p>Date: {{ now | format_date('%B %d, %Y') }}</p>
''', name="Flask", now=datetime.datetime.now())Explanation
Custom filters allow you to encapsulate formatting logic in Python functions and use them directly in your templates. You can register them either by adding them to app.jinja_env.filters or by using the @app.template_filter() decorator.
Filters are applied using the pipe character | and can be chained together to perform multiple transformations. For example, {{ name | reverse | upper }} applies the reverse filter and then the upper filter to the name variable.
They accept arguments just like regular functions, providing a powerful way to transform data. This keeps your templates clean and focused on presentation logic rather than data manipulation.
Code Breakdown
app.jinja_env.filters['reverse'] registers the function. The key 'reverse' is the name you will use in the template.@app.template_filter('format_date') is the decorator approach. It's often cleaner. The string argument is the filter name; if omitted, the function name is used.{{ name | reverse }} applies the filter. If name is "Flask", the output is "ksalF".format_date('%B %d, %Y') shows how to pass arguments to a filter. The value now is passed as the first argument (dt), and the string is passed as the second (fmt).
