Custom Template Tags and Filters in Django

Custom Template Tags/Filters are necessary when there is a need to modify the object received from views context, such that it suits the needs of rendering them in the template. Django’s out-of-the-box tags/filters might not always suffice. The custom tag/filter can be registered in Django’s tags or filters Library and used in the templates. Let’s learn something about writing our own tags and filters. Let me start off from the beginning:

  • Create a new Django Project:
django-admin startproject <proj_name>
  • Create an app in the project:
python manage.py startapp temptags
  • Add the App to INSTALLED_APPS in settings.py
  • Create a templatetag folder inside the app folder.
  • Create a __init__.py file to treat the folder as python package.
  • Create a ‘templates’ folder to add the html files
  • urls.py
from django.urls import pathfrom . import views

urlpatterns = [path('',views.sampleTemptag),]
  • views.py
from django.shortcuts import render

def sampleTemptag(request):
    context = {
        "name": "My name is Agnes.000123",
        "id": "89752358-1234",
        "fullname": "Agnes George Sequera"}
    return render(request,'main.html',context)

Now that the basic Django Project is ready, lets return to the temptags folder.

  • Create a file custom_filters.py in the temptags folder. This is where we will define our custom tags and filters.
  • Next, the html file needs to know the filename where the custom tags/filters are written, in order to use them. Hence, add the following to your main.html file.
{% load custom_filters %}

Custom Filters

The custom_filters.py file must contain a variable called register that should be an instance of  template.Library.

from django import template
register = template.Library()

The custom template function will take two inputs, the expected value and an argument. The @register.filter is a decorator that registers the function with the Library instance and makes it available in Django’s template language. It accepts the name of the filter as argument. It can also be left empty which leads to the function name being used as the name of the filter by default.

Lets define a filter that takes a string and returns all the words present in the string as a list. The default separator is considered as a space. However, it can take any other separator.

@register.filter(name='get_list')
@stringfilter
def get_list(arg,sep=" "):
    return arg.split(sep)

@stringfilter: Those functions which explicitly work with strings can use the @stringfilter decorator. This will convert the input into String before passing it to the function.

In the main.html file, we will use the custom tag as follows:

<p align="center">Full Name: {{ fullname|get_list:"-" }}</p>

get_list is the name of the filter. We specify the argument, which is the separator (sep) after the semicolon. Though the default separator in the function is a space, because we have explicitly specified it to be a hyphen (“-“) in the argument, “fullname” will be split by hyphen and returned as a list.

Also, if your custom filter is working with datetime objects, the argument expects_localtime=True to the @register.filter decorator can explicitly convert the datetime object into the local timezone before passing the datetime object to the function.

@register.filter(expects_localtime=True)
def AddFourHours(value):
    <....>

Custom Tags

Simple tags:

To create a simple tag, we need to use the simple_tag helper provided by the Django templates Library. A simple tag can take any number of arguments.

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

Here’s how we use it in the html file. We can also store it in a variable and use that as the output, rather than the entire tag.

{% get_current_time "%Y-%m %d %I:%M %p" as time %}        
<p align="center">Time is: {{ time }}</p>

Inclusion tags is another rarely used type of custom tags. You can find the documentation for Inclusion tags here: https://docs.djangoproject.com/en/3.2/howto/custom-template-tags/#inclusion-tags

Link to the Github repo where you can find the entire code: https://github.com/shilpavijay/Custom-Temp-Tags

Advertisement

One thought on “Custom Template Tags and Filters in Django

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s