django-components v0.94 - Templating is now on par with Vue or React
Juro Oravec
Posted on September 25, 2024
Hey, I'm Juro, I'm one of the maintainers of django-components. In releases v0.90-0.94 we've added features that make using components in templates much more flexible, similar to JSX / Vue.
(This info is already a bit dated (released a month ago; latest is v0.101), as I'm busy adding support for JS / CSS variables, TypeScript & Sass, and HTML fragment. Exciting stuff! But I realized haven't shared this update yet!)
Anyway, The following is a component blog_post
, that accepts a title
, id
, and additional kwargs applied from blog_post_props
:
{% blog_post
title="{{ person.first_name }} {{ person.last_name }}"
id="{% random_int 10 20 %}"
...blog_post_props
/ %}
The above is a combination of multiple features:
1. Self-closing tags:
Instead of
{% component "my_component" %}
{% endcomponent %}
You can now simply write
{% component "my_component" / %}
2. Multi-line tags:
django_components now automatically configures Django to allow multi-line tags. So instead of cramming everything on a single line:
{% component "blog_post" title="abcdef..." author="John Wick" date_published="2024-08-28" %}
{% endcomponent %}
You can spread it across multiple lines:
{% component "blog_post"
title="abcdef..."
author="John Wick"
date_published="2024-08-28"
/ %}
3. Spread operator:
Similarly to ...props
operator in JSX or v-bind
in Vue, this inserts props / kwargs into a given position.
So instead of
{% component "blog_post"
title="abcdef..."
author="John Wick"
date_published="2024-08-28"
/ %}
You can have the kwargs in a dictionary, and then apply that:
# Python
props = {
"title": "abcdef...",
"author": "John Wick",
"date_published": "2024-08-28"
}
{# Django #}
{% component "blog_post" ...props %}
4. Template tags inside string literals in component inputs:
You can now use template tags and flters inside component inputs:
{% component 'blog_post'
"As positional arg {# yay #}"
title="{{ person.first_name }} {{ person.last_name }}"
id="{% random_int 10 20 %}"
readonly="{{ editable|not }}"
/ %}
This way you don't have to define extra variables every time you need to format a value.
Note that when there is only a single tag and no extra text around it, then the result is passed as a value. So "{% random_int 10 20 %}"
passes in a number, and "{{ editable|not }}"
passes a boolean.
You can even go a step further and have a similar experience to Vue or React, where you can evaluate arbitrary code expressions, AKA similar to this:
<MyForm
value={ isEnabled ? inputValue : null }
/>
This can be possible with django-expr, which adds an expr
tag and filter that you can use to evaluate Python expressions from within the template:
{% component "my_form"
value="{% expr 'input_value if is_enabled else None' %}"
/ %}
5. Support for {% comp_name %} {% endcomp_name %}
and TagFormatter
By default, the components are written using the component
tag, followed by the name of the component:
{% component "button" href="..." disabled %}
Click me!
{% endcomponent %}
You can now change this (and even make your own!).
For example, setting COMPONENTS.tag_formatter
to "django_components.shorthand_component_formatter"
allows you to write components like so:
{% button href="..." disabled %}
Click me!
{% endbutton %}
Lots more is to come, so be sure to give django-components a try!
Posted on September 25, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.