Skip to content

Template tagsยค

All following template tags are defined in

django_components.templatetags.component_tags

Import as

{% load component_tags %}

componentยค

{% component [arg, ...] **kwargs [only] %}
{% endcomponent %}

See source code

Renders one of the components that was previously registered with @register() decorator.

Args:

  • name (str, required): Registered name of the component to render
  • All other args and kwargs are defined based on the component itself.

If you defined a component "my_table"

from django_component import Component, register

@register("my_table")
class MyTable(Component):
    template = """
      <table>
        <thead>
          {% for header in headers %}
            <th>{{ header }}</th>
          {% endfor %}
        </thead>
        <tbody>
          {% for row in rows %}
            <tr>
              {% for cell in row %}
                <td>{{ cell }}</td>
              {% endfor %}
            </tr>
          {% endfor %}
        <tbody>
      </table>
    """

    def get_context_data(self, rows: List, headers: List):
        return {
            "rows": rows,
            "headers": headers,
        }

Then you can render this component by referring to MyTable via its registered name "my_table":

{% component "my_table" rows=rows headers=headers ... / %}

Component inputยค

Positional and keyword arguments can be literals or template variables.

The component name must be a single- or double-quotes string and must be either:

  • The first positional argument after component:

    {% component "my_table" rows=rows headers=headers ... / %}
    
  • Passed as kwarg name:

    {% component rows=rows headers=headers name="my_table" ... / %}
    

Inserting into slotsยค

If the component defined any slots, you can pass in the content to be placed inside those slots by inserting {% fill %} tags, directly within the {% component %} tag:

{% component "my_table" rows=rows headers=headers ... / %}
  {% fill "pagination" %}
    < 1 | 2 | 3 >
  {% endfill %}
{% endcomponent %}

Isolating componentsยค

By default, components behave similarly to Django's {% include %}, and the template inside the component has access to the variables defined in the outer template.

You can selectively isolate a component, using the only flag, so that the inner template can access only the data that was explicitly passed to it:

{% component "name" positional_arg keyword_arg=value ... only %}

component_css_dependenciesยค

{% component_css_dependencies %}

See source code

Marks location where CSS link tags should be rendered after the whole HTML has been generated.

Generally, this should be inserted into the <head> tag of the HTML.

If the generated HTML does NOT contain any {% component_css_dependencies %} tags, CSS links are by default inserted into the <head> tag of the HTML. (See JS and CSS output locations)

Note that there should be only one {% component_css_dependencies %} for the whole HTML document. If you insert this tag multiple times, ALL CSS links will be duplicately inserted into ALL these places.

component_js_dependenciesยค

{% component_js_dependencies %}

See source code

Marks location where JS link tags should be rendered after the whole HTML has been generated.

Generally, this should be inserted at the end of the <body> tag of the HTML.

If the generated HTML does NOT contain any {% component_js_dependencies %} tags, JS scripts are by default inserted at the end of the <body> tag of the HTML. (See JS and CSS output locations)

Note that there should be only one {% component_js_dependencies %} for the whole HTML document. If you insert this tag multiple times, ALL JS scripts will be duplicately inserted into ALL these places.

fillยค

{% fill name data=None default=None %}
{% endfill %}

See source code

Use this tag to insert content into component's slots.

{% fill %} tag may be used only within a {% component %}..{% endcomponent %} block. Runtime checks should prohibit other usages.

Args:

  • name (str, required): Name of the slot to insert this content into. Use "default" for the default slot.
  • default (str, optional): This argument allows you to access the original content of the slot under the specified variable name. See Accessing original content of slots
  • data (str, optional): This argument allows you to access the data passed to the slot under the specified variable name. See Scoped slots

Examples:

Basic usage:

{% component "my_table" %}
  {% fill "pagination" %}
    < 1 | 2 | 3 >
  {% endfill %}
{% endcomponent %}

Accessing slot's default content with the default kwargยค

{# my_table.html #}
<table>
  ...
  {% slot "pagination" %}
    < 1 | 2 | 3 >
  {% endslot %}
</table>
{% component "my_table" %}
  {% fill "pagination" default="default_pag" %}
    <div class="my-class">
      {{ default_pag }}
    </div>
  {% endfill %}
{% endcomponent %}

Accessing slot's data with the data kwargยค

{# my_table.html #}
<table>
  ...
  {% slot "pagination" pages=pages %}
    < 1 | 2 | 3 >
  {% endslot %}
</table>
{% component "my_table" %}
  {% fill "pagination" data="slot_data" %}
    {% for page in slot_data.pages %}
        <a href="{{ page.link }}">
          {{ page.index }}
        </a>
    {% endfor %}
  {% endfill %}
{% endcomponent %}

Accessing slot data and default content on the default slotยค

To access slot data and the default slot content on the default slot, use {% fill %} with name set to "default":

{% component "button" %}
  {% fill name="default" data="slot_data" default="default_slot" %}
    You clicked me {{ slot_data.count }} times!
    {{ default_slot }}
  {% endfill %}
{% endcomponent %}

html_attrsยค

{% html_attrs attrs=None defaults=None **kwargs %}

See source code

Generate HTML attributes (key="value"), combining data from multiple sources, whether its template variables or static text.

It is designed to easily merge HTML attributes passed from outside with the internal. See how to in Passing HTML attributes to components.

Args:

  • attrs (dict, optional): Optional dictionary that holds HTML attributes. On conflict, overrides values in the default dictionary.
  • default (str, optional): Optional dictionary that holds HTML attributes. On conflict, is overriden with values in the attrs dictionary.
  • Any extra kwargs will be appended to the corresponding keys

The attributes in attrs and defaults are merged and resulting dict is rendered as HTML attributes (key="value").

Extra kwargs (key=value) are concatenated to existing keys. So if we have

attrs = {"class": "my-class"}

Then

{% html_attrs attrs class="extra-class" %}

will result in class="my-class extra-class".

Example:

<div {% html_attrs
    attrs
    defaults:class="default-class"
    class="extra-class"
    data-id="123"
%}>

renders

<div class="my-class extra-class" data-id="123">

See more usage examples in HTML attributes.

provideยค

{% provide name **kwargs %}
{% endprovide %}

See source code

The "provider" part of the provide / inject feature. Pass kwargs to this tag to define the provider's data. Any components defined within the {% provide %}..{% endprovide %} tags will be able to access this data with Component.inject().

This is similar to React's ContextProvider, or Vue's provide().

Args:

  • name (str, required): Provider name. This is the name you will then use in Component.inject().
  • **kwargs: Any extra kwargs will be passed as the provided data.

Example:

Provide the "user_data" in parent component:

@register("parent")
class Parent(Component):
    template = """
      <div>
        {% provide "user_data" user=user %}
          {% component "child" / %}
        {% endprovide %}
      </div>
    """

    def get_context_data(self, user: User):
        return {
            "user": user,
        }

Since the "child" component is used within the {% provide %} / {% endprovide %} tags, we can request the "user_data" using Component.inject("user_data"):

@register("child")
class Child(Component):
    template = """
      <div>
        User is: {{ user }}
      </div>
    """

    def get_context_data(self):
        user = self.inject("user_data").user
        return {
            "user": user,
        }

Notice that the keys defined on the {% provide %} tag are then accessed as attributes when accessing them with Component.inject().

โœ… Do this

user = self.inject("user_data").user

โŒ Don't do this

user = self.inject("user_data")["user"]

slotยค

{% slot name **kwargs [default] [required] %}
{% endslot %}

See source code

Slot tag marks a place inside a component where content can be inserted from outside.

Learn more about using slots.

This is similar to slots as seen in Web components, Vue or React's children.

Args:

  • name (str, required): Registered name of the component to render
  • default: Optional flag. If there is a default slot, you can pass the component slot content without using the {% fill %} tag. See Default slot
  • required: Optional flag. Will raise an error if a slot is required but not given.
  • **kwargs: Any extra kwargs will be passed as the slot data.

Example:

@register("child")
class Child(Component):
    template = """
      <div>
        {% slot "content" default %}
          This is shown if not overriden!
        {% endslot %}
      </div>
      <aside>
        {% slot "sidebar" required / %}
      </aside>
    """
@register("parent")
class Parent(Component):
    template = """
      <div>
        {% component "child" %}
          {% fill "content" %}
            ๐Ÿ—ž๏ธ๐Ÿ“ฐ
          {% endfill %}

          {% fill "sidebar" %}
            ๐Ÿท๐Ÿง‰๐Ÿพ
          {% endfill %}
        {% endcomponent %}
      </div>
    """

Passing data to slotsยค

Any extra kwargs will be considered as slot data, and will be accessible in the {% fill %} tag via fill's data kwarg:

@register("child")
class Child(Component):
    template = """
      <div>
        {# Passing data to the slot #}
        {% slot "content" user=user %}
          This is shown if not overriden!
        {% endslot %}
      </div>
    """
@register("parent")
class Parent(Component):
    template = """
      {# Parent can access the slot data #}
      {% component "child" %}
        {% fill "content" data="data" %}
          <div class="wrapper-class">
            {{ data.user }}
          </div>
        {% endfill %}
      {% endcomponent %}
    """

Accessing default slot contentยค

The content between the {% slot %}..{% endslot %} tags is the default content that will be rendered if no fill is given for the slot.

This default content can then be accessed from within the {% fill %} tag using the fill's default kwarg. This is useful if you need to wrap / prepend / append the original slot's content.

@register("child")
class Child(Component):
    template = """
      <div>
        {% slot "content" %}
          This is default content!
        {% endslot %}
      </div>
    """
@register("parent")
class Parent(Component):
    template = """
      {# Parent can access the slot's default content #}
      {% component "child" %}
        {% fill "content" default="default" %}
          {{ default }}
        {% endfill %}
      {% endcomponent %}
    """