6 KiB
By the end of this section, we want to be able to use our components in Django templates like so:
{% load component_tags %}
<!DOCTYPE html>
<html>
<head>
<title>My example calendar</title>
</head>
<body>
{% component "calendar" / %}
</body>
<html>
1. Register component
First, however, we need to register our component class with ComponentRegistry
.
To register a component with a ComponentRegistry
,
we will use the @register
decorator, and give it a name under which the component will be accessible from within the template:
from django_components import Component, register # <--- new
@register("calendar") # <--- new
class Calendar(Component):
template_file = "calendar.html"
js_file = "calendar.js"
css_file = "calendar.css"
def get_template_data(self, args, kwargs, slots, context):
return {
"date": "1970-01-01",
}
This will register the component to the default registry. Default registry is loaded into the template
by calling {% load component_tags %}
inside the template.
!!! info
**Why do we have to register components?**
We want to use our component as a template tag (`{% ... %}`) in Django template.
In Django, template tags are managed by the `Library` instances. Whenever you include `{% load xxx %}`
in your template, you are loading a `Library` instance into your template.
[`ComponentRegistry`](../../reference/api#django_components.ComponentRegistry) acts like a router
and connects the registered components with the associated `Library`.
That way, when you include `{% load component_tags %}` in your template, you are able to "call" components
like `{% component "calendar" / %}`.
`ComponentRegistries` also make it possible to group and share components as standalone packages.
[Learn more here](../../concepts/advanced/component_libraries).
!!! note
You can create custom [`ComponentRegistry`](../../reference/api#django_components.ComponentRegistry)
instances, which will use different `Library` instances.
In that case you will have to load different libraries depending on which components you want to use:
Example 1 - Using component defined in the default registry
```htmldjango
{% load component_tags %}
<div>
{% component "calendar" / %}
</div>
```
Example 2 - Using component defined in a custom registry
```htmldjango
{% load my_custom_tags %}
<div>
{% my_component "table" / %}
</div>
```
Note that, because the tag name `component` is use by the default ComponentRegistry,
the custom registry was configured to use the tag `my_component` instead. [Read more here](../../concepts/advanced/component_registry)
2. Load and use the component in template
The component is now registered under the name calendar
. All that remains to do is to load
and render the component inside a template:
{% load component_tags %} {# Load the default registry #}
<!DOCTYPE html>
<html>
<head>
<title>My example calendar</title>
</head>
<body>
{% component "calendar" / %} {# Render the component #}
</body>
<html>
!!! info
Component tags should end with `/` if they do not contain any [Slot fills](../../concepts/fundamentals/slots).
But you can also use `{% endcomponent %}` instead:
```htmldjango
{% component "calendar" %}{% endcomponent %}
```
We defined the Calendar's template as
<div class="calendar">
Today's date is <span>{{ date }}</span>
</div>
and the variable date
as "1970-01-01"
.
Thus, the final output will look something like this:
<!DOCTYPE html>
<html>
<head>
<title>My example calendar</title>
<style>
.calendar {
width: 200px;
background: pink;
}
.calendar span {
font-weight: bold;
}
</style>
</head>
<body>
<div class="calendar">
Today's date is <span>1970-01-01</span>
</div>
<script>
(function () {
document.querySelector(".calendar").onclick = () => {
alert("Clicked calendar!");
};
})();
</script>
</body>
<html>
This makes it possible to organize your front-end around reusable components, instead of relying on template tags and keeping your CSS and Javascript in the static directory.
!!! info
Remember that you can use
[`{% component_js_dependencies %}`](../../reference/template_tags#component_js_dependencies)
and [`{% component_css_dependencies %}`](../../reference/template_tags#component_css_dependencies)
to change where the `<script>` and `<style>` tags will be rendered
(See [Default JS / CSS locations](../../concepts/advanced/rendering_js_css#default-js-css-locations)).
!!! info
**How does django-components pick up registered components?**
Notice that it was enough to add [`@register`](../../reference/api#django_components.register) to the component.
We didn't need to import the component file anywhere to execute it.
This is because django-components automatically imports all Python files found in the component directories
during an event called [Autodiscovery](../../concepts/fundamentals/autodiscovery).
So with Autodiscovery, it's the same as if you manually imported the component files on the `ready()` hook:
```python
class MyApp(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "myapp"
def ready(self):
import myapp.components.calendar
import myapp.components.table
...
```
You can now render the components in templates!
Currently our component always renders the same content. Let's parametrise it, so that our Calendar component is configurable from within the template ➡️