Skip to content

Recursionยค

Unlike other frameworks, django-components handles templates of any depth. 100 nested components? Not a problem!

In this example, the Recursion will recursively render itself 100 times.

{% component "recursion" / %}

This will produce a deeply nested structure of divs, with each level indicating its depth in the recursion.

Recursion

Definitionยค

from typing import NamedTuple

from django_components import Component, register, types

DESCRIPTION = "100 nested components? Not a problem! Handle recursive rendering out of the box."


@register("recursion")
class Recursion(Component):
    class Kwargs(NamedTuple):
        current_depth: int = 0

    def get_template_data(self, args, kwargs: Kwargs, slots, context):
        current_depth = kwargs.current_depth
        return {
            "current_depth": current_depth,
            "next_depth": current_depth + 1,
        }

    template: types.django_html = """
        {% load component_tags %}
        <div class="py-4 border-l-2 border-gray-300 ml-1">
            {% if current_depth < 100 %}
                <p class="text-sm text-gray-600">
                    Recursion depth: {{ current_depth }}
                </p>
                {% component "recursion" current_depth=next_depth / %}
            {% else %}
                <p class="text-sm font-semibold text-green-600">
                    Reached maximum recursion depth!
                </p>
            {% endif %}
        </div>
    """

Exampleยค

To see the component in action, you can set up a view and a URL pattern as shown below.

views.pyยค

from django.http import HttpRequest, HttpResponse
from django.utils.safestring import mark_safe

from django_components import Component, types


class RecursionPage(Component):
    class Media:
        js = (
            mark_safe(
                '<script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp,container-queries"></script>'
            ),
        )

    template: types.django_html = """
        {% load component_tags %}
        <html>
            <head>
                <title>Recursion Example</title>
            </head>
            <body class="bg-gray-100 p-8">
                <div class="max-w-4xl mx-auto bg-white p-6 rounded-lg shadow-md">
                    <h1 class="text-2xl font-bold mb-4">Recursion</h1>
                    <p class="text-gray-600 mb-6">
                        Django components easily handles even deeply nested components.
                    </p>
                    {% component "recursion" / %}
                </div>
            </body>
        </html>
    """

    class View:
        def get(self, request: HttpRequest) -> HttpResponse:
            return RecursionPage.render_to_response(request=request)

urls.pyยค

from django.urls import path

from examples.pages.recursion import RecursionPage

urlpatterns = [
    path("examples/recursion", RecursionPage.as_view(), name="recursion"),
]