API¤
BaseNode ¤
BaseNode(
params: List[TagAttr], flags: Optional[Dict[str, bool]] = None, nodelist: Optional[NodeList] = None, node_id: Optional[str] = None
)
Bases: django.template.base.Node
Node class for all django-components custom template tags.
This class has a dual role:
-
It declares how a particular template tag should be parsed - By setting the
tag
,end_tag
, andallowed_flags
attributes:This will allow the template tag
{% slot %}
to be used like this: -
The
render
method is the actual implementation of the template tag.This is where the tag's logic is implemented:
class MyNode(BaseNode): tag = "mynode" def render(self, context: Context, name: str, **kwargs: Any) -> str: return f"Hello, {name}!"
This will allow the template tag
{% mynode %}
to be used like this:
The template tag accepts parameters as defined on the render
method's signature.
For more info, see BaseNode.render()
.
Methods:
-
parse
– -
register
– -
render
– -
unregister
–
Attributes:
-
active_flags
(List[str]
) – -
allowed_flags
(Optional[List[str]]
) – -
end_tag
(Optional[str]
) – -
flags
– -
node_id
– -
nodelist
– -
params
– -
tag
(str
) –
active_flags property
¤
Flags that were set for this specific instance.
allowed_flags class-attribute
instance-attribute
¤
The allowed flags for this tag.
E.g. ["required"]
will allow this tag to be used like {% slot required %}
.
end_tag class-attribute
instance-attribute
¤
The end tag name.
E.g. "endcomponent"
or "endslot"
will make this class match template tags {% endcomponent %}
or {% endslot %}
.
If not set, then this template tag has no end tag.
So instead of {% component %} ... {% endcomponent %}
, you'd use only {% component %}
.
tag instance-attribute
¤
tag: str
The tag name.
E.g. "component"
or "slot"
will make this class match template tags {% component %}
or {% slot %}
.
parse classmethod
¤
This function is what is passed to Django's Library.tag()
when registering the tag.
In other words, this method is called by Django's template parser when we encounter a tag that matches this node's tag, e.g. {% component %}
or {% slot %}
.
To register the tag, you can use BaseNode.register()
.
register classmethod
¤
A convenience method for registering the tag with the given library.
Allows you to then use the node in templates like so:
render ¤
Render the node. This method is meant to be overridden by subclasses.
The signature of this function decides what input the template tag accepts.
The render()
method MUST accept a context
argument. Any arguments after that will be part of the tag's input parameters.
So if you define a render
method like this:
Then the tag will require the name
parameter, and accept any extra keyword arguments:
unregister classmethod
¤
Unregisters the node from the given library.
CommandArg dataclass
¤
CommandArg(
name_or_flags: Union[str, Sequence[str]],
action: Optional[Union[CommandLiteralAction, Action]] = None,
nargs: Optional[Union[int, Literal["*", "+", "?"]]] = None,
const: Any = None,
default: Any = None,
type: Optional[Union[Type, Callable[[str], Any]]] = None,
choices: Optional[Sequence[Any]] = None,
required: Optional[bool] = None,
help: Optional[str] = None,
metavar: Optional[str] = None,
dest: Optional[str] = None,
version: Optional[str] = None,
deprecated: Optional[bool] = None,
)
Bases: object
Define a single positional argument or an option for a command.
Fields on this class correspond to the arguments for ArgumentParser.add_argument()
Methods:
-
asdict
–
Attributes:
-
action
(Optional[Union[CommandLiteralAction, Action]]
) – -
choices
(Optional[Sequence[Any]]
) – -
const
(Any
) – -
default
(Any
) – -
deprecated
(Optional[bool]
) – -
dest
(Optional[str]
) – -
help
(Optional[str]
) – -
metavar
(Optional[str]
) – -
name_or_flags
(Union[str, Sequence[str]]
) – -
nargs
(Optional[Union[int, Literal['*', '+', '?']]]
) – -
required
(Optional[bool]
) – -
type
(Optional[Union[Type, Callable[[str], Any]]]
) – -
version
(Optional[str]
) –
action class-attribute
instance-attribute
¤
action: Optional[Union[CommandLiteralAction, Action]] = None
The basic type of action to be taken when this argument is encountered at the command line.
choices class-attribute
instance-attribute
¤
A sequence of the allowable values for the argument.
const class-attribute
instance-attribute
¤
const: Any = None
A constant value required by some action and nargs selections.
default class-attribute
instance-attribute
¤
default: Any = None
The value produced if the argument is absent from the command line and if it is absent from the namespace object.
deprecated class-attribute
instance-attribute
¤
Whether or not use of the argument is deprecated.
NOTE: This is supported only in Python 3.13+
dest class-attribute
instance-attribute
¤
The name of the attribute to be added to the object returned by parse_args().
help class-attribute
instance-attribute
¤
A brief description of what the argument does.
metavar class-attribute
instance-attribute
¤
A name for the argument in usage messages.
name_or_flags instance-attribute
¤
Either a name or a list of option strings, e.g. 'foo' or '-f', '--foo'.
nargs class-attribute
instance-attribute
¤
The number of command-line arguments that should be consumed.
required class-attribute
instance-attribute
¤
Whether or not the command-line option may be omitted (optionals only).
type class-attribute
instance-attribute
¤
The type to which the command-line argument should be converted.
version class-attribute
instance-attribute
¤
The version string to be added to the object returned by parse_args().
MUST be used with action='version'
.
CommandArgGroup dataclass
¤
CommandArgGroup(title: Optional[str] = None, description: Optional[str] = None, arguments: Sequence[CommandArg] = ())
Bases: object
Define a group of arguments for a command.
Fields on this class correspond to the arguments for ArgumentParser.add_argument_group()
Methods:
-
asdict
–
Attributes:
-
arguments
(Sequence[CommandArg]
) – -
description
(Optional[str]
) – -
title
(Optional[str]
) –
description class-attribute
instance-attribute
¤
Description for the argument group in help output, by default None
title class-attribute
instance-attribute
¤
Title for the argument group in help output; by default “positional arguments” if description is provided, otherwise uses title for positional arguments.
CommandHandler ¤
CommandLiteralAction module-attribute
¤
CommandLiteralAction = Literal['append', 'append_const', 'count', 'extend', 'store', 'store_const', 'store_true', 'store_false', 'version']
The basic type of action to be taken when this argument is encountered at the command line.
This is a subset of the values for action
in ArgumentParser.add_argument()
.
CommandParserInput dataclass
¤
CommandParserInput(
prog: Optional[str] = None,
usage: Optional[str] = None,
description: Optional[str] = None,
epilog: Optional[str] = None,
parents: Optional[Sequence[ArgumentParser]] = None,
formatter_class: Optional[Type[_FormatterClass]] = None,
prefix_chars: Optional[str] = None,
fromfile_prefix_chars: Optional[str] = None,
argument_default: Optional[Any] = None,
conflict_handler: Optional[str] = None,
add_help: Optional[bool] = None,
allow_abbrev: Optional[bool] = None,
exit_on_error: Optional[bool] = None,
)
Bases: object
Typing for the input to the ArgumentParser
constructor.
Methods:
-
asdict
–
Attributes:
-
add_help
(Optional[bool]
) – -
allow_abbrev
(Optional[bool]
) – -
argument_default
(Optional[Any]
) – -
conflict_handler
(Optional[str]
) – -
description
(Optional[str]
) – -
epilog
(Optional[str]
) – -
exit_on_error
(Optional[bool]
) – -
formatter_class
(Optional[Type[_FormatterClass]]
) – -
fromfile_prefix_chars
(Optional[str]
) – -
parents
(Optional[Sequence[ArgumentParser]]
) – -
prefix_chars
(Optional[str]
) – -
prog
(Optional[str]
) – -
usage
(Optional[str]
) –
add_help class-attribute
instance-attribute
¤
Add a -h/--help option to the parser (default: True
)
allow_abbrev class-attribute
instance-attribute
¤
Allows long options to be abbreviated if the abbreviation is unambiguous. (default: True
)
argument_default class-attribute
instance-attribute
¤
The global default value for arguments (default: None
)
conflict_handler class-attribute
instance-attribute
¤
The strategy for resolving conflicting optionals (usually unnecessary)
description class-attribute
instance-attribute
¤
Text to display before the argument help (by default, no text)
epilog class-attribute
instance-attribute
¤
Text to display after the argument help (by default, no text)
exit_on_error class-attribute
instance-attribute
¤
Determines whether or not ArgumentParser exits with error info when an error occurs. (default: True
)
formatter_class class-attribute
instance-attribute
¤
A class for customizing the help output
fromfile_prefix_chars class-attribute
instance-attribute
¤
The set of characters that prefix files from which additional arguments should be read (default: None
)
parents class-attribute
instance-attribute
¤
parents: Optional[Sequence[ArgumentParser]] = None
A list of ArgumentParser objects whose arguments should also be included
prefix_chars class-attribute
instance-attribute
¤
The set of characters that prefix optional arguments (default: ‘-‘)
prog class-attribute
instance-attribute
¤
The name of the program (default: os.path.basename(sys.argv[0])
)
usage class-attribute
instance-attribute
¤
The string describing the program usage (default: generated from arguments added to parser)
CommandSubcommand dataclass
¤
CommandSubcommand(
title: Optional[str] = None,
description: Optional[str] = None,
prog: Optional[str] = None,
parser_class: Optional[Type[ArgumentParser]] = None,
action: Optional[Union[CommandLiteralAction, Action]] = None,
dest: Optional[str] = None,
required: Optional[bool] = None,
help: Optional[str] = None,
metavar: Optional[str] = None,
)
Bases: object
Define a subcommand for a command.
Fields on this class correspond to the arguments for ArgumentParser.add_subparsers.add_parser()
Methods:
-
asdict
–
Attributes:
-
action
(Optional[Union[CommandLiteralAction, Action]]
) – -
description
(Optional[str]
) – -
dest
(Optional[str]
) – -
help
(Optional[str]
) – -
metavar
(Optional[str]
) – -
parser_class
(Optional[Type[ArgumentParser]]
) – -
prog
(Optional[str]
) – -
required
(Optional[bool]
) – -
title
(Optional[str]
) –
action class-attribute
instance-attribute
¤
action: Optional[Union[CommandLiteralAction, Action]] = None
The basic type of action to be taken when this argument is encountered at the command line.
description class-attribute
instance-attribute
¤
Description for the sub-parser group in help output, by default None
.
dest class-attribute
instance-attribute
¤
Name of the attribute under which sub-command name will be stored; by default None
and no value is stored.
help class-attribute
instance-attribute
¤
Help for sub-parser group in help output, by default None
.
metavar class-attribute
instance-attribute
¤
String presenting available subcommands in help; by default it is None and presents subcommands in form {cmd1, cmd2, ..}
.
parser_class class-attribute
instance-attribute
¤
parser_class: Optional[Type[ArgumentParser]] = None
Class which will be used to create sub-parser instances, by default the class of the current parser (e.g. ArgumentParser
).
prog class-attribute
instance-attribute
¤
Usage information that will be displayed with sub-command help, by default the name of the program and any positional arguments before the subparser argument.
required class-attribute
instance-attribute
¤
Whether or not a subcommand must be provided, by default False
(added in 3.7)
title class-attribute
instance-attribute
¤
Title for the sub-parser group in help output; by default “subcommands” if description is provided, otherwise uses title for positional arguments.
Component ¤
Component(registered_name: Optional[str] = None, outer_context: Optional[Context] = None, registry: Optional[ComponentRegistry] = None)
Methods:
-
as_view
– -
get_context_data
– -
get_template
– -
get_template_name
– -
inject
– -
on_render_after
– -
on_render_before
– -
render
– -
render_to_response
–
Attributes:
-
Media
(Optional[Type[ComponentMediaInput]]
) – -
context_processors_data
(Dict
) – -
css
(Optional[str]
) – -
css_file
(Optional[str]
) – -
id
(str
) – -
input
(RenderInput[ArgsType, KwargsType, SlotsType]
) – -
is_filled
(SlotIsFilled
) – -
js
(Optional[str]
) – -
js_file
(Optional[str]
) – -
media
(Optional[Media]
) – -
media_class
(Type[Media]
) – -
name
(str
) – -
outer_context
(Optional[Context]
) – -
registered_name
(Optional[str]
) – -
registry
– -
request
(Optional[HttpRequest]
) – -
response_class
– -
template
(Optional[Union[str, Template]]
) – -
template_file
(Optional[str]
) – -
template_name
(Optional[str]
) –
Media class-attribute
instance-attribute
¤
Media: Optional[Type[ComponentMediaInput]] = None
Defines JS and CSS media files associated with this component.
This Media
class behaves similarly to Django's Media class:
- Paths are generally handled as static file paths, and resolved URLs are rendered to HTML with
media_class.render_js()
ormedia_class.render_css()
. - A path that starts with
http
,https
, or/
is considered a URL, skipping the static file resolution. This path is still rendered to HTML withmedia_class.render_js()
ormedia_class.render_css()
. - A
SafeString
(with__html__
method) is considered an already-formatted HTML tag, skipping both static file resolution and rendering withmedia_class.render_js()
ormedia_class.render_css()
. - You can set
extend
to configure whether to inherit JS / CSS from parent components. See Controlling Media Inheritance.
However, there's a few differences from Django's Media class:
- Our Media class accepts various formats for the JS and CSS files: either a single file, a list, or (CSS-only) a dictionary (See
ComponentMediaInput
). - Individual JS / CSS files can be any of
str
,bytes
,Path
,SafeString
, or a function (SeeComponentMediaInputPath
).
Example:
context_processors_data property
¤
context_processors_data: Dict
Retrieve data injected by context_processors
.
This data is also available from within the component's template, without having to return this data from get_context_data()
.
Unlike regular Django templates, the context processors are applied to components either when:
- The component is rendered with
RequestContext
(Regular Django behavior) - The component is rendered with a regular
Context
(or none), but therequest
kwarg ofComponent.render()
is set. - The component is nested in another component that matches one of the two conditions above.
See Component.request
on how the request
(HTTPRequest) object is passed to and within the components.
Raises RuntimeError
if accessed outside of rendering execution.
Example:
css class-attribute
instance-attribute
¤
css_file class-attribute
instance-attribute
¤
Main CSS associated with this component as file path.
The filepath must be either:
- Relative to the directory where the Component's Python file is defined.
- Relative to one of the component directories, as set by
COMPONENTS.dirs
orCOMPONENTS.app_dirs
(e.g.<root>/components/
). - Relative to the staticfiles directories, as set by Django's
STATICFILES_DIRS
setting (e.g.<root>/static/
).
When you create a Component class with css_file
, these will happen:
- If the file path is relative to the directory where the component's Python file is, the path is resolved.
- The file is read and its contents is set to
Component.css
.
Only one of css
or css_file
must be defined.
Example:
id property
¤
id: str
This ID is unique for every time a Component.render()
(or equivalent) is called (AKA "render ID").
This is useful for logging or debugging.
Raises RuntimeError
if accessed outside of rendering execution.
A single render ID has a chance of collision 1 in 3.3M. However, due to birthday paradox, the chance of collision increases when approaching ~1,000 render IDs.
Thus, there is a soft-cap of 1,000 components rendered on a single page.
If you need to more than that, please open an issue on GitHub.
Example:
input property
¤
Input holds the data (like arg, kwargs, slots) that were passed to the current execution of the render
method.
Raises RuntimeError
if accessed outside of rendering execution.
is_filled property
¤
Dictionary describing which slots have or have not been filled.
This attribute is available for use only within the template as {{ component_vars.is_filled.slot_name }}
, and within on_render_before
and on_render_after
hooks.
Raises RuntimeError
if accessed outside of rendering execution.
js class-attribute
instance-attribute
¤
js_file class-attribute
instance-attribute
¤
Main JS associated with this component as file path.
The filepath must be either:
- Relative to the directory where the Component's Python file is defined.
- Relative to one of the component directories, as set by
COMPONENTS.dirs
orCOMPONENTS.app_dirs
(e.g.<root>/components/
). - Relative to the staticfiles directories, as set by Django's
STATICFILES_DIRS
setting (e.g.<root>/static/
).
When you create a Component class with js_file
, these will happen:
- If the file path is relative to the directory where the component's Python file is, the path is resolved.
- The file is read and its contents is set to
Component.js
.
Only one of js
or js_file
must be defined.
Example:
media class-attribute
instance-attribute
¤
media: Optional[Media] = None
Normalized definition of JS and CSS media files associated with this component. None
if Component.Media
is not defined.
This field is generated from Component.media_class
.
Read more on Accessing component's HTML / JS / CSS.
Example:
media_class class-attribute
instance-attribute
¤
media_class: Type[Media] = Media
Set the Media class that will be instantiated with the JS and CSS media files from Component.Media
.
This is useful when you want to customize the behavior of the media files, like customizing how the JS or CSS files are rendered into <script>
or <link>
HTML tags. Read more in Defining HTML / JS / CSS files.
Example:
request property
¤
request: Optional[HttpRequest]
HTTPRequest object passed to this component.
In regular Django templates, you have to use RequestContext
to pass the HttpRequest
object to the template.
But in Components, you can either use RequestContext
, or pass the request
object explicitly via Component.render()
and Component.render_to_response()
.
When a component is nested in another, the child component uses parent's request
object.
Raises RuntimeError
if accessed outside of rendering execution.
Example:
response_class class-attribute
instance-attribute
¤
response_class = HttpResponse
This allows to configure what class is used to generate response from render_to_response
template class-attribute
instance-attribute
¤
Inlined Django template associated with this component. Can be a plain string or a Template instance.
Only one of template_file
, get_template_name
, template
or get_template
must be defined.
Example:
template_file class-attribute
instance-attribute
¤
Filepath to the Django template associated with this component.
The filepath must be either:
- Relative to the directory where the Component's Python file is defined.
- Relative to one of the component directories, as set by
COMPONENTS.dirs
orCOMPONENTS.app_dirs
(e.g.<root>/components/
). - Relative to the template directories, as set by Django's
TEMPLATES
setting (e.g.<root>/templates/
).
Only one of template_file
, get_template_name
, template
or get_template
must be defined.
Example:
template_name instance-attribute
¤
Alias for template_file
.
For historical reasons, django-components used template_name
to align with Django's TemplateView.
template_file
was introduced to align with js/js_file
and css/css_file
.
Setting and accessing this attribute is proxied to template_file
.
as_view classmethod
¤
as_view(**initkwargs: Any) -> ViewFn
Shortcut for calling Component.View.as_view
and passing component instance to it.
get_template ¤
Inlined Django template associated with this component. Can be a plain string or a Template instance.
Only one of template_file
, get_template_name
, template
or get_template
must be defined.
get_template_name ¤
Filepath to the Django template associated with this component.
The filepath must be relative to either the file where the component class was defined, or one of the roots of STATIFILES_DIRS
.
Only one of template_file
, get_template_name
, template
or get_template
must be defined.
inject ¤
Use this method to retrieve the data that was passed to a {% provide %}
tag with the corresponding key.
To retrieve the data, inject()
must be called inside a component that's inside the {% provide %}
tag.
You may also pass a default that will be used if the provide
tag with given key was NOT found.
This method mut be used inside the get_context_data()
method and raises an error if called elsewhere.
Example:
Given this template:
{% provide "provider" hello="world" %}
{% component "my_comp" %}
{% endcomponent %}
{% endprovide %}
And given this definition of "my_comp" component:
from django_components import Component, register
@register("my_comp")
class MyComp(Component):
template = "hi {{ data.hello }}!"
def get_context_data(self):
data = self.inject("provider")
return {"data": data}
This renders into:
As the {{ data.hello }}
is taken from the "provider".
on_render_after ¤
on_render_after(context: Context, template: Template, content: str) -> Optional[SlotResult]
Hook that runs just after the component's template was rendered. It receives the rendered output as the last argument.
You can use this hook to access the context or the template, but modifying them won't have any effect.
To override the content that gets rendered, you can return a string or SafeString from this hook.
on_render_before ¤
Hook that runs just before the component's template is rendered.
You can use this hook to access or modify the context or the template.
render classmethod
¤
render(
context: Optional[Union[Dict[str, Any], Context]] = None,
args: Optional[ArgsType] = None,
kwargs: Optional[KwargsType] = None,
slots: Optional[SlotsType] = None,
escape_slots_content: bool = True,
type: RenderType = "document",
render_dependencies: bool = True,
request: Optional[HttpRequest] = None,
) -> str
Render the component into a string.
Inputs: - args
- Positional args for the component. This is the same as calling the component as {% component "my_comp" arg1 arg2 ... %}
- kwargs
- Kwargs for the component. This is the same as calling the component as {% component "my_comp" key1=val1 key2=val2 ... %}
- slots
- Component slot fills. This is the same as pasing {% fill %}
tags to the component. Accepts a dictionary of { slot_name: slot_content }
where slot_content
can be a string or render function. - escape_slots_content
- Whether the content from slots
should be escaped. - context
- A context (dictionary or Django's Context) within which the component is rendered. The keys on the context can be accessed from within the template. - NOTE: In "isolated" mode, context is NOT accessible, and data MUST be passed via component's args and kwargs. - type
- Configure how to handle JS and CSS dependencies. - "document"
(default) - JS dependencies are inserted into {% component_js_dependencies %}
, or to the end of the <body>
tag. CSS dependencies are inserted into {% component_css_dependencies %}
, or the end of the <head>
tag. - render_dependencies
- Set this to False
if you want to insert the resulting HTML into another component. - request
- The request object. This is only required when needing to use RequestContext, e.g. to enable template context_processors
. Example:
render_to_response classmethod
¤
render_to_response(
context: Optional[Union[Dict[str, Any], Context]] = None,
slots: Optional[SlotsType] = None,
escape_slots_content: bool = True,
args: Optional[ArgsType] = None,
kwargs: Optional[KwargsType] = None,
type: RenderType = "document",
request: Optional[HttpRequest] = None,
*response_args: Any,
**response_kwargs: Any
) -> HttpResponse
Render the component and wrap the content in the response class.
The response class is taken from Component.response_class
. Defaults to django.http.HttpResponse
.
This is the interface for the django.views.View
class which allows us to use components as Django views with component.as_view()
.
Inputs: - args
- Positional args for the component. This is the same as calling the component as {% component "my_comp" arg1 arg2 ... %}
- kwargs
- Kwargs for the component. This is the same as calling the component as {% component "my_comp" key1=val1 key2=val2 ... %}
- slots
- Component slot fills. This is the same as pasing {% fill %}
tags to the component. Accepts a dictionary of { slot_name: slot_content }
where slot_content
can be a string or render function. - escape_slots_content
- Whether the content from slots
should be escaped. - context
- A context (dictionary or Django's Context) within which the component is rendered. The keys on the context can be accessed from within the template. - NOTE: In "isolated" mode, context is NOT accessible, and data MUST be passed via component's args and kwargs. - type
- Configure how to handle JS and CSS dependencies. - "document"
(default) - JS dependencies are inserted into {% component_js_dependencies %}
, or to the end of the <body>
tag. CSS dependencies are inserted into {% component_css_dependencies %}
, or the end of the <head>
tag. - request
- The request object. This is only required when needing to use RequestContext, e.g. to enable template context_processors
.
Any additional args and kwargs are passed to the response_class
.
Example:
MyComponent.render_to_response(
args=[1, "two", {}],
kwargs={
"key": 123,
},
slots={
"header": 'STATIC TEXT HERE',
"footer": lambda ctx, slot_kwargs, slot_ref: f'CTX: {ctx['hello']} SLOT_DATA: {slot_kwargs['abc']}',
},
escape_slots_content=False,
# HttpResponse input
status=201,
headers={...},
)
# HttpResponse(content=..., status=201, headers=...)
ComponentCommand ¤
Bases: object
Definition of a CLI command.
This class is based on Python's argparse
module and Django's BaseCommand
class. ComponentCommand
allows you to define:
- Command name, description, and help text
- Arguments and options (e.g.
--name John
) - Group arguments (see argparse groups)
- Subcommands (e.g.
components ext run my_ext hello
) - Handler behavior
Each extension can add its own commands, which will be available to run with components ext run
.
Extensions use the ComponentCommand
class to define their commands.
For example, if you define and install the following extension:
from django_components ComponentCommand, ComponentExtension
class HelloCommand(ComponentCommand):
name = "hello"
help = "Say hello"
def handle(self, *args, **kwargs):
print("Hello, world!")
class MyExt(ComponentExtension):
name = "my_ext"
commands = [HelloCommand]
You can run the hello
command with:
You can also define arguments for the command, which will be passed to the command's handle
method.
from django_components import CommandArg, ComponentCommand, ComponentExtension
class HelloCommand(ComponentCommand):
name = "hello"
help = "Say hello"
arguments = [
CommandArg(name="name", help="The name to say hello to"),
CommandArg(name=["--shout", "-s"], action="store_true"),
]
def handle(self, name: str, *args, **kwargs):
shout = kwargs.get("shout", False)
msg = f"Hello, {name}!"
if shout:
msg = msg.upper()
print(msg)
You can run the command with:
Note
Command arguments and options are based on Python's argparse
module.
For more information, see the argparse documentation.
Attributes:
-
arguments
(Sequence[Union[CommandArg, CommandArgGroup]]
) – -
handle
(Optional[CommandHandler]
) – -
help
(Optional[str]
) – -
name
(str
) – -
parser_input
(Optional[CommandParserInput]
) – -
subcommands
(Sequence[Type[ComponentCommand]]
) – -
subparser_input
(Optional[CommandSubcommand]
) –
arguments class-attribute
instance-attribute
¤
arguments: Sequence[Union[CommandArg, CommandArgGroup]] = ()
argparse arguments for the command
handle class-attribute
instance-attribute
¤
handle: Optional[CommandHandler] = None
The function that is called when the command is run. If None
, the command will print the help message.
help class-attribute
instance-attribute
¤
The help text for the command
name instance-attribute
¤
name: str
The name of the command - this is what is used to call the command
parser_input class-attribute
instance-attribute
¤
parser_input: Optional[CommandParserInput] = None
The input to use when creating the ArgumentParser
for this command. If None
, the default values will be used.
subcommands class-attribute
instance-attribute
¤
subcommands: Sequence[Type[ComponentCommand]] = ()
Subcommands for the command
subparser_input class-attribute
instance-attribute
¤
subparser_input: Optional[CommandSubcommand] = None
The input to use when this command is a subcommand installed with add_subparser()
. If None
, the default values will be used.
ComponentExtension ¤
Bases: object
Base class for all extensions.
Read more on Extensions.
Methods:
-
on_component_class_created
– -
on_component_class_deleted
– -
on_component_data
– -
on_component_input
– -
on_component_registered
– -
on_component_unregistered
– -
on_registry_created
– -
on_registry_deleted
–
Attributes:
-
ExtensionClass
– -
class_name
(str
) – -
commands
(List[Type[ComponentCommand]]
) – -
name
(str
) – -
urls
(List[URLRoute]
) –
ExtensionClass class-attribute
instance-attribute
¤
Base class that the "extension class" nested within a Component
class will inherit from.
This is where you can define new methods and attributes that will be available to the component instance.
Background:
The extension may add new features to the Component
class by allowing users to define and access a nested class in the Component
class. E.g.:
class MyComp(Component):
class MyExtension:
...
def get_context_data(self):
return {
"my_extension": self.my_extension.do_something(),
}
When rendering a component, the nested extension class will be set as a subclass of ExtensionClass
. So it will be same as if the user had directly inherited from ExtensionClass
. E.g.:
This setting decides what the extension class will inherit from.
class_name instance-attribute
¤
class_name: str
Name of the extension class.
By default, this is the same as name
, but with snake_case converted to PascalCase.
So if the extension name is "my_extension"
, then the extension class name will be "MyExtension"
.
commands class-attribute
instance-attribute
¤
commands: List[Type[ComponentCommand]] = []
List of commands that can be run by the extension.
These commands will be available to the user as components ext run <extension> <command>
.
Commands are defined as subclasses of ComponentCommand
.
Example:
This example defines an extension with a command that prints "Hello world". To run the command, the user would run components ext run hello_world hello
.
from django_components import ComponentCommand, ComponentExtension, CommandArg, CommandArgGroup
class HelloWorldCommand(ComponentCommand):
name = "hello"
help = "Hello world command."
# Allow to pass flags `--foo`, `--bar` and `--baz`.
# Argument parsing is managed by `argparse`.
arguments = [
CommandArg(
name_or_flags="--foo",
help="Foo description.",
),
# When printing the command help message, `bar` and `baz`
# will be grouped under "group bar".
CommandArgGroup(
title="group bar",
description="Group description.",
arguments=[
CommandArg(
name_or_flags="--bar",
help="Bar description.",
),
CommandArg(
name_or_flags="--baz",
help="Baz description.",
),
],
),
]
# Callback that receives the parsed arguments and options.
def handle(self, *args, **kwargs):
print(f"HelloWorldCommand.handle: args={args}, kwargs={kwargs}")
# Associate the command with the extension
class HelloWorldExtension(ComponentExtension):
name = "hello_world"
commands = [
HelloWorldCommand,
]
name instance-attribute
¤
name: str
Name of the extension.
Name must be lowercase, and must be a valid Python identifier (e.g. "my_extension"
).
The extension may add new features to the Component
class by allowing users to define and access a nested class in the Component
class.
The extension name determines the name of the nested class in the Component
class, and the attribute under which the extension will be accessible.
E.g. if the extension name is "my_extension"
, then the nested class in the Component
class will be MyExtension
, and the extension will be accessible as MyComp.my_extension
.
on_component_class_created ¤
on_component_class_created(ctx: OnComponentClassCreatedContext) -> None
on_component_class_deleted ¤
on_component_class_deleted(ctx: OnComponentClassDeletedContext) -> None
Called when a Component
class is being deleted.
This hook is called before the Component
class is deleted from memory.
Use this hook to perform any cleanup related to the Component
class.
Example:
from django_components import ComponentExtension, OnComponentClassDeletedContext
class MyExtension(ComponentExtension):
def on_component_class_deleted(self, ctx: OnComponentClassDeletedContext) -> None:
# Remove Component class from the extension's cache on deletion
self.cache.pop(ctx.component_cls, None)
on_component_data ¤
on_component_data(ctx: OnComponentDataContext) -> None
Called when a Component was triggered to render, after a component's context and data methods have been processed.
This hook is called after Component.get_context_data()
, Component.get_js_data()
and Component.get_css_data()
.
This hook runs after on_component_input
.
Use this hook to modify or validate the component's data before rendering.
Example:
on_component_input ¤
on_component_input(ctx: OnComponentInputContext) -> None
Called when a Component
was triggered to render, but before a component's context and data methods are invoked.
This hook is called before Component.get_context_data()
, Component.get_js_data()
and Component.get_css_data()
.
Use this hook to modify or validate component inputs before they're processed.
Example:
on_component_registered ¤
on_component_registered(ctx: OnComponentRegisteredContext) -> None
Called when a Component
class is registered with a ComponentRegistry
.
This hook is called after a Component
class is successfully registered.
Example:
on_component_unregistered ¤
on_component_unregistered(ctx: OnComponentUnregisteredContext) -> None
Called when a Component
class is unregistered from a ComponentRegistry
.
This hook is called after a Component
class is removed from the registry.
Example:
on_registry_created ¤
on_registry_created(ctx: OnRegistryCreatedContext) -> None
Called when a new ComponentRegistry
is created.
This hook is called after a new ComponentRegistry
instance is initialized.
Use this hook to perform any initialization needed for the registry.
Example:
on_registry_deleted ¤
on_registry_deleted(ctx: OnRegistryDeletedContext) -> None
Called when a ComponentRegistry
is being deleted.
This hook is called before a ComponentRegistry
instance is deleted.
Use this hook to perform any cleanup related to the registry.
Example:
ComponentFileEntry ¤
Bases: tuple
Result returned by get_component_files()
.
Attributes:
ComponentMediaInput ¤
Bases: typing.Protocol
Defines JS and CSS media files associated with a Component
.
class MyTable(Component):
class Media:
js = [
"path/to/script.js",
"https://unpkg.com/alpinejs@3.14.7/dist/cdn.min.js", # AlpineJS
]
css = {
"all": [
"path/to/style.css",
"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", # TailwindCSS
],
"print": ["path/to/style2.css"],
}
Attributes:
-
css
(Optional[Union[ComponentMediaInputPath, List[ComponentMediaInputPath], Dict[str, ComponentMediaInputPath], Dict[str, List[ComponentMediaInputPath]]]]
) – -
extend
(Union[bool, List[Type[Component]]]
) – -
js
(Optional[Union[ComponentMediaInputPath, List[ComponentMediaInputPath]]]
) –
css class-attribute
instance-attribute
¤
css: Optional[
Union[
ComponentMediaInputPath, List[ComponentMediaInputPath], Dict[str, ComponentMediaInputPath], Dict[str, List[ComponentMediaInputPath]]
]
] = None
CSS files associated with a Component
.
-
If a string, it's assumed to be a path to a CSS file.
-
If a list, each entry is assumed to be a path to a CSS file.
-
If a dict, the keys are media types (e.g. "all", "print", "screen", etc.), and the values are either:
- A string, assumed to be a path to a CSS file.
- A list, each entry is assumed to be a path to a CSS file.
Each entry can be a string, bytes, SafeString, PathLike, or a callable that returns one of the former (see ComponentMediaInputPath
).
Examples:
extend class-attribute
instance-attribute
¤
Configures whether the component should inherit the media files from the parent component.
- If
True
, the component inherits the media files from the parent component. - If
False
, the component does not inherit the media files from the parent component. - If a list of components classes, the component inherits the media files ONLY from these specified components.
Read more in Controlling Media Inheritance section.
Example:
Disable media inheritance:
class ParentComponent(Component):
class Media:
js = ["parent.js"]
class MyComponent(ParentComponent):
class Media:
extend = False # Don't inherit parent media
js = ["script.js"]
print(MyComponent.media._js) # ["script.js"]
Specify which components to inherit from. In this case, the media files are inherited ONLY from the specified components, and NOT from the original parent components:
class ParentComponent(Component):
class Media:
js = ["parent.js"]
class MyComponent(ParentComponent):
class Media:
# Only inherit from these, ignoring the files from the parent
extend = [OtherComponent1, OtherComponent2]
js = ["script.js"]
print(MyComponent.media._js) # ["script.js", "other1.js", "other2.js"]
js class-attribute
instance-attribute
¤
js: Optional[Union[ComponentMediaInputPath, List[ComponentMediaInputPath]]] = None
JS files associated with a Component
.
-
If a string, it's assumed to be a path to a JS file.
-
If a list, each entry is assumed to be a path to a JS file.
Each entry can be a string, bytes, SafeString, PathLike, or a callable that returns one of the former (see ComponentMediaInputPath
).
Examples:
ComponentMediaInputPath module-attribute
¤
ComponentMediaInputPath = Union[str, bytes, SafeData, Path, PathLike, Callable[[], Union[str, bytes, SafeData, Path, PathLike]]]
A type representing an entry in Media.js or Media.css.
If an entry is a SafeString (or has __html__
method), then entry is assumed to be a formatted HTML tag. Otherwise, it's assumed to be a path to a file.
Example:
ComponentRegistry ¤
ComponentRegistry(
library: Optional[Library] = None, settings: Optional[Union[RegistrySettings, Callable[[ComponentRegistry], RegistrySettings]]] = None
)
Bases: object
Manages components and makes them available in the template, by default as {% component %}
tags.
To enable a component to be used in a template, the component must be registered with a component registry.
When you register a component to a registry, behind the scenes the registry automatically adds the component's template tag (e.g. {% component %}
to the Library
. And the opposite happens when you unregister a component - the tag is removed.
Parameters:
-
library
(Library
, default:None
) –Django
Library
associated with this registry. If omitted, the default Library instance from django_components is used. -
settings
(Union[RegistrySettings, Callable[[ComponentRegistry], RegistrySettings]]
, default:None
) –Configure how the components registered with this registry will behave when rendered. See
RegistrySettings
. Can be either a static value or a callable that returns the settings. If omitted, the settings fromCOMPONENTS
are used.
Notes:
- The default registry is available as
django_components.registry
. - The default registry is used when registering components with
@register
decorator.
Example:
# Use with default Library
registry = ComponentRegistry()
# Or a custom one
my_lib = Library()
registry = ComponentRegistry(library=my_lib)
# Usage
registry.register("button", ButtonComponent)
registry.register("card", CardComponent)
registry.all()
registry.clear()
registry.get("button")
registry.has("button")
Using registry to share components¤
You can use component registry for isolating or "packaging" components:
-
Create new instance of
ComponentRegistry
and Library: -
Register components to the registry:
-
In your target project, load the Library associated with the registry:
-
Use the registered components in your templates:
Methods:
Attributes:
settings property
¤
Registry settings configured for this registry.
all ¤
clear ¤
Clears the registry, unregistering all components.
Example:
get ¤
Retrieve a Component
class registered under the given name.
Parameters:
-
name
(str
) –The name under which the component was registered. Required.
Returns:
Raises:
NotRegistered
if the given name is not registered.
Example:
has ¤
register ¤
Register a Component
class with this registry under the given name.
A component MUST be registered before it can be used in a template such as:
Parameters:
-
name
(str
) –The name under which the component will be registered. Required.
-
component
(Type[Component]
) –The component class to register. Required.
Raises:
AlreadyRegistered
if a different component was already registered under the same name.
Example:
unregister ¤
unregister(name: str) -> None
Unregister the Component
class that was registered under the given name.
Once a component is unregistered, it is no longer available in the templates.
Parameters:
-
name
(str
) –The name under which the component is registered. Required.
Raises:
NotRegistered
if the given name is not registered.
Example:
ComponentVars ¤
Bases: tuple
Type for the variables available inside the component templates.
All variables here are scoped under component_vars.
, so e.g. attribute is_filled
on this class is accessible inside the template as:
Attributes:
is_filled instance-attribute
¤
Dictonary describing which component slots are filled (True
) or are not (False
).
New in version 0.70
Use as {{ component_vars.is_filled }}
Example:
{# Render wrapping HTML only if the slot is defined #}
{% if component_vars.is_filled.my_slot %}
<div class="slot-wrapper">
{% slot "my_slot" / %}
</div>
{% endif %}
This is equivalent to checking if a given key is among the slot fills:
ComponentView ¤
Bases: django_components.extension.BaseExtensionClass
, django.views.generic.base.View
Subclass of django.views.View
where the Component
instance is available via self.component
.
Methods:
Attributes:
ComponentsSettings ¤
Bases: tuple
Settings available for django_components.
Example:
Attributes:
-
app_dirs
(Optional[Sequence[str]]
) – -
autodiscover
(Optional[bool]
) – -
cache
(Optional[str]
) – -
context_behavior
(Optional[ContextBehaviorType]
) – -
debug_highlight_components
(Optional[bool]
) – -
debug_highlight_slots
(Optional[bool]
) – -
dirs
(Optional[Sequence[Union[str, PathLike, Tuple[str, str], Tuple[str, PathLike]]]]
) – -
dynamic_component_name
(Optional[str]
) – -
extensions
(Optional[Sequence[Union[Type[ComponentExtension], str]]]
) – -
forbidden_static_files
(Optional[List[Union[str, Pattern]]]
) – -
libraries
(Optional[List[str]]
) – -
multiline_tags
(Optional[bool]
) – -
reload_on_file_change
(Optional[bool]
) – -
reload_on_template_change
(Optional[bool]
) – -
static_files_allowed
(Optional[List[Union[str, Pattern]]]
) – -
static_files_forbidden
(Optional[List[Union[str, Pattern]]]
) – -
tag_formatter
(Optional[Union[TagFormatterABC, str]]
) – -
template_cache_size
(Optional[int]
) –
app_dirs class-attribute
instance-attribute
¤
Specify the app-level directories that contain your components.
Defaults to ["components"]
. That is, for each Django app, we search <app>/components/
for components.
The paths must be relative to app, e.g.:
To search for <app>/my_comps/
.
These locations are searched during autodiscovery, or when you define HTML, JS, or CSS as separate files.
Set to empty list to disable app-level components:
autodiscover class-attribute
instance-attribute
¤
Toggle whether to run autodiscovery at the Django server startup.
Defaults to True
cache class-attribute
instance-attribute
¤
Name of the Django cache to be used for storing component's JS and CSS files.
If None
, a LocMemCache
is used with default settings.
Defaults to None
.
Read more about caching.
context_behavior class-attribute
instance-attribute
¤
context_behavior: Optional[ContextBehaviorType] = None
Configure whether, inside a component template, you can use variables from the outside ("django"
) or not ("isolated"
). This also affects what variables are available inside the {% fill %}
tags.
Also see Component context and scope.
Defaults to "django"
.
NOTE:
context_behavior
andslot_context_behavior
options were merged in v0.70.If you are migrating from BEFORE v0.67, set
context_behavior
to"django"
. From v0.67 to v0.78 (incl) the default value was"isolated"
.For v0.79 and later, the default is again
"django"
. See the rationale for change here.
debug_highlight_components class-attribute
instance-attribute
¤
Enable / disable component highlighting. See Troubleshooting for more details.
Defaults to False
.
debug_highlight_slots class-attribute
instance-attribute
¤
Enable / disable slot highlighting. See Troubleshooting for more details.
Defaults to False
.
dirs class-attribute
instance-attribute
¤
Specify the directories that contain your components.
Defaults to [Path(settings.BASE_DIR) / "components"]
. That is, the root components/
app.
Directories must be full paths, same as with STATICFILES_DIRS.
These locations are searched during autodiscovery, or when you define HTML, JS, or CSS as separate files.
Set to empty list to disable global components directories:
dynamic_component_name class-attribute
instance-attribute
¤
By default, the dynamic component is registered under the name "dynamic"
.
In case of a conflict, you can use this setting to change the component name used for the dynamic components.
After which you will be able to use the dynamic component with the new name:
extensions class-attribute
instance-attribute
¤
List of extensions to be loaded.
The extensions can be specified as:
- Python import path, e.g.
"path.to.my_extension.MyExtension"
. - Extension class, e.g.
my_extension.MyExtension
.
forbidden_static_files class-attribute
instance-attribute
¤
Deprecated. Use COMPONENTS.static_files_forbidden
instead.
libraries class-attribute
instance-attribute
¤
Configure extra python modules that should be loaded.
This may be useful if you are not using the autodiscovery feature, or you need to load components from non-standard locations. Thus you can have a structure of components that is independent from your apps.
Expects a list of python module paths. Defaults to empty list.
Example:
COMPONENTS = ComponentsSettings(
libraries=[
"mysite.components.forms",
"mysite.components.buttons",
"mysite.components.cards",
],
)
This would be the equivalent of importing these modules from within Django's AppConfig.ready()
:
class MyAppConfig(AppConfig):
def ready(self):
import "mysite.components.forms"
import "mysite.components.buttons"
import "mysite.components.cards"
Manually loading libraries¤
In the rare case that you need to manually trigger the import of libraries, you can use the import_libraries()
function:
multiline_tags class-attribute
instance-attribute
¤
Enable / disable multiline support for template tags. If True
, template tags like {% component %}
or {{ my_var }}
can span multiple lines.
Defaults to True
.
Disable this setting if you are making custom modifications to Django's regular expression for parsing templates at django.template.base.tag_re
.
reload_on_file_change class-attribute
instance-attribute
¤
This is relevant if you are using the project structure where HTML, JS, CSS and Python are in separate files and nested in a directory.
In this case you may notice that when you are running a development server, the server sometimes does not reload when you change component files.
Django's native live reload logic handles only Python files and HTML template files. It does NOT reload when other file types change or when template files are nested more than one level deep.
The setting reload_on_file_change
fixes this, reloading the dev server even when your component's HTML, JS, or CSS changes.
If True
, django_components configures Django to reload when files inside COMPONENTS.dirs
or COMPONENTS.app_dirs
change.
See Reload dev server on component file changes.
Defaults to False
.
Warning
This setting should be enabled only for the dev environment!
reload_on_template_change class-attribute
instance-attribute
¤
Deprecated. Use COMPONENTS.reload_on_file_change
instead.
static_files_allowed class-attribute
instance-attribute
¤
A list of file extensions (including the leading dot) that define which files within COMPONENTS.dirs
or COMPONENTS.app_dirs
are treated as static files.
If a file is matched against any of the patterns, it's considered a static file. Such files are collected when running collectstatic
, and can be accessed under the static file endpoint.
You can also pass in compiled regexes (re.Pattern
) for more advanced patterns.
By default, JS, CSS, and common image and font file formats are considered static files:
COMPONENTS = ComponentsSettings(
static_files_allowed=[
".css",
".js", ".jsx", ".ts", ".tsx",
# Images
".apng", ".png", ".avif", ".gif", ".jpg",
".jpeg", ".jfif", ".pjpeg", ".pjp", ".svg",
".webp", ".bmp", ".ico", ".cur", ".tif", ".tiff",
# Fonts
".eot", ".ttf", ".woff", ".otf", ".svg",
],
)
Warning
Exposing your Python files can be a security vulnerability. See Security notes.
static_files_forbidden class-attribute
instance-attribute
¤
A list of file extensions (including the leading dot) that define which files within COMPONENTS.dirs
or COMPONENTS.app_dirs
will NEVER be treated as static files.
If a file is matched against any of the patterns, it will never be considered a static file, even if the file matches a pattern in static_files_allowed
.
Use this setting together with static_files_allowed
for a fine control over what file types will be exposed.
You can also pass in compiled regexes (re.Pattern
) for more advanced patterns.
By default, any HTML and Python are considered NOT static files:
COMPONENTS = ComponentsSettings(
static_files_forbidden=[
".html", ".django", ".dj", ".tpl",
# Python files
".py", ".pyc",
],
)
Warning
Exposing your Python files can be a security vulnerability. See Security notes.
tag_formatter class-attribute
instance-attribute
¤
tag_formatter: Optional[Union[TagFormatterABC, str]] = None
Configure what syntax is used inside Django templates to render components. See the available tag formatters.
Defaults to "django_components.component_formatter"
.
Learn more about Customizing component tags with TagFormatter.
Can be set either as direct reference:
from django_components import component_formatter
COMPONENTS = ComponentsSettings(
"tag_formatter": component_formatter
)
Or as an import string;
Examples:
template_cache_size class-attribute
instance-attribute
¤
Configure the maximum amount of Django templates to be cached.
Defaults to 128
.
Each time a Django template is rendered, it is cached to a global in-memory cache (using Python's lru_cache
decorator). This speeds up the next render of the component. As the same component is often used many times on the same page, these savings add up.
By default the cache holds 128 component templates in memory, which should be enough for most sites. But if you have a lot of components, or if you are overriding Component.get_template()
to render many dynamic templates, you can increase this number.
To remove the cache limit altogether and cache everything, set template_cache_size
to None
.
If you want to add templates to the cache yourself, you can use cached_template()
:
ContextBehavior ¤
Bases: str
, enum.Enum
Configure how (and whether) the context is passed to the component fills and what variables are available inside the {% fill %}
tags.
Also see Component context and scope.
Options:
django
: With this setting, component fills behave as usual Django tags.isolated
: This setting makes the component fills behave similar to Vue or React.
Attributes:
DJANGO class-attribute
instance-attribute
¤
With this setting, component fills behave as usual Django tags. That is, they enrich the context, and pass it along.
- Component fills use the context of the component they are within.
- Variables from
Component.get_context_data()
are available to the component fill.
Example:
Given this template
{% with cheese="feta" %}
{% component 'my_comp' %}
{{ my_var }} # my_var
{{ cheese }} # cheese
{% endcomponent %}
{% endwith %}
and this context returned from the Component.get_context_data()
method
Then if component "my_comp" defines context
Then this will render:
Because "my_comp" overrides the variable "my_var", so {{ my_var }}
equals 456
.
And variable "cheese" will equal feta
, because the fill CAN access the current context.
ISOLATED class-attribute
instance-attribute
¤
This setting makes the component fills behave similar to Vue or React, where the fills use EXCLUSIVELY the context variables defined in Component.get_context_data()
.
Example:
Given this template
{% with cheese="feta" %}
{% component 'my_comp' %}
{{ my_var }} # my_var
{{ cheese }} # cheese
{% endcomponent %}
{% endwith %}
and this context returned from the get_context_data()
method
Then if component "my_comp" defines context
Then this will render:
Because both variables "my_var" and "cheese" are taken from the root context. Since "cheese" is not defined in root context, it's empty.
EmptyDict ¤
Bases: dict
TypedDict with no members.
You can use this to define a Component that accepts NO kwargs, or NO slots, or returns NO data from Component.get_context_data()
/ Component.get_js_data()
/ Component.get_css_data()
:
Accepts NO kwargs:
from django_components import Component, EmptyDict
class Table(Component(Any, EmptyDict, Any, Any, Any, Any))
...
Accepts NO slots:
from django_components import Component, EmptyDict
class Table(Component(Any, Any, EmptyDict, Any, Any, Any))
...
Returns NO data from get_context_data()
:
from django_components import Component, EmptyDict
class Table(Component(Any, Any, Any, EmptyDict, Any, Any))
...
Going back to the example with NO kwargs, when you then call Component.render()
or Component.render_to_response()
, the kwargs
parameter will raise type error if kwargs
is anything else than an empty dict.
Omitting kwargs
is also fine:
Other values are not allowed. This will raise an error with MyPy:
EmptyTuple module-attribute
¤
EmptyTuple = Tuple[]
Tuple with no members.
You can use this to define a Component that accepts NO positional arguments:
from django_components import Component, EmptyTuple
class Table(Component(EmptyTuple, Any, Any, Any, Any, Any))
...
After that, when you call Component.render()
or Component.render_to_response()
, the args
parameter will raise type error if args
is anything else than an empty tuple.
Omitting args
is also fine:
Other values are not allowed. This will raise an error with MyPy:
OnComponentClassCreatedContext ¤
Attributes:
-
component_cls
(Type[Component]
) –
component_cls instance-attribute
¤
The created Component class
OnComponentClassDeletedContext ¤
Attributes:
-
component_cls
(Type[Component]
) –
component_cls instance-attribute
¤
The to-be-deleted Component class
OnComponentDataContext ¤
Attributes:
-
component
(Component
) – -
component_cls
(Type[Component]
) – -
component_id
(str
) – -
context_data
(Dict
) – -
css_data
(Dict
) – -
js_data
(Dict
) –
component_cls instance-attribute
¤
The Component class
component_id instance-attribute
¤
component_id: str
The unique identifier for this component instance
context_data instance-attribute
¤
context_data: Dict
Dictionary of context data from Component.get_context_data()
OnComponentInputContext ¤
Attributes:
-
args
(List
) – -
component
(Component
) – -
component_cls
(Type[Component]
) – -
component_id
(str
) – -
context
(Context
) – -
kwargs
(Dict
) – -
slots
(Dict
) –
component instance-attribute
¤
component: Component
The Component instance that received the input and is being rendered
component_cls instance-attribute
¤
The Component class
component_id instance-attribute
¤
component_id: str
The unique identifier for this component instance
OnComponentRegisteredContext ¤
Attributes:
-
component_cls
(Type[Component]
) – -
name
(str
) – -
registry
(ComponentRegistry
) –
component_cls instance-attribute
¤
The registered Component class
registry instance-attribute
¤
registry: ComponentRegistry
The registry the component was registered to
OnComponentUnregisteredContext ¤
Attributes:
-
component_cls
(Type[Component]
) – -
name
(str
) – -
registry
(ComponentRegistry
) –
component_cls instance-attribute
¤
The unregistered Component class
registry instance-attribute
¤
registry: ComponentRegistry
The registry the component was unregistered from
OnRegistryCreatedContext ¤
Attributes:
OnRegistryDeletedContext ¤
Attributes:
registry instance-attribute
¤
registry: ComponentRegistry
The to-be-deleted ComponentRegistry instance
RegistrySettings ¤
Bases: tuple
Configuration for a ComponentRegistry
.
These settings define how the components registered with this registry will behave when rendered.
from django_components import ComponentRegistry, RegistrySettings
registry_settings = RegistrySettings(
context_behavior="django",
tag_formatter="django_components.component_shorthand_formatter",
)
registry = ComponentRegistry(settings=registry_settings)
Attributes:
-
CONTEXT_BEHAVIOR
(Optional[ContextBehaviorType]
) – -
TAG_FORMATTER
(Optional[Union[TagFormatterABC, str]]
) – -
context_behavior
(Optional[ContextBehaviorType]
) – -
tag_formatter
(Optional[Union[TagFormatterABC, str]]
) –
CONTEXT_BEHAVIOR class-attribute
instance-attribute
¤
CONTEXT_BEHAVIOR: Optional[ContextBehaviorType] = None
Deprecated. Use context_behavior
instead. Will be removed in v1.
Same as the global COMPONENTS.context_behavior
setting, but for this registry.
If omitted, defaults to the global COMPONENTS.context_behavior
setting.
TAG_FORMATTER class-attribute
instance-attribute
¤
TAG_FORMATTER: Optional[Union[TagFormatterABC, str]] = None
Deprecated. Use tag_formatter
instead. Will be removed in v1.
Same as the global COMPONENTS.tag_formatter
setting, but for this registry.
If omitted, defaults to the global COMPONENTS.tag_formatter
setting.
context_behavior class-attribute
instance-attribute
¤
context_behavior: Optional[ContextBehaviorType] = None
Same as the global COMPONENTS.context_behavior
setting, but for this registry.
If omitted, defaults to the global COMPONENTS.context_behavior
setting.
tag_formatter class-attribute
instance-attribute
¤
tag_formatter: Optional[Union[TagFormatterABC, str]] = None
Same as the global COMPONENTS.tag_formatter
setting, but for this registry.
If omitted, defaults to the global COMPONENTS.tag_formatter
setting.
Slot dataclass
¤
Slot(
content_func: SlotFunc[TSlotData],
escaped: bool = False,
component_name: Optional[str] = None,
slot_name: Optional[str] = None,
nodelist: Optional[NodeList] = None,
)
Bases: typing.Generic
This class holds the slot content function along with related metadata.
Attributes:
-
component_name
(Optional[str]
) – -
content_func
(SlotFunc[TSlotData]
) – -
do_not_call_in_templates
(bool
) – -
escaped
(bool
) – -
nodelist
(Optional[NodeList]
) – -
slot_name
(Optional[str]
) –
component_name class-attribute
instance-attribute
¤
Name of the component that originally defined or accepted this slot fill.
escaped class-attribute
instance-attribute
¤
escaped: bool = False
Whether the slot content has been escaped.
nodelist class-attribute
instance-attribute
¤
nodelist: Optional[NodeList] = None
Nodelist of the slot content.
slot_name class-attribute
instance-attribute
¤
Name of the slot that originally defined or accepted this slot fill.
SlotContent module-attribute
¤
SlotContent = Union[SlotResult, SlotFunc[TSlotData], Slot[TSlotData]]
SlotFunc ¤
SlotRef ¤
SlotRef(slot: SlotNode, context: Context)
Bases: object
SlotRef allows to treat a slot as a variable. The slot is rendered only once the instance is coerced to string.
This is used to access slots as variables inside the templates. When a SlotRef is rendered in the template with {{ my_lazy_slot }}
, it will output the contents of the slot.
TagFormatterABC ¤
Bases: abc.ABC
Abstract base class for defining custom tag formatters.
Tag formatters define how the component tags are used in the template.
Read more about Tag formatter.
For example, with the default tag formatter (ComponentFormatter
), components are written as:
While with the shorthand tag formatter (ShorthandComponentFormatter
), components are written as:
Example:
Implementation for ShorthandComponentFormatter
:
from djagno_components import TagFormatterABC, TagResult
class ShorthandComponentFormatter(TagFormatterABC):
def start_tag(self, name: str) -> str:
return name
def end_tag(self, name: str) -> str:
return f"end{name}"
def parse(self, tokens: List[str]) -> TagResult:
tokens = [*tokens]
name = tokens.pop(0)
return TagResult(name, tokens)
Methods:
end_tag abstractmethod
¤
parse abstractmethod
¤
Given the tokens (words) passed to a component start tag, this function extracts the component name from the tokens list, and returns TagResult
, which is a tuple of (component_name, remaining_tokens)
.
Parameters:
-
tokens
([List(str]
) –List of tokens passed to the component tag.
Returns:
-
TagResult
(TagResult
) –Parsed component name and remaining tokens.
Example:
Assuming we used a component in a template like this:
This function receives a list of tokens:
component
is the tag name, which we drop."my_comp"
is the component name, but we must remove the extra quotes.- The remaining tokens we pass unmodified, as that's the input to the component.
So in the end, we return:
TagResult ¤
Bases: tuple
The return value from TagFormatter.parse()
.
Read more about Tag formatter.
Attributes:
-
component_name
(str
) – -
tokens
(List[str]
) –
component_name instance-attribute
¤
component_name: str
Component name extracted from the template tag
For example, if we had tag
Then component_name
would be my_comp
.
tokens instance-attribute
¤
Remaining tokens (words) that were passed to the tag, with component name removed
For example, if we had tag
Then tokens
would be ['key=val', 'key2=val2']
.
URLRoute dataclass
¤
URLRoute(
path: str,
handler: Optional[URLRouteHandler] = None,
children: List[URLRoute] = list(),
name: Optional[str] = None,
extra: Dict[str, Any] = dict(),
)
Bases: object
Framework-agnostic route definition.
This is similar to Django's URLPattern
object created with django.urls.path()
.
The URLRoute
must either define a handler
function or have a list of child routes children
. If both are defined, an error will be raised.
Example:
URLRoute("/my/path", handler=my_handler, name="my_name", extra={"kwargs": {"my_extra": "my_value"}})
Is equivalent to:
With children:
URLRoute(
"/my/path",
name="my_name",
extra={"kwargs": {"my_extra": "my_value"}},
children=[
URLRoute(
"/child/<str:name>/",
handler=my_handler,
name="my_name",
extra={"kwargs": {"my_extra": "my_value"}},
),
URLRoute("/other/<int:id>/", handler=other_handler),
],
)
Attributes:
-
children
(List[URLRoute]
) – -
extra
(Dict[str, Any]
) – -
handler
(Optional[URLRouteHandler]
) – -
name
(Optional[str]
) – -
path
(str
) –
children class-attribute
instance-attribute
¤
URLRouteHandler ¤
all_registries ¤
all_registries() -> List[ComponentRegistry]
Get a list of all created ComponentRegistry
instances.
autodiscover ¤
Search for all python files in COMPONENTS.dirs
and COMPONENTS.app_dirs
and import them.
See Autodiscovery.
NOTE: Subdirectories and files starting with an underscore _
(except for __init__.py
are ignored.
Parameters:
-
map_module
(Callable[[str], str]
, default:None
) –Map the module paths with
map_module
function. This serves as an escape hatch for when you need to use this function in tests.
Returns:
To get the same list of modules that autodiscover()
would return, but without importing them, use get_component_files()
:
cached_template ¤
cached_template(
template_string: str,
template_cls: Optional[Type[Template]] = None,
origin: Optional[Origin] = None,
name: Optional[str] = None,
engine: Optional[Any] = None,
) -> Template
Create a Template instance that will be cached as per the COMPONENTS.template_cache_size
setting.
Parameters:
-
template_string
(str
) –Template as a string, same as the first argument to Django's
Template
. Required. -
template_cls
(Type[Template]
, default:None
) –Specify the Template class that should be instantiated. Defaults to Django's
Template
class. -
origin
(Type[Origin]
, default:None
) –Sets
Template.Origin
. -
name
(Type[str]
, default:None
) –Sets
Template.name
-
engine
(Type[Any]
, default:None
) –Sets
Template.engine
from django_components import cached_template
template = cached_template("Variable: {{ variable }}")
# You can optionally specify Template class, and other Template inputs:
class MyTemplate(Template):
pass
template = cached_template(
"Variable: {{ variable }}",
template_cls=MyTemplate,
name=...
origin=...
engine=...
)
format_attributes ¤
Format a dict of attributes into an HTML attributes string.
Read more about HTML attributes.
Example:
will return
get_component_dirs ¤
Get directories that may contain component files.
This is the heart of all features that deal with filesystem and file lookup. Autodiscovery, Django template resolution, static file resolution - They all use this.
Parameters:
-
include_apps
(bool
, default:True
) –Include directories from installed Django apps. Defaults to
True
.
Returns:
get_component_dirs()
searches for dirs set in COMPONENTS.dirs
settings. If none set, defaults to searching for a "components"
app.
In addition to that, also all installed Django apps are checked whether they contain directories as set in COMPONENTS.app_dirs
(e.g. [app]/components
).
Notes:
-
Paths that do not point to directories are ignored.
-
BASE_DIR
setting is required. -
The paths in
COMPONENTS.dirs
must be absolute paths.
get_component_files ¤
get_component_files(suffix: Optional[str] = None) -> List[ComponentFileEntry]
Search for files within the component directories (as defined in get_component_dirs()
).
Requires BASE_DIR
setting to be set.
Subdirectories and files starting with an underscore _
(except __init__.py
) are ignored.
Parameters:
-
suffix
(Optional[str]
, default:None
) –The suffix to search for. E.g.
.py
,.js
,.css
. Defaults toNone
, which will search for all files.
Returns:
-
List[ComponentFileEntry]
–List[ComponentFileEntry] A list of entries that contain both the filesystem path and the python import path (dot path).
Example:
import_libraries ¤
Import modules set in COMPONENTS.libraries
setting.
See Autodiscovery.
Parameters:
-
map_module
(Callable[[str], str]
, default:None
) –Map the module paths with
map_module
function. This serves as an escape hatch for when you need to use this function in tests.
Returns:
Examples:
Normal usage - load libraries after Django has loaded
from django_components import import_libraries
class MyAppConfig(AppConfig):
def ready(self):
import_libraries()
Potential usage in tests
merge_attributes ¤
Merge a list of dictionaries into a single dictionary.
The dictionaries are treated as HTML attributes and are merged accordingly:
- If a same key is present in multiple dictionaries, the values are joined with a space character.
- The
class
andstyle
keys are handled specially, similar to how Vue does it.
Read more about HTML attributes.
Example:
merge_attributes(
{"my-attr": "my-value", "class": "my-class"},
{"my-attr": "extra-value", "data-id": "123"},
)
will result in
The class
attribute
The class
attribute can be given as a string, or a dictionary.
- If given as a string, it is used as is.
- If given as a dictionary, only the keys with a truthy value are used.
Example:
will result in
The style
attribute
The style
attribute can be given as a string, a list, or a dictionary.
- If given as a string, it is used as is.
- If given as a dictionary, it is converted to a style attribute string.
Example:
merge_attributes(
{"style": "color: red; background-color: blue;"},
{"style": {"background-color": "green", "color": False}},
)
will result in
register ¤
register(name: str, registry: Optional[ComponentRegistry] = None) -> Callable[
[Type[Component[ArgsType, KwargsType, SlotsType, DataType, JsDataType, CssDataType]]],
Type[Component[ArgsType, KwargsType, SlotsType, DataType, JsDataType, CssDataType]],
]
Class decorator for registering a component to a component registry.
Parameters:
-
name
(str
) –Registered name. This is the name by which the component will be accessed from within a template when using the
{% component %}
tag. Required. -
registry
(ComponentRegistry
, default:None
) –Specify the registry to which to register this component. If omitted, component is registered to the default registry.
Raises:
-
AlreadyRegistered
–If there is already a component registered under the same name.
Examples:
from django_components import Component, register
@register("my_component")
class MyComponent(Component):
...
Specifing ComponentRegistry
the component should be registered to by setting the registry
kwarg:
registry module-attribute
¤
registry: ComponentRegistry = ComponentRegistry()
The default and global component registry. Use this instance to directly register or remove components:
# Register components
registry.register("button", ButtonComponent)
registry.register("card", CardComponent)
# Get single
registry.get("button")
# Get all
registry.all()
# Check if component is registered
registry.has("button")
# Unregister single
registry.unregister("button")
# Unregister all
registry.clear()
render_dependencies ¤
Given a string that contains parts that were rendered by components, this function inserts all used JS and CSS.
By default, the string is parsed as an HTML and: - CSS is inserted at the end of <head>
(if present) - JS is inserted at the end of <body>
(if present)
If you used {% component_js_dependencies %}
or {% component_css_dependencies %}
, then the JS and CSS will be inserted only at these locations.
Example:
def my_view(request):
template = Template('''
{% load components %}
<!doctype html>
<html>
<head></head>
<body>
<h1>{{ table_name }}</h1>
{% component "table" name=table_name / %}
</body>
</html>
''')
html = template.render(
Context({
"table_name": request.GET["name"],
})
)
# This inserts components' JS and CSS
processed_html = render_dependencies(html)
return HttpResponse(processed_html)
template_tag ¤
template_tag(
library: Library, tag: str, end_tag: Optional[str] = None, allowed_flags: Optional[List[str]] = None
) -> Callable[[Callable], Callable]
A simplified version of creating a template tag based on BaseNode
.
Instead of defining the whole class, you can just define the render()
method.
from django.template import Context, Library
from django_components import BaseNode, template_tag
library = Library()
@template_tag(
library,
tag="mytag",
end_tag="endmytag",
allowed_flags=["required"],
)
def mytag(node: BaseNode, context: Context, name: str, **kwargs: Any) -> str:
return f"Hello, {name}!"
This will allow the template tag {% mytag %}
to be used like this:
The given function will be wrapped in a class that inherits from BaseNode
.
And this class will be registered with the given library.
The function MUST accept at least two positional arguments: node
and context
Any extra parameters defined on this function will be part of the tag's input parameters.
For more info, see BaseNode.render()
.