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)