-
First let's clarify how
include
andextends
tags work inside components. So when component template includesinclude
orextends
tags, it's as if the "included" template was inlined. So if the "included" template containsslot
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 from django_components import Component, register @register("my_comp_extends") class MyCompWithExtends(Component): template = """{% extends "abc.html" %}""" @register("my_comp_include") class MyCompWithInclude(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> ```
-
Slot and block
So if you have a template
abc.html
like so:<div> hello {% block inner %} 1 {% slot "body" %} 2 {% endslot %} {% endblock %} </div>
and component
my_comp
:@register("my_comp") class MyComp(Component): template_name = "abc.html"
Then:
-
Since the
block
wasn't overriden, you can use thebody
slot:{% component "my_comp" %} {% fill "body" %} XYZ {% endfill %} {% endcomponent %}
And we get:
<div>hello 1 XYZ</div>
-
blocks
CANNOT be overriden through thecomponent
tag, so something like this:{% component "my_comp" %} {% fill "body" %} XYZ {% endfill %} {% endcomponent %} {% block "inner" %} 456 {% endblock %}
Will still render the component content just the same:
<div>hello 1 XYZ</div>
-
You CAN override the
block
tags ofabc.html
if my component template usesextends
. In that case, just as you would expect, theblock inner
insideabc.html
will renderOVERRIDEN
:@register("my_comp") class MyComp(Component): template_name = """ {% extends "abc.html" %} {% block inner %} OVERRIDEN {% endblock %} """ ```
-
This is where it gets interesting (but still intuitive). You can insert even new
slots
inside these "overriding" blocks:@register("my_comp") class MyComp(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:{% component "my_comp" %} {% fill "new_slot" %} XYZ {% endfill %} {% endcomponent %}
NOTE: Currently you can supply fills for both
new_slot
andbody
slots, and you will not get an error for an invalid/unknown slot name. But sincebody
slot is not rendered, it just won't do anything. So this renders the same as above:{% component "my_comp" %} {% fill "new_slot" %} XYZ {% endfill %} {% fill "body" %} www {% endfill %} {% endcomponent %}
-