mirror of
https://github.com/django-components/django-components.git
synced 2025-09-18 11:49:44 +00:00
fix: fix compat with extends and includes (#1344)
This commit is contained in:
parent
a6e840bdca
commit
9be4124339
6 changed files with 88 additions and 5 deletions
|
@ -1,5 +1,12 @@
|
|||
# Release notes
|
||||
|
||||
## v0.141.4
|
||||
|
||||
#### Fix
|
||||
|
||||
- Fix compatibility with Django's `{% include %}` and `{% extends %}` tags.
|
||||
See https://github.com/django-components/django-components/issues/1325
|
||||
|
||||
## v0.141.3
|
||||
|
||||
#### Feat
|
||||
|
|
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||
|
||||
[project]
|
||||
name = "django_components"
|
||||
version = "0.141.3"
|
||||
version = "0.141.4"
|
||||
requires-python = ">=3.8, <4.0"
|
||||
description = "A way to create simple reusable template components in Django."
|
||||
keywords = ["django", "components", "css", "js", "html"]
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import difflib
|
||||
import re
|
||||
from contextlib import contextmanager
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import replace as dataclass_replace
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Dict,
|
||||
Generator,
|
||||
Generic,
|
||||
List,
|
||||
Literal,
|
||||
|
@ -1460,6 +1462,8 @@ def _extract_fill_content(
|
|||
# When, during rendering of this tree, we encounter a {% fill %} node, instead of rendering content,
|
||||
# it will add itself into captured_fills, because `FILL_GEN_CONTEXT_KEY` is defined.
|
||||
captured_fills: List[FillWithData] = []
|
||||
|
||||
with _extends_context_reset(context):
|
||||
with context.update({FILL_GEN_CONTEXT_KEY: captured_fills}):
|
||||
content = mark_safe(nodes.render(context).strip())
|
||||
|
||||
|
@ -1667,3 +1671,24 @@ def _nodelist_to_slot(
|
|||
|
||||
def _is_extracting_fill(context: Context) -> bool:
|
||||
return context.get(FILL_GEN_CONTEXT_KEY, None) is not None
|
||||
|
||||
|
||||
# Fix for compatibility with Django's `{% include %}` and `{% extends %}` tags.
|
||||
# See https://github.com/django-components/django-components/issues/1325
|
||||
#
|
||||
# When we search for `{% fill %}` tags, we also evaluate `{% include %}` and `{% extends %}`
|
||||
# tags if they are within component body (between `{% component %}` / `{% endcomponent %}` tags).
|
||||
# But by doing so, we trigger Django's block/extends logic to remember that this extended file
|
||||
# was already walked.
|
||||
# (See https://github.com/django/django/blob/0bff53b4138d8c6009e9040dbb8916a1271a68d7/django/template/loader_tags.py#L114) # noqa: E501
|
||||
#
|
||||
# We need to clear that state, otherwise Django won't render the extended template the second time
|
||||
# (when we actually render it).
|
||||
@contextmanager
|
||||
def _extends_context_reset(context: Context) -> Generator[None, None, None]:
|
||||
b4_ctx_extends = context.render_context.setdefault("extends_context", []).copy()
|
||||
|
||||
yield
|
||||
|
||||
# Reset the state of what extends have been seen.
|
||||
context.render_context["extends_context"] = b4_ctx_extends
|
||||
|
|
4
tests/templates/extends_compat_c_include.html
Normal file
4
tests/templates/extends_compat_c_include.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
{% extends "extends_compat_d_extended.html" %}
|
||||
{% block content %}
|
||||
<p>This template extends another template.</p>
|
||||
{% endblock %}
|
3
tests/templates/extends_compat_d_extended.html
Normal file
3
tests/templates/extends_compat_d_extended.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<p>This template gets extended.</p>
|
||||
{% block content %}
|
||||
{% endblock %}
|
|
@ -145,7 +145,9 @@ class TestExtendsCompat:
|
|||
assertHTMLEqual(rendered, expected)
|
||||
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_double_extends_on_main_template_and_component_two_different_components_same_parent(self, components_settings): # noqa: E501
|
||||
def test_double_extends_on_main_template_and_component_two_different_components_same_parent(
|
||||
self, components_settings
|
||||
):
|
||||
registry.register("blocked_and_slotted_component", gen_blocked_and_slotted_component())
|
||||
|
||||
@register("extended_component")
|
||||
|
@ -211,7 +213,9 @@ class TestExtendsCompat:
|
|||
assertHTMLEqual(rendered, expected)
|
||||
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_double_extends_on_main_template_and_component_two_different_components_different_parent(self, components_settings): # noqa: E501
|
||||
def test_double_extends_on_main_template_and_component_two_different_components_different_parent(
|
||||
self, components_settings
|
||||
):
|
||||
registry.register("blocked_and_slotted_component", gen_blocked_and_slotted_component())
|
||||
|
||||
@register("extended_component")
|
||||
|
@ -1029,3 +1033,43 @@ class TestExtendsCompat:
|
|||
</html>
|
||||
"""
|
||||
assertHTMLEqual(rendered, expected)
|
||||
|
||||
# Fix for compatibility with Django's `{% include %}` and `{% extends %}` tags.
|
||||
# See https://github.com/django-components/django-components/issues/1325
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_nested_component_with_include_and_extends_in_slot(self, components_settings):
|
||||
@register("a_outer")
|
||||
class AOuterComponent(Component):
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<p>This is the outer component.</p>
|
||||
{% slot "a" default / %}
|
||||
"""
|
||||
|
||||
@register("b_inner")
|
||||
class BInnerComponent(Component):
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<p>This is the inner component.</p>
|
||||
{% slot "b" default / %}
|
||||
"""
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
{% component "a_outer" %}
|
||||
{% component "b_inner" %}
|
||||
{% include "extends_compat_c_include.html" %}
|
||||
{% endcomponent %}
|
||||
{% endcomponent %}
|
||||
"""
|
||||
rendered = Template(template).render(Context({}))
|
||||
|
||||
assertHTMLEqual(
|
||||
rendered,
|
||||
"""
|
||||
<p data-djc-id-ca1bc40>This is the outer component.</p>
|
||||
<p data-djc-id-ca1bc40 data-djc-id-ca1bc42>This is the inner component.</p>
|
||||
<p data-djc-id-ca1bc40 data-djc-id-ca1bc42>This template gets extended.</p>
|
||||
<p data-djc-id-ca1bc40 data-djc-id-ca1bc42>This template extends another template.</p>
|
||||
""",
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue