fix: Set Context.template for components to work with include (#582)

This commit is contained in:
Juro Oravec 2024-08-16 23:31:00 +02:00 committed by GitHub
parent b2fece49d2
commit b8e92dac37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 54 additions and 12 deletions

View file

@ -362,15 +362,11 @@ class Component(View, metaclass=ComponentMeta):
slots: Optional[Mapping[SlotName, SlotContent]] = None,
escape_slots_content: bool = True,
) -> str:
# Allow to provide no args/kwargs
args = args or []
kwargs = kwargs or {}
# Allow to provide no Context, so we can render component just with args + kwargs
context_was_given = True
if context is None:
context = Context()
context_was_given = False
# Allow to provide no args/kwargs/slots/context
args = args or [] # type: ignore[assignment]
kwargs = kwargs or {} # type: ignore[assignment]
slots = slots or {} # type: ignore[assignment]
context = context or Context()
# Allow to provide a dict instead of Context
# NOTE: This if/else is important to avoid nested Contexts,
@ -387,9 +383,11 @@ class Component(View, metaclass=ComponentMeta):
with context.update(context_data):
template = self.get_template(context)
_monkeypatch_template(template)
if not context_was_given:
if context.template is None:
# Associate the newly-created Context with a Template, otherwise we get
# an error when we try to use `{% include %}` tag inside the template?
# See https://github.com/EmilStenstrom/django-components/issues/580
context.template = template
context.template_name = template.name

View file

@ -6,8 +6,8 @@ For tests focusing on the `component` tag, see `test_templatetags_component.py`
from typing import Dict
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse
from django.template import Context, Template, TemplateSyntaxError
from django.http import HttpRequest, HttpResponse
from django.template import Context, RequestContext, Template, TemplateSyntaxError
from django_components import Component, registry, types
from django_components.slots import SlotRef
@ -448,6 +448,50 @@ class ComponentRenderTest(BaseTestCase):
""",
)
# See https://github.com/EmilStenstrom/django-components/issues/580
# And https://github.com/EmilStenstrom/django-components/commit/fee26ec1d8b46b5ee065ca1ce6143889b0f96764
@parametrize_context_behavior(["django", "isolated"])
def test_render_with_include_and_context(self):
class SimpleComponent(Component):
template: types.django_html = """
{% load component_tags %}
{% include 'slotted_template.html' %}
"""
rendered = SimpleComponent.render(context=Context())
self.assertHTMLEqual(
rendered,
"""
<custom-template>
<header>Default header</header>
<main>Default main</main>
<footer>Default footer</footer>
</custom-template>
""",
)
# See https://github.com/EmilStenstrom/django-components/issues/580
# And https://github.com/EmilStenstrom/django-components/commit/fee26ec1d8b46b5ee065ca1ce6143889b0f96764
@parametrize_context_behavior(["django", "isolated"])
def test_render_with_include_and_request_context(self):
class SimpleComponent(Component):
template: types.django_html = """
{% load component_tags %}
{% include 'slotted_template.html' %}
"""
rendered = SimpleComponent.render(context=RequestContext(HttpRequest()))
self.assertHTMLEqual(
rendered,
"""
<custom-template>
<header>Default header</header>
<main>Default main</main>
<footer>Default footer</footer>
</custom-template>
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_render_with_extends(self):
class SimpleComponent(Component):