Skip to content

Template tagsยค

All following template tags are defined in

django_components.templatetags.component_tags

Import as

{% load component_tags %}

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 Default JS / CSS 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 Default JS / CSS 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.

componentยค

{% component *args: Any, **kwargs: Any [only] %}
{% endcomponent %}

See source code

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

The {% component %} tag takes:

  • Component's registered name as the first positional argument,
  • Followed by any number of positional and keyword arguments.
{% load component_tags %}
<div>
    {% component "button" name="John" job="Developer" / %}
</div>

The component name must be a string literal.

Inserting slot fillsยค

If the component defined any slots, you can "fill" these slots by placing the {% fill %} tags within the {% component %} tag:

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

You can even nest {% fill %} tags within {% if %}, {% for %} and other tags:

{% component "my_table" rows=rows headers=headers %}
    {% if rows %}
        {% fill "pagination" %}
            < 1 | 2 | 3 >
        {% endfill %}
    {% endif %}
{% 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 %}

Alternatively, you can set all components to be isolated by default, by setting context_behavior to "isolated" in your settings:

# settings.py
COMPONENTS = {
    "context_behavior": "isolated",
}

Omitting the component keywordยค

If you would like to omit the component keyword, and simply refer to your components by their registered names:

{% button name="John" job="Developer" / %}

You can do so by setting the "shorthand" Tag formatter in the settings:

# settings.py
COMPONENTS = {
    "tag_formatter": "django_components.component_shorthand_formatter",
}

fillยค

{% fill name: str, *, data: Optional[str] = None, default: Optional[str] = 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: Optional[Dict] = None, defaults: Optional[Dict] = None, **kwargs: Any %}

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 as well as inside the component.

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: str, **kwargs: Any %}
{% 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_template_data(self, args, kwargs, slots, context):
        return {
            "user": kwargs["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_template_data(self, args, kwargs, slots, context):
        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: str, **kwargs: Any [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 %}
    """