Django: Move a template tag library into builtins

Keep your templates nimble like a shrimp.

Django’s template engine has an underappreciated builtins option that selects libraries to preload in every template. Making a library a builtin avoids the need for an explicit {% load %} tag whenever you use its tags or filters. Putting key libraries in builtins can shorten your templates and make development a little bit faster.

In this post, we’ll cover how to add a template library to builtins and remove existing {% load %} tags from your templates.

Move a library to builtins

Imagine you’re using my heroicons package to embed icons from the lovely heroicons. Your templates use the template library like so:

{% load heroicons %}

...

<button>
  {% heroicon_outline "beaker" %}
  Launch experiment
</button>

You realize that most of your templates use heroicons, making it worth adding to builtins. Here are the steps you’d follow to add it and clean up your templates.

First, add the library’s full module path to builtins in OPTIONS:

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        # ...
        "OPTIONS": {
            "builtins": [
                "heroicons.templatetags.heroicons",
            ],
            # ...
        },
    },
]

Second, check it is correctly configured. Remove {% load heroicons %} from one template:

-{% load heroicons %}

 ...

 <button>
   {% heroicon_outline "beaker" %}
   Launch experiment
 </button>

Then load the corresponding page to check it doesn’t have an error like:

Invalid block tag on line 46: 'heroicon_outline', expected 'endblock'. Did you forget to register or load this tag?

Third, remove the {% load %} from your templates with the below shell commands. Install the sd command first and edit the commands to replace “heroicons” with the name of the library you’re changing.

$ git ls-files -z '*.html' | xargs -0 sd '^ *\{% +load +heroicons +%\}\n+' '$1'

$ git ls-files -z '*.html' | xargs -0 sd '(\{% +load.*? )heroicons (.*?%\})' '$1$2'

Both command chains use git ls-files with xargs to run a command on all files, a technique I covered previously. If you have non-HTML templates, adjust the git ls-files pathspec to match them too.

The string replacement is done with sd and regular expressions. sd is a modern sed alternative that’s a lot easier to use. (I tried to modify the commands to use sed, but it was too difficult, due to matching newlines.)

The first command removes load tags for a single library, like {% load heroicons %}. The second one then removes from load tags for multiple libraries, like {% load heroicons static %}.

After this step, git diff should show you a lot of changes like:

templates/experiments/create.html
@@ -9 +9 @@
-{% load core_tags heroicons %}
+{% load core_tags %}

templates/experiments/edit.html
@@ -9 +9 @@
-{% load heroicons static %}
+{% load static %}

templates/experiments/index.html
@@ -1,2 +0,0 @@
-{% load heroicons %}
-

...

And that’s it, you’ve added heroicons to builtins and tidied up your templates.

To add multiple libraries to builtins, repeat these steps all the way through for each.

Built-in libraries to add to builtins

Django comes with several template tag libraries. If you use any of these frequently, consider adding them to builtins per above, using their module paths:

Short nameModule path
humanize"django.contrib.humanize.templatetags.humanize"
i18n"django.templatetags.i18n"
l10n"django.templatetags.l10n"
static"django.templatetags.static"
tz"django.templatetags.tz"

Fin

May your templates be ever terser,

—Adam


Read my book Boost Your Git DX to Git better.


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: