Switching between partial and full html when using django and htmx
I created a context processor to help me switch between full and partial templates in django automatically. It sets my base template to a partial template if the request is a htmx
request.
TL;DR
I just check if the current request is a htmx
request, then I set the base template to _partial.html
, else _base.html
.
The code
myApp/context_processors.py
from django.http import HttpRequest
def setBaseTemplate(request: HttpRequest) -> dict[str, str]:
"""Sets the base_template context variable.
Parameters:
- request: Request object.
Returns:
- dict: A dictionary that sets either '_base.html' or '_partial.html' as the base template.
"""
baseTemplate = '_partial.html' if request.htmx else '_base.html'
return {'base_template': baseTemplate}
myProject/settings.py
To activate the context processor, I added it to the list of context processors for my template engine django template. I opened my settings.py
file, moved down to where the list TEMPLATES
is defined and added it to the context_processors
list;
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"myApp.context_processors.setBaseTemplate",
],
},
},
]
The new context processor is "myApp.context_processors.setBaseTemplate"
.
Explanation
I will be building my explanation on that of django-htmx tips.
If you have your templates setup as django-htmx
suggested, then your templates will be expecting a base_template
variable. That variable will determine which base template to use.
From django docs:
Context processors are functions that receive the current HttpRequest as an argument and return a dict of data to be added to the rendering context.
Their main use is to add common data shared by all templates to the context without repeating code in every view.
Instead of having to pass the base_template
variable each time I want to render a template, my context processor automatically sets it for me. I need only the main html chunk when it’s a htmx
request, so I set the base template to _partial.html
. Otherwise, I set it to _base.html
, which is a full html file.
Conclusion
This will work until there is an exception to the assumption. In that case, I am planning to add an attribute to the request
object to let my context processor
know about the exception. Until then, this is perfect!
Perhaps django-htmx might like to add it to there extension, I’ll open an issue and tell them about it.