How do you create a custom template tag in Django? I guess this question brought you here.

 

In my previous article, I talked about how to create custom template filters in Django which is kinda similar to this one because they are both used in the template.

 

Django provides a handful of template tags such as {% if %} and {% block %} which are very useful but on rare occasions, you would need to create yours to match your particular business logic. In this post, I will be explaining in the best way possible how to create a custom template tag in Django.

 

Before creating a template filter or tag, you should first create a directory named templatetags inside an app (same level with models.py, views.py files) that has been added to the INSTALLED_APPS.

 

Inside the directory, create an empty __init__.py file to tell python to treat the directory as a package and all its .py files as a module. Then, you could create a new python file that would contain the custom filters and tags; let's call it anyname.py.

 

exampleapp/
    __init__.py
    models.py
    templatetags/
        __init__.py
        anyname.py
    views.py

 

For the custom tag created to be valid, the anyname.py file must contain a module-level variable named register that is a template.Library instance, in which all the tags and filters are registered.

 

from django import template
 
register = template.Library()

 

Secondly, you must load the filters and tags created into the templates where you would like them to be used by adding:

 

{% load anyname %}

 

Creating a Custom Template Tag in Django

Creating a custom template tag is more complex than creating a custom template filter because of the ability to do literally anything on the template.

 

Django provides basically two helper functions to help us create them easily. Namely:
 

  • simple_tag: accepts data like strings or template variables and returns the output on the template.
  • inclusion_tag: This processes the data and returns a rendered template.
     

Simple Tag

As the name implies, this is used to create simple template tags that take in arguments then optionally perform operations on them then return an output that is likely a string.
 

Let's see a simple template tag that takes an argument of number type and multiplies it by itself.

 

from django import template

register = template.Library()

@register.simple_tag
def self_multiplier(number):
    number = int(number)
    return number * number

 

This template tag has been registered with the function name "self_multiplier" but assuming we wanted to use another name, we could simply do this by specifying it using the "name" attribute of the simple tag.

 

@register.simple_tag(name="multiplier")
def self_multiplier(number):
    number = int(number)
    return number * number

 

Then, we could use it in the template as follows:

 

{% load anyname %}

<div>
    <table>
        <thead>
             <tr>
                  <th>Number</th>
                  <th>Multiplied Version</th>
             </tr>
        </thead>
        <tbody>
             <tr>
                  <td>50</td>
                  <td>{% multiplier 50 %}</td>
             </tr>
        </tbody>
    </table>
</div>

 

Inclusion Tag

Unlike the simple tag, inclusion tags display some data by rendering another template.

This can be used in a scenario where data in a template would be used in another template or multiple templates.

Take, for instance, a situation whereby an employee list wants to be displayed on the homepage.

Do not forget that all tags(and filters) must be written inside the anyname.py file.
 

#app/models.py

from django.db import models

class Employee(models.Model):
     first_name = models.CharField(max_length=50)
     last_name = models.CharField(max_length=50)
     email = models.EmailField()

     def __str__(self):
         return f"{self.first_name} {self.last_name}"

#templatetags/anyname.py

from django.contrib.auth import get_user_model
from django.template.loader import get_template
from app.models import Employee

from django import template
register = template.Library()

def show_employees_table():
    employees = Employee.objects.all()
    return {'employees': employees}

employees_template = get_template('employees.html')
register.inclusion_tag(employees_template)(show_employees_table)

 

Then, let's create the template employee.html.
 

{% load anyname %}

<table>
    <thead>
        <tr>
        <td>First name</td>
        <td>Last name</td>
        <td>email</td>
        </tr>
    </thead>
    <tbody>
        {% for employee in employees %}
        <tr>
            <td>{{employee.first_name}}</td>
            <td>{{employee.last_name}}</td>
            <td>{{employee.email}}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

 

Now let's use our custom template tag on homepage.html
 

{% load anyname %}

{% show_employees_table %}

 

It renders as follows:

 

First name	Last name	email
Godspower       Eze	        testemail@gmail.com

 

Conclusion

Django has provided a lot of in-built template tags so check out the documentation before deciding to create yours because there is a high probability that the tag you are about to create is already available.
 

For more info check out the documentation on this.

 

Follow me on Twitter for more amazing content.

 

Keep coding. Keep learning.

 

This was originally published on codingwithease.com