Components
django-components ships these ready-to-use components. Register them like any other component, then use them in your templates.
DynamicComponent
Bases: django_components.component.Component
This component is given a registered name or a reference to another component, and behaves as if the other component was in its place.
The args, kwargs, and slot fills are all passed down to the underlying component.
| Parameter | Type | Description |
|---|---|---|
is | str | type[Component] | Component that should be rendered. Either a registered name of a component, or a Component class directly. Required. |
registry | ComponentRegistry | None | Specify the registry to search for the registered name. If omitted, all registries are searched until the first match. (default: None) |
*args | Any | None | Additional data passed to the component. (default: None) |
**kwargs | Any | None | Additional data passed to the component. (default: None) |
Slots:
- Any slots, depending on the actual component.
Example
Django
{% component "dynamic" is=table_comp data=table_data headers=table_headers %}
{% fill "pagination" %}
{% component "pagination" / %}
{% endfill %}
{% endcomponent %}
Or in case you use the django_components.component_shorthand_formatter tag formatter:
{% dynamic is=table_comp data=table_data headers=table_headers %}
{% fill "pagination" %}
{% component "pagination" / %}
{% endfill %}
{% enddynamic %}
Python
from django_components import DynamicComponent
DynamicComponent.render(
kwargs={
"is": table_comp,
"data": table_data,
"headers": table_headers,
},
slots={
"pagination": PaginationComponent.render(
deps_strategy="ignore",
),
},
)
Use cases
Dynamic components are suitable if you are writing something like a form component. You may design it such that users give you a list of input types, and you render components depending on the input types.
While you could handle this with a series of if / else statements, that's not an extensible approach. Instead, you can use the dynamic component in place of normal components.
Component name
By default, the dynamic component is registered under the name "dynamic". In case of a conflict, you can set the COMPONENTS.dynamic_component_name setting to change the name used for the dynamic components.
# settings.py
COMPONENTS = ComponentsSettings(
dynamic_component_name="my_dynamic",
)
After which you will be able to use the dynamic component with the new name:
{% component "my_dynamic" is=table_comp data=table_data headers=table_headers %}
{% fill "pagination" %}
{% component "pagination" / %}
{% endfill %}
{% endcomponent %}
ErrorFallback
Bases: django_components.component.Component
A component that catches errors and displays fallback content, similar to React's ErrorBoundary.
See React's ErrorBoundary component.
Parameters:
- fallback (str, optional): A string to display when an error occurs. Cannot be used together with the
fallbackslot.
Slots:
- content or default: The main content that might raise an error.
- fallback: Custom fallback content to display when an error occurs. When using the
fallbackslot, you can access theerrorobject through slot data ({% fill "fallback" data="data" %}). Cannot be used together with thefallbackkwarg.
Example
Given this template:
{% component "error_fallback" fallback="Oops, something went wrong" %}
{% component "table" / %}
{% endcomponent %}
Then:
- If the
tablecomponent does NOT raise an error, then the table is rendered as normal. - If the
tablecomponent DOES raise an error, thenerror_fallbackrendersOops, something went wrong.
To have more control over the fallback content, you can use the fallback slot instead of the fallback kwarg.
{% component "error_fallback" %}
{% fill "content" %}
{% component "table" / %}
{% endfill %}
{% fill "fallback" %}
<p>Oops, something went wrong</p>
{% button href="/report-error" %}
Report error
{% endbutton %}
{% endfill %}
{% endcomponent %}
If you want to print the error, you can access the error variable as slot data.
{% component "error_fallback" %}
{% fill "content" %}
{% component "table" / %}
{% endfill %}
{% fill "fallback" data="data" %}
Oops, something went wrong:
<pre>{{ data.error }}</pre>
{% endfill %}
{% endcomponent %}
Python:
With fallback kwarg:
from django_components import ErrorFallback
ErrorFallback.render(
slots={
# Main content
"content": lambda ctx: TableComponent.render(
deps_strategy="ignore",
),
},
kwargs={
# Fallback content
"fallback": "Oops, something went wrong",
},
)
With fallback slot:
from django_components import ErrorFallback
ErrorFallback.render(
slots={
# Main content
"content": lambda ctx: TableComponent.render(
deps_strategy="ignore",
),
# Fallback content
"fallback": lambda ctx: mark_safe("Oops, something went wrong: " + ctx.error),
},
)
Info
Remember to define the content slot as function, so it's evaluated from inside of ErrorFallback.