Authoring component libraries
You can publish and share your components for others to use. Here are the steps to do so:
Writing component libraries¤
-
Create a Django project with a similar structure:
-
Create custom
Library
andComponentRegistry
instances inmytags.py
This will be the entrypoint for using the components inside Django templates.
Remember that Django requires the
Library
instance to be accessible under theregister
variable (See Django docs):from django.template import Library from django_components import ComponentRegistry, RegistrySettings register = library = django.template.Library() comp_registry = ComponentRegistry( library=library, settings=RegistrySettings( context_behavior="isolated", tag_formatter="django_components.component_formatter", ), )
As you can see above, this is also the place where we configure how our components should behave, using the
settings
argument. If omitted, default settings are used.For library authors, we recommend setting
context_behavior
to"isolated"
, so that the state cannot leak into the components, and so the components' behavior is configured solely through the inputs. This means that the components will be more predictable and easier to debug.Next, you can decide how will others use your components by setting the
tag_formatter
options.If omitted or set to
"django_components.component_formatter"
, your components will be used like this:Or you can use
"django_components.component_shorthand_formatter"
to use components like so:Or you can define a custom TagFormatter.
Either way, these settings will be scoped only to your components. So, in the user code, there may be components side-by-side that use different formatters:
-
Write your components and register them with your instance of
ComponentRegistry
There's one difference when you are writing components that are to be shared, and that's that the components must be explicitly registered with your instance of
ComponentRegistry
from the previous step.For better user experience, you can also define the types for the args, kwargs, slots and data.
It's also a good idea to have a common prefix for your components, so they can be easily distinguished from users' components. In the example below, we use the prefix
my_
/My
.from typing import Dict, NotRequired, Optional, Tuple, TypedDict from django_components import Component, SlotFunc, register, types from myapp.templatetags.mytags import comp_registry # Define the types class EmptyDict(TypedDict): pass type MyMenuArgs = Tuple[int, str] class MyMenuSlots(TypedDict): default: NotRequired[Optional[SlotFunc[EmptyDict]]] class MyMenuProps(TypedDict): vertical: NotRequired[bool] klass: NotRequired[str] style: NotRequired[str] # Define the component # NOTE: Don't forget to set the `registry`! @register("my_menu", registry=comp_registry) class MyMenu(Component[MyMenuArgs, MyMenuProps, MyMenuSlots, Any, Any, Any]): def get_context_data( self, *args, attrs: Optional[Dict] = None, ): return { "attrs": attrs, } template: types.django_html = """ {# Load django_components template tags #} {% load component_tags %} <div {% html_attrs attrs class="my-menu" %}> <div class="my-menu__content"> {% slot "default" default / %} </div> </div> """
-
Import the components in
apps.py
Normally, users rely on autodiscovery and
COMPONENTS.dirs
to load the component files.Since you, as the library author, are not in control of the file system, it is recommended to load the components manually.
We recommend doing this in the
AppConfig.ready()
hook of yourapps.py
:from django.apps import AppConfig class MyAppConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" name = "myapp" # This is the code that gets run when user adds myapp # to Django's INSTALLED_APPS def ready(self) -> None: # Import the components that you want to make available # inside the templates. from myapp.templates import ( menu, table, )
Note that you can also include any other startup logic within
AppConfig.ready()
.
And that's it! The next step is to publish it.
Publishing component libraries¤
Once you are ready to share your library, you need to build a distribution and then publish it to PyPI.
django_components uses the build
utility to build a distribution:
And to publish to PyPI, you can use twine
(See Python user guide)
Notes on publishing:
- If you use components where the HTML / CSS / JS files are separate, you may need to define
MANIFEST.in
to include those files with the distribution (see user guide).
Installing and using component libraries¤
After the package has been published, all that remains is to install it in other django projects:
-
Install the package:
-
Add the package to
INSTALLED_APPS
-
Optionally add the template tags to the
builtins
, so you don't have to call{% load mytags %}
in every template: -
And, at last, you can use the components in your own project!