Tag formatters
Customizing component tags with TagFormatter¤
New in version 0.89
By default, components are rendered using the pair of {% component %}
/ {% endcomponent %}
template tags:
{% component "button" href="..." disabled %}
Click me!
{% endcomponent %}
{# or #}
{% component "button" href="..." disabled / %}
You can change this behaviour in the settings under the COMPONENTS.tag_formatter
.
For example, if you set the tag formatter to
django_components.component_shorthand_formatter
then the components' names will be used as the template tags:
{% button href="..." disabled %}
Click me!
{% endbutton %}
{# or #}
{% button href="..." disabled / %}
Available TagFormatters¤
django_components provides following predefined TagFormatters:
ComponentFormatter
(django_components.component_formatter
)
Default
Uses the component
and endcomponent
tags, and the component name is gives as the first positional argument.
Example as block:
Example as inlined tag:
ShorthandComponentFormatter
(django_components.component_shorthand_formatter
)
Uses the component name as start tag, and end<component_name>
as an end tag.
Example as block:
Example as inlined tag:
Writing your own TagFormatter¤
Background¤
First, let's discuss how TagFormatters work, and how components are rendered in django_components.
When you render a component with {% component %}
(or your own tag), the following happens:
component
must be registered as a Django's template tag- Django triggers django_components's tag handler for tag
component
. - The tag handler passes the tag contents for pre-processing to
TagFormatter.parse()
.
So if you render this:
Then TagFormatter.parse()
will receive a following input:
TagFormatter
extracts the component name and the remaining input.
So, given the above, TagFormatter.parse()
returns the following:
- The tag handler resumes, using the tokens returned from
TagFormatter
.
So, continuing the example, at this point the tag handler practically behaves as if you rendered:
- Tag handler looks up the component
button
, and passes the args, kwargs, and slots to it.
TagFormatter¤
TagFormatter
handles following parts of the process above:
-
Generates start/end tags, given a component. This is what you then call from within your template as
{% component %}
. -
When you
{% component %}
, tag formatter pre-processes the tag contents, so it can link back the custom template tag to the right component.
To do so, subclass from TagFormatterABC
and implement following method:
start_tag
end_tag
parse
For example, this is the implementation of ShorthandComponentFormatter
class ShorthandComponentFormatter(TagFormatterABC):
# Given a component name, generate the start template tag
def start_tag(self, name: str) -> str:
return name # e.g. 'button'
# Given a component name, generate the start template tag
def end_tag(self, name: str) -> str:
return f"end{name}" # e.g. 'endbutton'
# Given a tag, e.g.
# `{% button href="..." disabled %}`
#
# The parser receives:
# `['button', 'href="..."', 'disabled']`
def parse(self, tokens: List[str]) -> TagResult:
tokens = [*tokens]
name = tokens.pop(0)
return TagResult(
name, # e.g. 'button'
tokens # e.g. ['href="..."', 'disabled']
)
That's it! And once your TagFormatter
is ready, don't forget to update the settings!