DEV Community

Juro Oravec
Juro Oravec

Posted on

django-components v0.94 - Templating is now on par with Vue or React

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 / %} 
Enter fullscreen mode Exit fullscreen mode

The above is a combination of multiple features:

1. Self-closing tags:

Instead of

 {% component "my_component" %} {% endcomponent %} 
Enter fullscreen mode Exit fullscreen mode

You can now simply write

 {% component "my_component" / %} 
Enter fullscreen mode Exit fullscreen mode

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 %} 
Enter fullscreen mode Exit fullscreen mode

You can spread it across multiple lines:

 {% component "blog_post" title="abcdef..." author="John Wick" date_published="2024-08-28" / %} 
Enter fullscreen mode Exit fullscreen mode

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" / %} 
Enter fullscreen mode Exit fullscreen mode

You can have the kwargs in a dictionary, and then apply that:

 # Python props = { "title": "abcdef...", "author": "John Wick", "date_published": "2024-08-28" } 
Enter fullscreen mode Exit fullscreen mode
 {# Django #} {% component "blog_post" ...props %} 
Enter fullscreen mode Exit fullscreen mode

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 }}" / %} 
Enter fullscreen mode Exit fullscreen mode

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 } /> 
Enter fullscreen mode Exit fullscreen mode

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' %}" / %} 
Enter fullscreen mode Exit fullscreen mode

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 %} 
Enter fullscreen mode Exit fullscreen mode

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 %} 
Enter fullscreen mode Exit fullscreen mode

Lots more is to come, so be sure to give django-components a try!

Top comments (0)