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!
    
Top comments (0)