fix: loader tags compatibility (#468)

This commit is contained in:
Juro Oravec 2024-05-02 22:24:49 +02:00 committed by GitHub
parent eef331e903
commit e566d8ecbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 592 additions and 22 deletions

166
docs/slots_and_blocks.md Normal file
View file

@ -0,0 +1,166 @@
# Using `slot` and `block` tags
1. First let's clarify how `include` and `extends` tags work inside components.
So when component template includes `include` or `extends` tags, it's as if the "included"
template was inlined. So if the "included" template contains `slot` tags, then the component
uses those slots.
So if you have a template `abc.html`:
```django
<div>
hello
{% slot "body" %}{% endslot %}
</div>
```
And components that make use of `abc.html` via `include` or `extends`:
```py
@component.register("my_comp_extends")
class MyCompWithExtends(component.Component):
template = """{% extends "abc.html" %}"""
@component.register("my_comp_include")
class MyCompWithInclude(component.Component):
template = """{% include "abc.html" %}"""
```
Then you can set slot fill for the slot imported via `include/extends`:
```django
{% component "my_comp_extends" %}
{% fill "body" %}
123
{% endfill %}
{% endcomponent %}
```
And it will render:
```html
<div>
hello
123
</div>
```
2. Slot and block
So if you have a template `abc.html` like so:
```django
<div>
hello
{% block inner %}
1
{% slot "body" %}
2
{% endslot %}
{% endblock %}
</div>
```
and component `my_comp`:
```py
@component.register("my_comp")
class MyComp(component.Component):
template_name = "abc.html"
```
Then:
1. Since the `block` wasn't overriden, you can use the `body` slot:
```django
{% component "my_comp" %}
{% fill "body" %}
XYZ
{% endfill %}
{% endcomponent %}
```
And we get:
```html
<div>hello 1 XYZ</div>
```
2. `blocks` CANNOT be overriden through the `component` tag, so something like this:
```django
{% component "my_comp" %}
{% fill "body" %}
XYZ
{% endfill %}
{% endcomponent %}
{% block "inner" %}
456
{% endblock %}
```
Will still render the component content just the same:
```html
<div>hello 1 XYZ</div>
```
3. You CAN override the `block` tags of `abc.html` if my component template
uses `extends`. In that case, just as you would expect, the `block inner` inside
`abc.html` will render `OVERRIDEN`:
````py
@component.register("my_comp")
class MyComp(component.Component):
template_name = """
{% extends "abc.html" %}
{% block inner %}
OVERRIDEN
{% endblock %}
"""
```
````
4. This is where it gets interesting (but still intuitive). You can insert even
new `slots` inside these "overriding" blocks:
```py
@component.register("my_comp")
class MyComp(component.Component):
template_name = """
{% extends "abc.html" %}
{% load component_tags %}
{% block "inner" %}
OVERRIDEN
{% slot "new_slot" %}
hello
{% endslot %}
{% endblock %}
"""
```
And you can then pass fill for this `new_slot` when rendering the component:
```django
{% component "my_comp" %}
{% fill "new_slot" %}
XYZ
{% endfill %}
{% endcomponent %}
```
NOTE: Currently you can supply fills for both `new_slot` and `body` slots, and you will
not get an error for an invalid/unknown slot name. But since `body` slot is not rendered,
it just won't do anything. So this renders the same as above:
```django
{% component "my_comp" %}
{% fill "new_slot" %}
XYZ
{% endfill %}
{% fill "body" %}
www
{% endfill %}
{% endcomponent %}
```