Django Integration

Use Kida as a Django template backend with kida.contrib.django

3 min read 607 words

Use Kida as a drop-in Django template backend withkida.contrib.django. The integration provides KidaTemplates -- a backend class that plugs into Django's TEMPLATES setting and works with django.shortcuts.render, template loaders, and the Django debug toolbar.

Installation

pip install django kida

Django Settings

Add the Kida backend to yourTEMPLATES list in settings.py:

# settings.py
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

TEMPLATES = [
    {
        "BACKEND": "kida.contrib.django.KidaTemplates",
        "DIRS": [BASE_DIR / "templates"],
        "OPTIONS": {
            "autoescape": True,
            "extensions": [],
        },
    },
]
Key Description
BACKEND Must be"kida.contrib.django.KidaTemplates"
DIRS List of directories to search for templates
OPTIONS.autoescape Enable HTML autoescaping (default:True)
OPTIONS.extensions List of Kida extensions to load

Usage in Views

Once configured, use Django's standard rendering functions. Therequestobject is automatically added to the template context:

from django.shortcuts import render

def home(request):
    return render(request, "home.html", {"title": "Home"})

def user_profile(request, username):
    user = get_user(username)
    return render(request, "profile.html", {"user": user})

You can also load templates directly through the backend:

from django.template import loader

def home(request):
    template = loader.get_template("home.html")
    html = template.render({"title": "Home"}, request)
    return HttpResponse(html)

Or create templates from strings:

from django.template import engines

kida = engines["kida"]  # Name matches BACKEND path
template = kida.from_string("Hello {{ name }}!")
html = template.render({"name": "World"})

Template Syntax Differences

If you're coming from Django's built-in template language, note these Kida syntax differences:

Feature Django Kida
Block end tags {% endblock %} {% end %}
For loop end {% endfor %} {% end %}
If end {% endif %} {% end %}
Comments {# comment #} {# comment #}
Variable output {{ var }} {{ var }}
Filters {{ var\|filter }} {{ var \| filter }}
Extends {% extends "base.html" %} {% extends "base.html" %}

Template Example

templates/base.html:

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My Site{% end %}</title>
</head>
<body>
    <nav>{% block nav %}{% end %}</nav>
    <main>{% block content %}{% end %}</main>
</body>
</html>

templates/home.html:

{% extends "base.html" %}

{% block title %}{{ title }}{% end %}

{% block content %}
    <h1>{{ title }}</h1>
    <p>Welcome to the site!</p>
{% end %}

Custom Filters and Globals

Access the KidaEnvironmentthrough the backend to register custom filters and globals:

# templatetags.py (or in your AppConfig.ready())
from django.template import engines

def setup_kida():
    backend = engines["kida"]
    env = backend.env

    # Register a custom filter
    @env.filter()
    def format_datetime(value, fmt="%Y-%m-%d"):
        return value.strftime(fmt)

    # Register a global
    env.add_global("SITE_NAME", "My Django Site")

Use in templates:

<p>Published: {{ post.date | format_datetime("%B %d, %Y") }}</p>
<footer>{{ SITE_NAME }}</footer>

Complete Example

# settings.py
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

TEMPLATES = [
    {
        "BACKEND": "kida.contrib.django.KidaTemplates",
        "DIRS": [BASE_DIR / "templates"],
        "OPTIONS": {
            "autoescape": True,
        },
    },
]
# views.py
from django.shortcuts import render

def home(request):
    return render(request, "home.html", {
        "title": "Home",
        "items": ["Alpha", "Bravo", "Charlie"],
    })
{# templates/home.html #}
{% extends "base.html" %}

{% block title %}{{ title }}{% end %}

{% block content %}
    <h1>{{ title }}</h1>
    <ul>
    {% for item in items %}
        <li>{{ item }}</li>
    {% end %}
    </ul>
{% end %}

See Also