import re
from django.conf import settings
from django.forms import Media
from django.http import StreamingHttpResponse
from django_components.component_registry import registry
RENDERED_COMPONENTS_CONTEXT_KEY = "_COMPONENT_DEPENDENCIES"
CSS_DEPENDENCY_PLACEHOLDER = ''
JS_DEPENDENCY_PLACEHOLDER = ''
SCRIPT_TAG_REGEX = re.compile("'
)
class ComponentDependencyMiddleware:
"""Middleware that inserts CSS/JS dependencies for all rendered components at points marked with template tags."""
dependency_regex = COMPONENT_COMMENT_REGEX
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
if (
getattr(settings, "COMPONENTS", {}).get("RENDER_DEPENDENCIES", False)
and not isinstance(response, StreamingHttpResponse)
and response.get("Content-Type", "").startswith("text/html")
):
response.content = process_response_content(response.content)
return response
def process_response_content(content):
component_names_seen = {match.group("name") for match in COMPONENT_COMMENT_REGEX.finditer(content)}
all_components = [registry.get(name.decode("utf-8"))("") for name in component_names_seen]
all_media = join_media(all_components)
js_dependencies = b"".join(media.encode("utf-8") for media in all_media.render_js())
css_dependencies = b"".join(media.encode("utf-8") for media in all_media.render_css())
return PLACEHOLDER_REGEX.sub(DependencyReplacer(css_dependencies, js_dependencies), content)
def add_module_attribute_to_scripts(scripts):
return re.sub(SCRIPT_TAG_REGEX, '