Skip to content

Htmx

hypha.core.middleware.htmx

HtmxMessageMiddleware

Bases: MiddlewareMixin

Middleware that transfers Django messages into the HX-Trigger header for HTMX requests.

This middleware captures Django messages and adds them to the HX-Trigger header when the request is made with HTMX. It preserves any existing HX-Trigger values and adds the messages in a standardized format that can be processed by frontend JavaScript.

The messages are formatted as an array of objects, each containing: - message: The text content of the message - tags: CSS class names or other categorization for the message

process_response

process_response(request, response)
Source code in hypha/core/middleware/htmx.py
def process_response(
    self, request: HttpRequest, response: HttpResponse
) -> HttpResponse:
    # The HX-Request header indicates that the request was made with HTMX
    if "HX-Request" not in request.headers:
        return response

    # Ignore redirection because HTMX cannot read the headers
    if 300 <= response.status_code < 400:
        return response

    if response.headers.get("HX-Refresh", False):
        return response

    # Extract the messages
    messages = [
        {"message": message.message, "tags": message.tags}
        for message in get_messages(request)
    ]
    if not messages:
        return response

    # Get the existing HX-Trigger that could have been defined by the view
    hx_trigger = response.headers.get("HX-Trigger")

    if hx_trigger is None:
        # If the HX-Trigger is not set, start with an empty object
        hx_trigger = {}
    elif hx_trigger.startswith("{"):
        # If the HX-Trigger uses the object syntax, parse the object
        hx_trigger = json.loads(hx_trigger)
    else:
        # If the HX-Trigger uses the string syntax, convert to the object syntax
        hx_trigger = {hx_trigger: True}

    # Add the messages array in the HX-Trigger object
    hx_trigger["messages"] = messages

    # Add or update the HX-Trigger
    response.headers["HX-Trigger"] = json.dumps(hx_trigger)

    return response

HtmxAuthRedirectMiddleware

HtmxAuthRedirectMiddleware(get_response)

Middleware to handle HTMX authentication redirects properly.

When an HTMX request results in a 302 redirect (typically for authentication), this middleware: 1. Changes the response status code to 204 (No Content) 2. Adds an HX-Redirect header with the redirect URL 3. Preserves the original request path in the 'next' query parameter

This ensures that after authentication, the user is returned to the page they were attempting to access, maintaining a seamless UX with HTMX.

Credits: https://www.caktusgroup.com/blog/2022/11/11/how-handle-django-login-redirects-htmx/

Source code in hypha/core/middleware/htmx.py
def __init__(self, get_response):
    self.get_response = get_response

get_response instance-attribute

get_response = get_response