diff --git a/src/django_components/component.py b/src/django_components/component.py index 9e348120..1f61cf4f 100644 --- a/src/django_components/component.py +++ b/src/django_components/component.py @@ -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 diff --git a/tests/test_component.py b/tests/test_component.py index 25e50f56..25f44412 100644 --- a/tests/test_component.py +++ b/tests/test_component.py @@ -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, + """ + +
Default header
+
Default main
+ +
+ """, + ) + + # 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, + """ + +
Default header
+
Default main
+ +
+ """, + ) + @parametrize_context_behavior(["django", "isolated"]) def test_render_with_extends(self): class SimpleComponent(Component):