When I quickly want to prototype a new idea I use a combination of:
- Django
- Tailwind with django-tailwind for UI auto-reloads on templates changes
- DaisyUI for Tailwind components
Many sites use some sort of alerts to notify users of actions and site updates such as email subscriptions or successful payments. By combining the Django messages framework and DaisyUI alerts we get pretty alerts out of the box.
Django messages have various helpers which generate tags we can use in css classes:
- messages.info(request, "Three credits remain in your account.") -- css-class:info
- messages.success(request, "Profile details updated."): -- css-class:success
- messages.warning(request, "Your account expires in three days."): -- css-class:warning
- messages.error(request, "Document deleted."): -- css-class:error
Luckily all of the built-in tags map cleanly to DaisyUI alert classes:
Suppose we have a view that performs an action, publishes a message and redirects the user:
from django.contrib import messages
from django.views.generic.base import RedirectView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
class ActionView(LoginRequiredMixin, RedirectView):
permanent = False
url = reverse_lazy("core:index")
def get_redirect_url(self, *args, **kwargs):
messages.success(
self.request,
"You have triggered an action!",
)
return super().get_redirect_url(*args, **kwargs)
The call to messages.success
will add a success
tag to the message object in the template like so:
{% for message in messages %}
<div role="alert" class="alert alert-{{ message.tags }}">
<span>{{ message }}</span>
</div>
{% endfor %}
The resulting HTML would be:
<div role="alert" class="alert alert-success">
<span>You've triggered an action!</span>
</div>
The class alert alert-success
automatically creates a DaisyUI alert component:
However, since Tailwind cleverly strips out unused css classes this won't work. Tailwind scans the HTML document on build time for what css classes are in use and only includes those in the resulting css build. Since our Django template dynamically generates the alert type alert alert-{{ message.tags }}
we have to instruct Tailwind to keep certain classes in the final build even if they don't exist in the HTML document. We can do that by modifying the Tailwind config file tailwind.config.js
. Simply add the generated class names in the safelist
:
module.exports = {
content: [
'../templates/**/*.html',
],
theme: {},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
require('@tailwindcss/line-clamp'),
require('@tailwindcss/aspect-ratio'),
require('daisyui'),
],
daisyui: {},
safelist: [
'alert-info',
'alert-success',
'alert-warning',
'alert-error',
],
}