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:
componentmust 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:
TagFormatterextracts 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_tagend_tagparse
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!