Skip to content

templatetags ¤

component_tags ¤

component ¤

component(parser: Parser, token: Token, registry: ComponentRegistry, tag_name: str) -> ComponentNode
To give the component access to the template context

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

To render the component in an isolated context

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

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 or, if there are no positional arguments, passed as 'name'.

Source code in src/django_components/templatetags/component_tags.py
def component(parser: Parser, token: Token, registry: ComponentRegistry, tag_name: str) -> ComponentNode:
    """
    To give the component access to the template context:
        ```#!htmldjango {% component "name" positional_arg keyword_arg=value ... %}```

    To render the component in an isolated context:
        ```#!htmldjango {% component "name" positional_arg keyword_arg=value ... only %}```

    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 or, if there are no positional
    arguments, passed as 'name'.
    """
    _fix_nested_tags(parser, token)
    bits = token.split_contents()

    # Let the TagFormatter pre-process the tokens
    formatter = get_tag_formatter(registry)
    result = formatter.parse([*bits])
    end_tag = formatter.end_tag(result.component_name)

    # NOTE: The tokens returned from TagFormatter.parse do NOT include the tag itself
    bits = [bits[0], *result.tokens]
    token.contents = " ".join(bits)

    tag = _parse_tag(
        tag_name,
        parser,
        token,
        params=[],
        extra_params=True,  # Allow many args
        flags=[COMP_ONLY_FLAG],
        keywordonly_kwargs=True,
        repeatable_kwargs=False,
        end_tag=end_tag,
    )

    # Check for isolated context keyword
    isolated_context = tag.flags[COMP_ONLY_FLAG]

    trace_msg("PARSE", "COMP", result.component_name, tag.id)

    body = tag.parse_body()
    fill_nodes = parse_slot_fill_nodes_from_component_nodelist(tuple(body), ignored_nodes=(ComponentNode,))

    # Tag all fill nodes as children of this particular component instance
    for node in fill_nodes:
        trace_msg("ASSOC", "FILL", node.trace_id, node.node_id, component_id=tag.id)
        node.component_id = tag.id

    component_node = ComponentNode(
        name=result.component_name,
        args=tag.args,
        kwargs=tag.kwargs,
        isolated_context=isolated_context,
        fill_nodes=fill_nodes,
        node_id=tag.id,
        registry=registry,
    )

    trace_msg("PARSE", "COMP", result.component_name, tag.id, "...Done!")
    return component_node

component_css_dependencies ¤

component_css_dependencies(preload: str = '') -> SafeString

Marks location where CSS link tags should be rendered.

Source code in src/django_components/templatetags/component_tags.py
@register.simple_tag(name="component_css_dependencies")
def component_css_dependencies(preload: str = "") -> SafeString:
    """Marks location where CSS link tags should be rendered."""

    if is_dependency_middleware_active():
        preloaded_dependencies = []
        for component in _get_components_from_preload_str(preload):
            preloaded_dependencies.append(RENDERED_COMMENT_TEMPLATE.format(name=component.registered_name))
        return mark_safe("\n".join(preloaded_dependencies) + CSS_DEPENDENCY_PLACEHOLDER)
    else:
        rendered_dependencies = []
        for component in _get_components_from_registry(component_registry):
            rendered_dependencies.append(component.render_css_dependencies())

        return mark_safe("\n".join(rendered_dependencies))

component_dependencies ¤

component_dependencies(preload: str = '') -> SafeString

Marks location where CSS link and JS script tags should be rendered.

Source code in src/django_components/templatetags/component_tags.py
@register.simple_tag(name="component_dependencies")
def component_dependencies(preload: str = "") -> SafeString:
    """Marks location where CSS link and JS script tags should be rendered."""

    if is_dependency_middleware_active():
        preloaded_dependencies = []
        for component in _get_components_from_preload_str(preload):
            preloaded_dependencies.append(RENDERED_COMMENT_TEMPLATE.format(name=component.registered_name))
        return mark_safe("\n".join(preloaded_dependencies) + CSS_DEPENDENCY_PLACEHOLDER + JS_DEPENDENCY_PLACEHOLDER)
    else:
        rendered_dependencies = []
        for component in _get_components_from_registry(component_registry):
            rendered_dependencies.append(component.render_dependencies())

        return mark_safe("\n".join(rendered_dependencies))

component_js_dependencies ¤

component_js_dependencies(preload: str = '') -> SafeString

Marks location where JS script tags should be rendered.

Source code in src/django_components/templatetags/component_tags.py
@register.simple_tag(name="component_js_dependencies")
def component_js_dependencies(preload: str = "") -> SafeString:
    """Marks location where JS script tags should be rendered."""

    if is_dependency_middleware_active():
        preloaded_dependencies = []
        for component in _get_components_from_preload_str(preload):
            preloaded_dependencies.append(RENDERED_COMMENT_TEMPLATE.format(name=component.registered_name))
        return mark_safe("\n".join(preloaded_dependencies) + JS_DEPENDENCY_PLACEHOLDER)
    else:
        rendered_dependencies = []
        for component in _get_components_from_registry(component_registry):
            rendered_dependencies.append(component.render_js_dependencies())

        return mark_safe("\n".join(rendered_dependencies))

fill ¤

fill(parser: Parser, token: Token) -> FillNode

Block tag whose contents 'fill' (are inserted into) an identically named 'slot'-block in the component template referred to by a parent component. It exists to make component nesting easier.

This tag is available only within a {% component %}..{% endcomponent %} block. Runtime checks should prohibit other usages.

Source code in src/django_components/templatetags/component_tags.py
@register.tag("fill")
def fill(parser: Parser, token: Token) -> FillNode:
    """
    Block tag whose contents 'fill' (are inserted into) an identically named
    'slot'-block in the component template referred to by a parent component.
    It exists to make component nesting easier.

    This tag is available only within a {% component %}..{% endcomponent %} block.
    Runtime checks should prohibit other usages.
    """
    tag = _parse_tag(
        "fill",
        parser,
        token,
        params=[SLOT_NAME_KWARG],
        optional_params=[SLOT_NAME_KWARG],
        keywordonly_kwargs=[SLOT_DATA_KWARG, SLOT_DEFAULT_KWARG],
        repeatable_kwargs=False,
        end_tag="endfill",
    )

    fill_name_kwarg = tag.kwargs.kwargs.get(SLOT_NAME_KWARG, None)
    trace_id = f"fill-id-{tag.id} ({fill_name_kwarg})" if fill_name_kwarg else f"fill-id-{tag.id}"

    trace_msg("PARSE", "FILL", trace_id, tag.id)

    body = tag.parse_body()
    fill_node = FillNode(
        nodelist=body,
        node_id=tag.id,
        kwargs=tag.kwargs,
        trace_id=trace_id,
    )

    trace_msg("PARSE", "FILL", trace_id, tag.id, "...Done!")
    return fill_node

html_attrs ¤

html_attrs(parser: Parser, token: Token) -> HtmlAttrsNode

This tag takes: - Optional dictionary of attributes (attrs) - Optional dictionary of defaults (defaults) - Additional kwargs that are appended to the former two

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

Rules: 1. Both attrs and defaults can be passed as positional args or as kwargs 2. Both attrs and defaults are optional (can be omitted) 3. Both attrs and defaults are dictionaries, and we can define them the same way we define dictionaries for the component tag. So either as attrs=attrs or attrs:key=value. 4. All other kwargs (key=value) are appended and can be repeated.

Normal kwargs (key=value) are concatenated to existing keys. So if e.g. key "class" is supplied with value "my-class", then adding class="extra-class" will result in `class="my-class extra-class".

Example:

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

Source code in src/django_components/templatetags/component_tags.py
@register.tag("html_attrs")
def html_attrs(parser: Parser, token: Token) -> HtmlAttrsNode:
    """
    This tag takes:
    - Optional dictionary of attributes (`attrs`)
    - Optional dictionary of defaults (`defaults`)
    - Additional kwargs that are appended to the former two

    The inputs are merged and resulting dict is rendered as HTML attributes
    (`key="value"`).

    Rules:
    1. Both `attrs` and `defaults` can be passed as positional args or as kwargs
    2. Both `attrs` and `defaults` are optional (can be omitted)
    3. Both `attrs` and `defaults` are dictionaries, and we can define them the same way
       we define dictionaries for the `component` tag. So either as `attrs=attrs` or
       `attrs:key=value`.
    4. All other kwargs (`key=value`) are appended and can be repeated.

    Normal kwargs (`key=value`) are concatenated to existing keys. So if e.g. key
    "class" is supplied with value "my-class", then adding `class="extra-class"`
    will result in `class="my-class extra-class".

    Example:
    ```htmldjango
    {% html_attrs attrs defaults:class="default-class" class="extra-class" data-id="123" %}
    ```
    """
    tag = _parse_tag(
        "html_attrs",
        parser,
        token,
        params=[HTML_ATTRS_ATTRS_KEY, HTML_ATTRS_DEFAULTS_KEY],
        optional_params=[HTML_ATTRS_ATTRS_KEY, HTML_ATTRS_DEFAULTS_KEY],
        flags=[],
        keywordonly_kwargs=True,
        repeatable_kwargs=True,
    )

    return HtmlAttrsNode(
        kwargs=tag.kwargs,
        kwarg_pairs=tag.kwarg_pairs,
    )