Author avatar

Gaurav Singhal

Create Custom Template Tags and Filters in Django

Gaurav Singhal

  • Nov 24, 2020
  • 6 Min read
  • 585 Views
  • Nov 24, 2020
  • 6 Min read
  • 585 Views
Web Development
Django
Back End Web Development
Server-side Frameworks

Introduction

The Django template language offers a wide range of built-in tags and filters for designing the presentation layer of your Django app. However, your app may need a functionality that is not included in the core set of template primitive language. Django allows you to create your own set of custom tags and filters using Python, and make them available in the Django templates.

This guide will demonstrate how to create custom template tags and filters, and how to load them in templates.

Getting Started

Inside your Django app directory, create a module called templatetags and add an empty __init__.py file as shown in the below directory structure.

Note: Make sure that you have included your app in INSTALLED_APPS available in settings.py .

1
2
3
4
5
6
7
8
my_app/
├── __init__.py
├── admin.py
├── models.py
├── templatetags/
│   ├── __init__.py
│   └── custom_tags.py
└── views.py

Next, open the custom_tags.py file and add these two lines to get started with custom template tags and filters.

1
2
3
from django import template

register = template.Library()
python

Make custom_tags available by loading it in templates.

1
{% load custom_tags %}
django

Writing Custom Template Filters

Filters are nothing but a Python function, which takes one or two arguments. For instance, in the filter {{var|filter_f:arg}} , the filter filter_f would be passed to the variable var and argument as arg.

For demonstration, create a filter to modify a string based on the argument. Create a simple view in views.py, that renders a string as follows:

1
2
3
4
5
def my_view(request):
    context = {
        "author": "gaurav singhal",
    }
    return render(request, "index.html", context)
python

After creating views, create a simple template filter named modify_name in custom_tags.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django import template

register = template.Library()

def modify_name(value, arg):
    # if arg is first_name: return the first string before space
    if arg == "first_name":
        return value.split(" ")[0]
    # if arg is last_name: return the last string before space
    if arg == "last_name":
        return value.split(" ")[-1]
    # if arg is title_case: return the title case of the string
    if arg == "title_case":
        return value.title()
    return value
    
register.filter('modify_name', modify_name)
python

You can now use the modify_name filter in your templates.

1
2
3
4
5
6
7
8
{% comment %} index.html {% endcomment %}

{% load custom_tags %}

{{ author | modify_name:"first_name"}}<br>
{{ author | modify_name:"last_name"}}<br>
{{ author | modify_name:"title_case"}}<br>
{{ author | modify_name:"first_name" | modify_name:"title_case"}}<br>
django

This will give the output as follows:

1
2
3
4
gaurav
singhal
Gaurav Singhal
Gaurav

Likewise, you can create your template filters, and then you can use them in your templates.

Writing Custom Template Tags

Template tags are more powerful and more complex than filters. Django supports several shortcuts for making most of them easier.

simple_tag

simple_tag takes several arguments and returns a result after doing some processing. Below is a simple example to display the current date and time in the template

1
2
3
4
5
6
7
8
9
# custom_tags.py
from django import template
register = template.Library()

import datetime

@register.simple_tag
def current_time(format_string):
    return datetime.datetime.now().strftime(format_string)
python

Next, use the above custom template tag into your template as follows:

1
2
3
4
5
{% comment %} index.html {% endcomment %}

{% load custom_tags %}

{% current_time "%d/%m/%Y %H:%M:%S %p" %}
django

This will give you the current date and time when you run the Django server.

1
17/11/2020 14:15:59 PM

inclusion_tag:

inclusion_tag is a common type of template tag, and helps in displaying data by rendering another template. This tag is useful in scenarios when you want to render data that is common in several pages.

In the example below, the Users table is rendered by creating a new template named users.html using the show_users_table template tag. The custom_tag.py is modified as given below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# custom_tags.py
from django.contrib.auth import get_user_model
from django.template.loader import get_template

from django import template
register = template.Library()

User = get_user_model()

def show_users_table():
    users = User.objects.all()
    return {'users': users}

users_template = get_template('users.html')
register.inclusion_tag(users_template)(show_users_table)
python

Next, create a new template named users.html and render the users in a tabular format.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{% comment %} users.html {% endcomment %}

{% load custom_tags %}

<table>
    <thead>
        <tr>
        <td>Username</td>
        <td>First name</td>
        <td>Last name</td>
        <td>email</td>
        </tr>
    </thead>
    <tbody>
        {% for user in users %}
        <tr>
            <td>{{user.username}}</td>
            <td>{{user.first_name}}</td>
            <td>{{user.last_name}}</td>
            <td>{{user.email}}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
django

Now, you can use the above inclusion tag in any other template (say index.html) as shown below.

1
2
3
4
5
{% comment %} index.html {% endcomment %}

{% load custom_tags %}

{% show_users_table %}
django

This will render the user in a tabular manner as shown below.

1
2
Username	    First name	Last name	email
gaurav_singhal	Gaurav	    Singhal	    [email protected]

Conclusion

Django custom template tags and filters are the best way to create tags and filters that you may need in your Django app. If you are new to Django templates, read this guide. You can refer to the Django documentation on custom template tags and filters for more understanding. If you have any queries, feel free to reach out at Codealphabet.

6