refactor: fix some links, fix restart loop on file change of mkdocs serve (#1342)

This commit is contained in:
Juro Oravec 2025-08-15 09:26:08 +02:00 committed by GitHub
parent 14eaebff9e
commit a6e840bdca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 251 additions and 220 deletions

View file

@ -54,7 +54,8 @@ python manage.py components ext run <extension> <command>
## `components create` ## `components create`
```txt ```txt
usage: python manage.py components create [-h] [--path PATH] [--js JS] [--css CSS] [--template TEMPLATE] [--force] [--verbose] [--dry-run] name usage: python manage.py components create [-h] [--path PATH] [--js JS] [--css CSS] [--template TEMPLATE] [--force] [--verbose] [--dry-run]
name
``` ```
@ -301,7 +302,7 @@ usage: python manage.py components ext run [-h]
<a href="https://github.com/django-components/django-components/tree/master/src/django_components/commands/ext_run.py#L48" target="_blank">See source code</a> <a href="https://github.com/django-components/django-components/tree/master/src/django_components/commands/ext_run.py#L51" target="_blank">See source code</a>
@ -461,8 +462,8 @@ ProjectDashboardAction project.components.dashboard_action.ProjectDashboardAc
## `upgradecomponent` ## `upgradecomponent`
```txt ```txt
usage: upgradecomponent [-h] [--path PATH] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] usage: upgradecomponent [-h] [--path PATH] [--version] [-v {0,1,2,3}] [--settings SETTINGS]
[--skip-checks] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks]
``` ```
@ -506,8 +507,9 @@ Deprecated. Use `components upgrade` instead.
## `startcomponent` ## `startcomponent`
```txt ```txt
usage: startcomponent [-h] [--path PATH] [--js JS] [--css CSS] [--template TEMPLATE] [--force] [--verbose] [--dry-run] [--version] [-v {0,1,2,3}] usage: startcomponent [-h] [--path PATH] [--js JS] [--css CSS] [--template TEMPLATE] [--force] [--verbose]
[--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks] [--dry-run] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH]
[--traceback] [--no-color] [--force-color] [--skip-checks]
name name
``` ```

View file

@ -20,7 +20,7 @@ Import as
<a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L1010" target="_blank">See source code</a> <a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L1052" target="_blank">See source code</a>
@ -43,7 +43,7 @@ If you insert this tag multiple times, ALL CSS links will be duplicately inserte
<a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L1032" target="_blank">See source code</a> <a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L1074" target="_blank">See source code</a>
@ -67,7 +67,7 @@ If you insert this tag multiple times, ALL JS scripts will be duplicately insert
<a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L3799" target="_blank">See source code</a> <a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L3803" target="_blank">See source code</a>

View file

@ -44,6 +44,7 @@ from pathlib import Path
from textwrap import dedent from textwrap import dedent
from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Tuple, Type, Union from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Tuple, Type, Union
import mkdocs_gen_files
from django.conf import settings from django.conf import settings
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.urls import URLPattern, URLResolver from django.urls import URLPattern, URLResolver
@ -80,11 +81,11 @@ def gen_reference_api():
module = import_module("django_components") module = import_module("django_components")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_api.md").read_text() template_path = "docs/templates/reference_api.md"
out_file = root / "docs/reference/api.md" preface += (root / template_path).read_text()
out_path = "reference/api.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
for name, obj in inspect.getmembers(module): for name, obj in inspect.getmembers(module):
@ -112,6 +113,8 @@ def gen_reference_api():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_testing_api(): def gen_reference_testing_api():
""" """
@ -122,11 +125,11 @@ def gen_reference_testing_api():
module = import_module("django_components.testing") module = import_module("django_components.testing")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_testing_api.md").read_text() template_path = "docs/templates/reference_testing_api.md"
out_file = root / "docs/reference/testing_api.md" preface += (root / template_path).read_text()
out_path = "reference/testing_api.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
for name, obj in inspect.getmembers(module): for name, obj in inspect.getmembers(module):
@ -143,6 +146,8 @@ def gen_reference_testing_api():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_exceptions(): def gen_reference_exceptions():
""" """
@ -151,11 +156,11 @@ def gen_reference_exceptions():
module = import_module("django_components") module = import_module("django_components")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_exceptions.md").read_text() template_path = "docs/templates/reference_exceptions.md"
out_file = root / "docs/reference/exceptions.md" preface += (root / template_path).read_text()
out_path = "reference/exceptions.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
for name, obj in inspect.getmembers(module): for name, obj in inspect.getmembers(module):
@ -177,6 +182,8 @@ def gen_reference_exceptions():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_components(): def gen_reference_components():
""" """
@ -186,11 +193,11 @@ def gen_reference_components():
module = import_module("django_components.components") module = import_module("django_components.components")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_components.md").read_text() template_path = "docs/templates/reference_components.md"
out_file = root / "docs/reference/components.md" preface += (root / template_path).read_text()
out_path = "reference/components.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
for name, obj in inspect.getmembers(module): for name, obj in inspect.getmembers(module):
@ -234,6 +241,8 @@ def gen_reference_components():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_settings(): def gen_reference_settings():
""" """
@ -242,11 +251,11 @@ def gen_reference_settings():
module = import_module("django_components.app_settings") module = import_module("django_components.app_settings")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_settings.md").read_text() template_path = "docs/templates/reference_settings.md"
out_file = root / "docs/reference/settings.md" preface += (root / template_path).read_text()
out_path = "reference/settings.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
# 1. Insert section from `reference_settings.md` # 1. Insert section from `reference_settings.md`
f.write(preface + "\n\n") f.write(preface + "\n\n")
@ -288,6 +297,8 @@ def gen_reference_settings():
) )
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
# Get attributes / methods that are unique to the subclass # Get attributes / methods that are unique to the subclass
def _get_unique_methods(base_class: Type, sub_class: Type): def _get_unique_methods(base_class: Type, sub_class: Type):
@ -347,8 +358,9 @@ def gen_reference_tagformatters():
module = import_module("django_components") module = import_module("django_components")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_tagformatters.md").read_text() template_path = "docs/templates/reference_tagformatters.md"
out_file = root / "docs/reference/tag_formatters.md" preface += (root / template_path).read_text()
out_path = "reference/tag_formatters.md"
tag_formatter_classes: Dict[str, Type[TagFormatterABC]] = {} tag_formatter_classes: Dict[str, Type[TagFormatterABC]] = {}
tag_formatter_instances: Dict[str, TagFormatterABC] = {} tag_formatter_instances: Dict[str, TagFormatterABC] = {}
@ -358,8 +370,7 @@ def gen_reference_tagformatters():
elif _is_tag_formatter_cls(obj): elif _is_tag_formatter_cls(obj):
tag_formatter_classes[name] = obj tag_formatter_classes[name] = obj
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
# Generate a summary of available tag formatters. # Generate a summary of available tag formatters.
@ -402,6 +413,8 @@ def gen_reference_tagformatters():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_urls(): def gen_reference_urls():
""" """
@ -410,13 +423,13 @@ def gen_reference_urls():
module = import_module("django_components.urls") module = import_module("django_components.urls")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_urls.md").read_text() template_path = "docs/templates/reference_urls.md"
out_file = root / "docs/reference/urls.md" preface += (root / template_path).read_text()
out_path = "reference/urls.md"
all_urls = _list_urls(module.urlpatterns) all_urls = _list_urls(module.urlpatterns)
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
# Simply list all URLs, e.g. # Simply list all URLs, e.g.
@ -431,11 +444,11 @@ def gen_reference_commands():
These are discovered by looking at the files defined inside `management/commands`. These are discovered by looking at the files defined inside `management/commands`.
""" """
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_commands.md").read_text() template_path = "docs/templates/reference_commands.md"
out_file = root / "docs/reference/commands.md" preface += (root / template_path).read_text()
out_path = "reference/commands.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
# Document all commands defined by django-components # Document all commands defined by django-components
@ -530,6 +543,8 @@ def gen_reference_commands():
f"{cmd_desc}\n\n" f"{cmd_desc}\n\n"
) )
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_template_tags(): def gen_reference_template_tags():
""" """
@ -544,11 +559,11 @@ def gen_reference_template_tags():
] ]
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_template_tags.md").read_text() template_path = "docs/templates/reference_template_tags.md"
out_file = root / "docs/reference/template_tags.md" preface += (root / template_path).read_text()
out_path = "reference/template_tags.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
for mod_name, mod_path in tags_modules: for mod_name, mod_path in tags_modules:
@ -591,6 +606,8 @@ def gen_reference_template_tags():
f"{docstring}\n\n" f"{docstring}\n\n"
) )
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_template_variables(): def gen_reference_template_variables():
""" """
@ -598,16 +615,18 @@ def gen_reference_template_variables():
under the `{{ component_vars }}` variable, as defined by `ComponentVars`. under the `{{ component_vars }}` variable, as defined by `ComponentVars`.
""" """
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_template_variables.md").read_text() template_path = "docs/templates/reference_template_variables.md"
out_file = root / "docs/reference/template_variables.md" preface += (root / template_path).read_text()
out_path = "reference/template_variables.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
for field in ComponentVars._fields: for field in ComponentVars._fields:
f.write(f"::: {ComponentVars.__module__}.{ComponentVars.__name__}.{field}\n\n") f.write(f"::: {ComponentVars.__module__}.{ComponentVars.__name__}.{field}\n\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_extension_hooks(): def gen_reference_extension_hooks():
""" """
@ -616,11 +635,11 @@ def gen_reference_extension_hooks():
module = import_module("django_components.extension") module = import_module("django_components.extension")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_extension_hooks.md").read_text() template_path = "docs/templates/reference_extension_hooks.md"
out_file = root / "docs/reference/extension_hooks.md" preface += (root / template_path).read_text()
out_path = "reference/extension_hooks.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
# 1. Insert section from `reference_extension_hooks.md` # 1. Insert section from `reference_extension_hooks.md`
f.write(preface + "\n\n") f.write(preface + "\n\n")
@ -700,6 +719,8 @@ def gen_reference_extension_hooks():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_extension_commands(): def gen_reference_extension_commands():
""" """
@ -708,11 +729,11 @@ def gen_reference_extension_commands():
module = import_module("django_components") module = import_module("django_components")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_extension_commands.md").read_text() template_path = "docs/templates/reference_extension_commands.md"
out_file = root / "docs/reference/extension_commands.md" preface += (root / template_path).read_text()
out_path = "reference/extension_commands.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
# 1. Insert section from `reference_extension_commands.md` # 1. Insert section from `reference_extension_commands.md`
f.write(preface + "\n\n") f.write(preface + "\n\n")
@ -737,6 +758,8 @@ def gen_reference_extension_commands():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def gen_reference_extension_urls(): def gen_reference_extension_urls():
""" """
@ -745,11 +768,11 @@ def gen_reference_extension_urls():
module = import_module("django_components") module = import_module("django_components")
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_extension_urls.md").read_text() template_path = "docs/templates/reference_extension_urls.md"
out_file = root / "docs/reference/extension_urls.md" preface += (root / template_path).read_text()
out_path = "reference/extension_urls.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
# 1. Insert section from `reference_extension_urls.md` # 1. Insert section from `reference_extension_urls.md`
f.write(preface + "\n\n") f.write(preface + "\n\n")
@ -774,6 +797,8 @@ def gen_reference_extension_urls():
f.write("\n") f.write("\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
forward_ref_pattern = re.compile(r"ForwardRef\('(.+?)'\)") forward_ref_pattern = re.compile(r"ForwardRef\('(.+?)'\)")
class_repr_pattern = re.compile(r"<class '(.+?)'>") class_repr_pattern = re.compile(r"<class '(.+?)'>")
@ -890,13 +915,15 @@ def gen_reference_signals():
send by or during the use of django-components. send by or during the use of django-components.
""" """
preface = "<!-- Autogenerated by reference.py -->\n\n" preface = "<!-- Autogenerated by reference.py -->\n\n"
preface += (root / "docs/templates/reference_signals.md").read_text() template_path = "docs/templates/reference_signals.md"
out_file = root / "docs/reference/signals.md" preface += (root / template_path).read_text()
out_path = "reference/signals.md"
out_file.parent.mkdir(parents=True, exist_ok=True) with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f:
with out_file.open("w", encoding="utf-8") as f:
f.write(preface + "\n\n") f.write(preface + "\n\n")
mkdocs_gen_files.set_edit_path(out_path, template_path)
def _list_urls(urlpatterns: Sequence[Union[URLPattern, URLResolver]], prefix=""): def _list_urls(urlpatterns: Sequence[Union[URLPattern, URLResolver]], prefix=""):
"""Recursively extract all URLs and their associated views from Django's urlpatterns""" """Recursively extract all URLs and their associated views from Django's urlpatterns"""
@ -1130,4 +1157,5 @@ def gen_reference():
# This is run when `gen-files` plugin is run in mkdocs.yml # This is run when `gen-files` plugin is run in mkdocs.yml
gen_reference() if __name__ == "__main__":
gen_reference()

View file

@ -1,10 +1,11 @@
--- ---
# See https://www.mkdocs.org/user-guide/configuration
site_name: Django-Components site_name: Django-Components
site_description: A way to create simple reusable template components in Django. site_description: A way to create simple reusable template components in Django.
site_url: https://django-components.github.io/django-components/ site_url: https://django-components.github.io/django-components/
repo_url: https://github.com/django-components/django-components repo_url: https://github.com/django-components/django-components
repo_name: django-components/django-components repo_name: django-components
edit_uri: https://github.com/django-components/django-components/edit/master/docs/ edit_uri: https://github.com/django-components/django-components/edit/master/docs/
dev_addr: "127.0.0.1:9000" dev_addr: "127.0.0.1:9000"

View file

@ -40,9 +40,9 @@ ContextBehaviorType = Literal["django", "isolated"]
class ContextBehavior(str, Enum): class ContextBehavior(str, Enum):
""" """
Configure how (and whether) the context is passed to the component fills Configure how (and whether) the context is passed to the component fills
and what variables are available inside the [`{% fill %}`](../template_tags#fill) tags. and what variables are available inside the [`{% fill %}`](./template_tags.md#fill) tags.
Also see [Component context and scope](../../concepts/fundamentals/component_context_scope#context-behavior). Also see [Component context and scope](../concepts/advanced/component_context_scope.md#context-behavior).
**Options:** **Options:**
@ -56,7 +56,7 @@ class ContextBehavior(str, Enum):
That is, they enrich the context, and pass it along. That is, they enrich the context, and pass it along.
1. Component fills use the context of the component they are within. 1. Component fills use the context of the component they are within.
2. Variables from [`Component.get_template_data()`](../api#django_components.Component.get_template_data) 2. Variables from [`Component.get_template_data()`](./api.md#django_components.Component.get_template_data)
are available to the component fill. are available to the component fill.
**Example:** **Example:**
@ -98,7 +98,7 @@ class ContextBehavior(str, Enum):
""" """
This setting makes the component fills behave similar to Vue or React, where This setting makes the component fills behave similar to Vue or React, where
the fills use EXCLUSIVELY the context variables defined in the fills use EXCLUSIVELY the context variables defined in
[`Component.get_template_data()`](../api#django_components.Component.get_template_data). [`Component.get_template_data()`](./api.md#django_components.Component.get_template_data).
**Example:** **Example:**
@ -151,14 +151,14 @@ class ComponentsSettings(NamedTuple):
extensions: Optional[Sequence[Union[Type["ComponentExtension"], str]]] = None extensions: Optional[Sequence[Union[Type["ComponentExtension"], str]]] = None
""" """
List of [extensions](../../concepts/advanced/extensions) to be loaded. List of [extensions](../concepts/advanced/extensions.md) to be loaded.
The extensions can be specified as: The extensions can be specified as:
- Python import path, e.g. `"path.to.my_extension.MyExtension"`. - Python import path, e.g. `"path.to.my_extension.MyExtension"`.
- Extension class, e.g. `my_extension.MyExtension`. - Extension class, e.g. `my_extension.MyExtension`.
Read more about [extensions](../../concepts/advanced/extensions). Read more about [extensions](../concepts/advanced/extensions.md).
**Example:** **Example:**
@ -176,7 +176,7 @@ class ComponentsSettings(NamedTuple):
""" """
Global defaults for the extension classes. Global defaults for the extension classes.
Read more about [Extension defaults](../../concepts/advanced/extensions#extension-defaults). Read more about [Extension defaults](../concepts/advanced/extensions.md#extension-defaults).
**Example:** **Example:**
@ -197,7 +197,7 @@ class ComponentsSettings(NamedTuple):
autodiscover: Optional[bool] = None autodiscover: Optional[bool] = None
""" """
Toggle whether to run [autodiscovery](../../concepts/fundamentals/autodiscovery) at the Django server startup. Toggle whether to run [autodiscovery](../concepts/fundamentals/autodiscovery.md) at the Django server startup.
Defaults to `True` Defaults to `True`
@ -217,8 +217,8 @@ class ComponentsSettings(NamedTuple):
Directories must be full paths, same as with Directories must be full paths, same as with
[STATICFILES_DIRS](https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-STATICFILES_DIRS). [STATICFILES_DIRS](https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-STATICFILES_DIRS).
These locations are searched during [autodiscovery](../../concepts/fundamentals/autodiscovery), These locations are searched during [autodiscovery](../concepts/fundamentals/autodiscovery.md),
or when you [define HTML, JS, or CSS as separate files](../../concepts/fundamentals/html_js_css_files). or when you [define HTML, JS, or CSS as separate files](../concepts/fundamentals/html_js_css_files.md).
```python ```python
COMPONENTS = ComponentsSettings( COMPONENTS = ComponentsSettings(
@ -251,8 +251,8 @@ class ComponentsSettings(NamedTuple):
To search for `<app>/my_comps/`. To search for `<app>/my_comps/`.
These locations are searched during [autodiscovery](../../concepts/fundamentals/autodiscovery), These locations are searched during [autodiscovery](../concepts/fundamentals/autodiscovery.md),
or when you [define HTML, JS, or CSS as separate files](../../concepts/fundamentals/html_js_css_files). or when you [define HTML, JS, or CSS as separate files](../concepts/fundamentals/html_js_css_files.md).
Set to empty list to disable app-level components: Set to empty list to disable app-level components:
@ -273,7 +273,7 @@ class ComponentsSettings(NamedTuple):
Defaults to `None`. Defaults to `None`.
Read more about [caching](../../guides/setup/caching). Read more about [caching](../guides/setup/caching.md).
```python ```python
COMPONENTS = ComponentsSettings( COMPONENTS = ComponentsSettings(
@ -285,12 +285,12 @@ class ComponentsSettings(NamedTuple):
context_behavior: Optional[ContextBehaviorType] = None context_behavior: Optional[ContextBehaviorType] = None
""" """
Configure whether, inside a component template, you can use variables from the outside Configure whether, inside a component template, you can use variables from the outside
([`"django"`](../api#django_components.ContextBehavior.DJANGO)) ([`"django"`](./api.md#django_components.ContextBehavior.DJANGO))
or not ([`"isolated"`](../api#django_components.ContextBehavior.ISOLATED)). or not ([`"isolated"`](./api.md#django_components.ContextBehavior.ISOLATED)).
This also affects what variables are available inside the [`{% fill %}`](../template_tags#fill) This also affects what variables are available inside the [`{% fill %}`](./template_tags.md#fill)
tags. tags.
Also see [Component context and scope](../../concepts/fundamentals/component_context_scope#context-behavior). Also see [Component context and scope](../concepts/advanced/component_context_scope.md#context-behavior).
Defaults to `"django"`. Defaults to `"django"`.
@ -313,11 +313,11 @@ class ComponentsSettings(NamedTuple):
debug_highlight_components: Optional[bool] = None debug_highlight_components: Optional[bool] = None
""" """
DEPRECATED. Use DEPRECATED. Use
[`extensions_defaults`](../settings/#django_components.app_settings.ComponentsSettings.extensions_defaults) [`extensions_defaults`](./settings.md#django_components.app_settings.ComponentsSettings.extensions_defaults)
instead. Will be removed in v1. instead. Will be removed in v1.
Enable / disable component highlighting. Enable / disable component highlighting.
See [Troubleshooting](../../guides/other/troubleshooting#component-highlighting) for more details. See [Troubleshooting](../guides/other/troubleshooting.md#component-and-slot-highlighting) for more details.
Defaults to `False`. Defaults to `False`.
@ -332,11 +332,11 @@ class ComponentsSettings(NamedTuple):
debug_highlight_slots: Optional[bool] = None debug_highlight_slots: Optional[bool] = None
""" """
DEPRECATED. Use DEPRECATED. Use
[`extensions_defaults`](../settings/#django_components.app_settings.ComponentsSettings.extensions_defaults) [`extensions_defaults`](./settings.md#django_components.app_settings.ComponentsSettings.extensions_defaults)
instead. Will be removed in v1. instead. Will be removed in v1.
Enable / disable slot highlighting. Enable / disable slot highlighting.
See [Troubleshooting](../../guides/other/troubleshooting#slot-highlighting) for more details. See [Troubleshooting](../guides/other/troubleshooting.md#component-and-slot-highlighting) for more details.
Defaults to `False`. Defaults to `False`.
@ -349,7 +349,7 @@ class ComponentsSettings(NamedTuple):
dynamic_component_name: Optional[str] = None dynamic_component_name: Optional[str] = None
""" """
By default, the [dynamic component](../components#django_components.components.dynamic.DynamicComponent) By default, the [dynamic component](./components.md#django_components.components.dynamic.DynamicComponent)
is registered under the name `"dynamic"`. is registered under the name `"dynamic"`.
In case of a conflict, you can use this setting to change the component name used for In case of a conflict, you can use this setting to change the component name used for
@ -377,7 +377,7 @@ class ComponentsSettings(NamedTuple):
""" """
Configure extra python modules that should be loaded. Configure extra python modules that should be loaded.
This may be useful if you are not using the [autodiscovery feature](../../concepts/fundamentals/autodiscovery), This may be useful if you are not using the [autodiscovery feature](../concepts/fundamentals/autodiscovery.md),
or you need to load components from non-standard locations. Thus you can have or you need to load components from non-standard locations. Thus you can have
a structure of components that is independent from your apps. a structure of components that is independent from your apps.
@ -409,7 +409,7 @@ class ComponentsSettings(NamedTuple):
# Manually loading libraries # Manually loading libraries
In the rare case that you need to manually trigger the import of libraries, you can use In the rare case that you need to manually trigger the import of libraries, you can use
the [`import_libraries()`](../api/#django_components.import_libraries) function: the [`import_libraries()`](./api.md#django_components.import_libraries) function:
```python ```python
from django_components import import_libraries from django_components import import_libraries
@ -421,7 +421,7 @@ class ComponentsSettings(NamedTuple):
multiline_tags: Optional[bool] = None multiline_tags: Optional[bool] = None
""" """
Enable / disable Enable / disable
[multiline support for template tags](../../concepts/fundamentals/template_tag_syntax#multiline-tags). [multiline support for template tags](../concepts/fundamentals/template_tag_syntax.md#multiline-tags).
If `True`, template tags like `{% component %}` or `{{ my_var }}` can span multiple lines. If `True`, template tags like `{% component %}` or `{{ my_var }}` can span multiple lines.
Defaults to `True`. Defaults to `True`.
@ -439,7 +439,7 @@ class ComponentsSettings(NamedTuple):
# TODO_REMOVE_IN_V1 # TODO_REMOVE_IN_V1
reload_on_template_change: Optional[bool] = None reload_on_template_change: Optional[bool] = None
"""Deprecated. Use """Deprecated. Use
[`COMPONENTS.reload_on_file_change`](../settings/#django_components.app_settings.ComponentsSettings.reload_on_file_change) [`COMPONENTS.reload_on_file_change`](./settings.md#django_components.app_settings.ComponentsSettings.reload_on_file_change)
instead.""" # noqa: E501 instead.""" # noqa: E501
reload_on_file_change: Optional[bool] = None reload_on_file_change: Optional[bool] = None
@ -458,12 +458,12 @@ class ComponentsSettings(NamedTuple):
HTML, JS, or CSS changes. HTML, JS, or CSS changes.
If `True`, django_components configures Django to reload when files inside If `True`, django_components configures Django to reload when files inside
[`COMPONENTS.dirs`](../settings/#django_components.app_settings.ComponentsSettings.dirs) [`COMPONENTS.dirs`](./settings.md#django_components.app_settings.ComponentsSettings.dirs)
or or
[`COMPONENTS.app_dirs`](../settings/#django_components.app_settings.ComponentsSettings.app_dirs) [`COMPONENTS.app_dirs`](./settings.md#django_components.app_settings.ComponentsSettings.app_dirs)
change. change.
See [Reload dev server on component file changes](../../guides/setup/development_server/#reload-dev-server-on-component-file-changes). See [Reload dev server on component file changes](../guides/setup/development_server.md#reload-dev-server-on-component-file-changes).
Defaults to `False`. Defaults to `False`.
@ -475,9 +475,9 @@ class ComponentsSettings(NamedTuple):
static_files_allowed: Optional[List[Union[str, re.Pattern]]] = None static_files_allowed: Optional[List[Union[str, re.Pattern]]] = None
""" """
A list of file extensions (including the leading dot) that define which files within A list of file extensions (including the leading dot) that define which files within
[`COMPONENTS.dirs`](../settings/#django_components.app_settings.ComponentsSettings.dirs) [`COMPONENTS.dirs`](./settings.md#django_components.app_settings.ComponentsSettings.dirs)
or or
[`COMPONENTS.app_dirs`](../settings/#django_components.app_settings.ComponentsSettings.app_dirs) [`COMPONENTS.app_dirs`](./settings.md#django_components.app_settings.ComponentsSettings.app_dirs)
are treated as [static files](https://docs.djangoproject.com/en/5.2/howto/static-files/). are treated as [static files](https://docs.djangoproject.com/en/5.2/howto/static-files/).
If a file is matched against any of the patterns, it's considered a static file. Such files are collected If a file is matched against any of the patterns, it's considered a static file. Such files are collected
@ -508,29 +508,29 @@ class ComponentsSettings(NamedTuple):
!!! warning !!! warning
Exposing your Python files can be a security vulnerability. Exposing your Python files can be a security vulnerability.
See [Security notes](../../overview/security_notes). See [Security notes](../overview/security_notes.md).
""" """
# TODO_REMOVE_IN_V1 # TODO_REMOVE_IN_V1
forbidden_static_files: Optional[List[Union[str, re.Pattern]]] = None forbidden_static_files: Optional[List[Union[str, re.Pattern]]] = None
"""Deprecated. Use """Deprecated. Use
[`COMPONENTS.static_files_forbidden`](../settings/#django_components.app_settings.ComponentsSettings.static_files_forbidden) [`COMPONENTS.static_files_forbidden`](./settings.md#django_components.app_settings.ComponentsSettings.static_files_forbidden)
instead.""" # noqa: E501 instead.""" # noqa: E501
static_files_forbidden: Optional[List[Union[str, re.Pattern]]] = None static_files_forbidden: Optional[List[Union[str, re.Pattern]]] = None
""" """
A list of file extensions (including the leading dot) that define which files within A list of file extensions (including the leading dot) that define which files within
[`COMPONENTS.dirs`](../settings/#django_components.app_settings.ComponentsSettings.dirs) [`COMPONENTS.dirs`](./settings.md#django_components.app_settings.ComponentsSettings.dirs)
or or
[`COMPONENTS.app_dirs`](../settings/#django_components.app_settings.ComponentsSettings.app_dirs) [`COMPONENTS.app_dirs`](./settings.md#django_components.app_settings.ComponentsSettings.app_dirs)
will NEVER be treated as [static files](https://docs.djangoproject.com/en/5.2/howto/static-files/). will NEVER be treated as [static files](https://docs.djangoproject.com/en/5.2/howto/static-files/).
If a file is matched against any of the patterns, it will never be considered a static file, 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 even if the file matches a pattern in
[`static_files_allowed`](../settings/#django_components.app_settings.ComponentsSettings.static_files_allowed). [`static_files_allowed`](./settings.md#django_components.app_settings.ComponentsSettings.static_files_allowed).
Use this setting together with Use this setting together with
[`static_files_allowed`](../settings/#django_components.app_settings.ComponentsSettings.static_files_allowed) [`static_files_allowed`](./settings.md#django_components.app_settings.ComponentsSettings.static_files_allowed)
for a fine control over what file types will be exposed. for a fine control over what file types will be exposed.
You can also pass in compiled regexes ([`re.Pattern`](https://docs.python.org/3/library/re.html#re.Pattern)) You can also pass in compiled regexes ([`re.Pattern`](https://docs.python.org/3/library/re.html#re.Pattern))
@ -551,17 +551,17 @@ class ComponentsSettings(NamedTuple):
!!! warning !!! warning
Exposing your Python files can be a security vulnerability. Exposing your Python files can be a security vulnerability.
See [Security notes](../../overview/security_notes). See [Security notes](../overview/security_notes.md).
""" """
tag_formatter: Optional[Union["TagFormatterABC", str]] = None tag_formatter: Optional[Union["TagFormatterABC", str]] = None
""" """
Configure what syntax is used inside Django templates to render components. Configure what syntax is used inside Django templates to render components.
See the [available tag formatters](../tag_formatters). See the [available tag formatters](./tag_formatters.md).
Defaults to `"django_components.component_formatter"`. Defaults to `"django_components.component_formatter"`.
Learn more about [Customizing component tags with TagFormatter](../../concepts/advanced/tag_formatter). Learn more about [Customizing component tags with TagFormatter](../concepts/advanced/tag_formatters.md).
Can be set either as direct reference: Can be set either as direct reference:
@ -637,7 +637,7 @@ class ComponentsSettings(NamedTuple):
By default the cache holds 128 component templates in memory, which should be enough for most sites. 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 But if you have a lot of components, or if you are overriding
[`Component.get_template()`](../api#django_components.Component.get_template) [`Component.get_template()`](./api.md#django_components.Component.get_template)
to render many dynamic templates, you can increase this number. to render many dynamic templates, you can increase this number.
```python ```python
@ -655,7 +655,7 @@ class ComponentsSettings(NamedTuple):
``` ```
If you want to add templates to the cache yourself, you can use If you want to add templates to the cache yourself, you can use
[`cached_template()`](../api/#django_components.cached_template): [`cached_template()`](./api.md#django_components.cached_template):
```python ```python
from django_components import cached_template from django_components import cached_template

View file

@ -33,9 +33,9 @@ TComponent = TypeVar("TComponent", bound="Component")
class AlreadyRegistered(Exception): class AlreadyRegistered(Exception):
""" """
Raised when you try to register a [Component](../api#django_components#Component), Raised when you try to register a [Component](./api.md#django_components.Component),
but it's already registered with given but it's already registered with given
[ComponentRegistry](../api#django_components.ComponentRegistry). [ComponentRegistry](./api.md#django_components.ComponentRegistry).
""" """
pass pass
@ -43,9 +43,9 @@ class AlreadyRegistered(Exception):
class NotRegistered(Exception): class NotRegistered(Exception):
""" """
Raised when you try to access a [Component](../api#django_components#Component), Raised when you try to access a [Component](./api.md#django_components.Component),
but it's NOT registered with given but it's NOT registered with given
[ComponentRegistry](../api#django_components.ComponentRegistry). [ComponentRegistry](./api.md#django_components.ComponentRegistry).
""" """
pass pass
@ -67,7 +67,7 @@ class ComponentRegistryEntry(NamedTuple):
class RegistrySettings(NamedTuple): class RegistrySettings(NamedTuple):
""" """
Configuration for a [`ComponentRegistry`](../api#django_components.ComponentRegistry). Configuration for a [`ComponentRegistry`](./api.md#django_components.ComponentRegistry).
These settings define how the components registered with this registry will behave when rendered. These settings define how the components registered with this registry will behave when rendered.
@ -86,11 +86,11 @@ class RegistrySettings(NamedTuple):
context_behavior: Optional[ContextBehaviorType] = None context_behavior: Optional[ContextBehaviorType] = None
""" """
Same as the global Same as the global
[`COMPONENTS.context_behavior`](../settings#django_components.app_settings.ComponentsSettings.context_behavior) [`COMPONENTS.context_behavior`](./settings.md#django_components.app_settings.ComponentsSettings.context_behavior)
setting, but for this registry. setting, but for this registry.
If omitted, defaults to the global If omitted, defaults to the global
[`COMPONENTS.context_behavior`](../settings#django_components.app_settings.ComponentsSettings.context_behavior) [`COMPONENTS.context_behavior`](./settings.md#django_components.app_settings.ComponentsSettings.context_behavior)
setting. setting.
""" """
@ -100,22 +100,22 @@ class RegistrySettings(NamedTuple):
_Deprecated. Use `context_behavior` instead. Will be removed in v1._ _Deprecated. Use `context_behavior` instead. Will be removed in v1._
Same as the global Same as the global
[`COMPONENTS.context_behavior`](../settings#django_components.app_settings.ComponentsSettings.context_behavior) [`COMPONENTS.context_behavior`](./settings.md#django_components.app_settings.ComponentsSettings.context_behavior)
setting, but for this registry. setting, but for this registry.
If omitted, defaults to the global If omitted, defaults to the global
[`COMPONENTS.context_behavior`](../settings#django_components.app_settings.ComponentsSettings.context_behavior) [`COMPONENTS.context_behavior`](./settings.md#django_components.app_settings.ComponentsSettings.context_behavior)
setting. setting.
""" """
tag_formatter: Optional[Union["TagFormatterABC", str]] = None tag_formatter: Optional[Union["TagFormatterABC", str]] = None
""" """
Same as the global Same as the global
[`COMPONENTS.tag_formatter`](../settings#django_components.app_settings.ComponentsSettings.tag_formatter) [`COMPONENTS.tag_formatter`](./settings.md#django_components.app_settings.ComponentsSettings.tag_formatter)
setting, but for this registry. setting, but for this registry.
If omitted, defaults to the global If omitted, defaults to the global
[`COMPONENTS.tag_formatter`](../settings#django_components.app_settings.ComponentsSettings.tag_formatter) [`COMPONENTS.tag_formatter`](./settings.md#django_components.app_settings.ComponentsSettings.tag_formatter)
setting. setting.
""" """
@ -125,11 +125,11 @@ class RegistrySettings(NamedTuple):
_Deprecated. Use `tag_formatter` instead. Will be removed in v1._ _Deprecated. Use `tag_formatter` instead. Will be removed in v1._
Same as the global Same as the global
[`COMPONENTS.tag_formatter`](../settings#django_components.app_settings.ComponentsSettings.tag_formatter) [`COMPONENTS.tag_formatter`](./settings.md#django_components.app_settings.ComponentsSettings.tag_formatter)
setting, but for this registry. setting, but for this registry.
If omitted, defaults to the global If omitted, defaults to the global
[`COMPONENTS.tag_formatter`](../settings#django_components.app_settings.ComponentsSettings.tag_formatter) [`COMPONENTS.tag_formatter`](./settings.md#django_components.app_settings.ComponentsSettings.tag_formatter)
setting. setting.
""" """
@ -147,7 +147,7 @@ ALL_REGISTRIES: AllRegistries = []
def all_registries() -> List["ComponentRegistry"]: def all_registries() -> List["ComponentRegistry"]:
""" """
Get a list of all created [`ComponentRegistry`](../api#django_components.ComponentRegistry) instances. Get a list of all created [`ComponentRegistry`](./api.md#django_components.ComponentRegistry) instances.
""" """
registries: List["ComponentRegistry"] = [] registries: List["ComponentRegistry"] = []
for reg_ref in ALL_REGISTRIES: for reg_ref in ALL_REGISTRIES:
@ -159,8 +159,8 @@ def all_registries() -> List["ComponentRegistry"]:
class ComponentRegistry: class ComponentRegistry:
""" """
Manages [components](../api#django_components.Component) and makes them available Manages [components](./api.md#django_components.Component) and makes them available
in the template, by default as [`{% component %}`](../template_tags#component) in the template, by default as [`{% component %}`](./template_tags.md#component)
tags. tags.
```django ```django
@ -175,7 +175,7 @@ class ComponentRegistry:
the [`Library`](https://docs.djangoproject.com/en/5.2/howto/custom-template-tags/#code-layout). the [`Library`](https://docs.djangoproject.com/en/5.2/howto/custom-template-tags/#code-layout).
And the opposite happens when you unregister a component - the tag is removed. And the opposite happens when you unregister a component - the tag is removed.
See [Registering components](../../concepts/advanced/component_registry). See [Registering components](../concepts/advanced/component_registry.md).
Args: Args:
library (Library, optional): Django\ library (Library, optional): Django\
@ -183,14 +183,14 @@ class ComponentRegistry:
associated with this registry. If omitted, the default Library instance from django_components is used. associated with this registry. If omitted, the default Library instance from django_components is used.
settings (Union[RegistrySettings, Callable[[ComponentRegistry], RegistrySettings]], optional): Configure\ settings (Union[RegistrySettings, Callable[[ComponentRegistry], RegistrySettings]], optional): Configure\
how the components registered with this registry will behave when rendered.\ how the components registered with this registry will behave when rendered.\
See [`RegistrySettings`](../api#django_components.RegistrySettings). Can be either\ See [`RegistrySettings`](./api.md#django_components.RegistrySettings). Can be either\
a static value or a callable that returns the settings. If omitted, the settings from\ a static value or a callable that returns the settings. If omitted, the settings from\
[`COMPONENTS`](../settings#django_components.app_settings.ComponentsSettings) are used. [`COMPONENTS`](./settings.md#django_components.app_settings.ComponentsSettings) are used.
**Notes:** **Notes:**
- The default registry is available as [`django_components.registry`](../api#django_components.registry). - The default registry is available as [`django_components.registry`](./api.md#django_components.registry).
- The default registry is used when registering components with [`@register`](../api#django_components.register) - The default registry is used when registering components with [`@register`](./api.md#django_components.register)
decorator. decorator.
**Example:** **Example:**
@ -302,7 +302,7 @@ class ComponentRegistry:
@property @property
def settings(self) -> InternalRegistrySettings: def settings(self) -> InternalRegistrySettings:
""" """
[Registry settings](../api#django_components.RegistrySettings) configured for this registry. [Registry settings](./api.md#django_components.RegistrySettings) configured for this registry.
""" """
# NOTE: We allow the settings to be given as a getter function # NOTE: We allow the settings to be given as a getter function
# so the settings can respond to changes. # so the settings can respond to changes.
@ -325,7 +325,7 @@ class ComponentRegistry:
def register(self, name: str, component: Type["Component"]) -> None: def register(self, name: str, component: Type["Component"]) -> None:
""" """
Register a [`Component`](../api#django_components.Component) class Register a [`Component`](./api.md#django_components.Component) class
with this registry under the given name. with this registry under the given name.
A component MUST be registered before it can be used in a template such as: A component MUST be registered before it can be used in a template such as:
@ -340,7 +340,7 @@ class ComponentRegistry:
**Raises:** **Raises:**
- [`AlreadyRegistered`](../exceptions#django_components.AlreadyRegistered) - [`AlreadyRegistered`](./exceptions.md#django_components.AlreadyRegistered)
if a different component was already registered under the same name. if a different component was already registered under the same name.
**Example:** **Example:**
@ -377,7 +377,7 @@ class ComponentRegistry:
def unregister(self, name: str) -> None: def unregister(self, name: str) -> None:
""" """
Unregister the [`Component`](../api#django_components.Component) class Unregister the [`Component`](./api.md#django_components.Component) class
that was registered under the given name. that was registered under the given name.
Once a component is unregistered, it is no longer available in the templates. Once a component is unregistered, it is no longer available in the templates.
@ -387,7 +387,7 @@ class ComponentRegistry:
**Raises:** **Raises:**
- [`NotRegistered`](../exceptions#django_components.NotRegistered) - [`NotRegistered`](./exceptions.md#django_components.NotRegistered)
if the given name is not registered. if the given name is not registered.
**Example:** **Example:**
@ -438,7 +438,7 @@ class ComponentRegistry:
def get(self, name: str) -> Type["Component"]: def get(self, name: str) -> Type["Component"]:
""" """
Retrieve a [`Component`](../api#django_components.Component) Retrieve a [`Component`](./api.md#django_components.Component)
class registered under the given name. class registered under the given name.
Args: Args:
@ -449,7 +449,7 @@ class ComponentRegistry:
**Raises:** **Raises:**
- [`NotRegistered`](../exceptions#django_components.NotRegistered) - [`NotRegistered`](./exceptions.md#django_components.NotRegistered)
if the given name is not registered. if the given name is not registered.
**Example:** **Example:**
@ -469,7 +469,7 @@ class ComponentRegistry:
def has(self, name: str) -> bool: def has(self, name: str) -> bool:
""" """
Check if a [`Component`](../api#django_components.Component) Check if a [`Component`](./api.md#django_components.Component)
class is registered under the given name. class is registered under the given name.
Args: Args:
@ -492,7 +492,7 @@ class ComponentRegistry:
def all(self) -> Dict[str, Type["Component"]]: def all(self) -> Dict[str, Type["Component"]]:
""" """
Retrieve all registered [`Component`](../api#django_components.Component) classes. Retrieve all registered [`Component`](./api.md#django_components.Component) classes.
Returns: Returns:
Dict[str, Type[Component]]: A dictionary of component names to component classes Dict[str, Type[Component]]: A dictionary of component names to component classes
@ -582,10 +582,10 @@ class ComponentRegistry:
# This variable represents the global component registry # This variable represents the global component registry
registry: ComponentRegistry = ComponentRegistry() registry: ComponentRegistry = ComponentRegistry()
""" """
The default and global [component registry](./#django_components.ComponentRegistry). The default and global [component registry](./api.md#django_components.ComponentRegistry).
Use this instance to directly register or remove components: Use this instance to directly register or remove components:
See [Registering components](../../concepts/advanced/component_registry). See [Registering components](../concepts/advanced/component_registry.md).
```python ```python
# Register components # Register components
@ -621,11 +621,11 @@ def register(name: str, registry: Optional[ComponentRegistry] = None) -> Callabl
Class decorator for registering a [component](./#django_components.Component) Class decorator for registering a [component](./#django_components.Component)
to a [component registry](./#django_components.ComponentRegistry). to a [component registry](./#django_components.ComponentRegistry).
See [Registering components](../../concepts/advanced/component_registry). See [Registering components](../concepts/advanced/component_registry.md).
Args: Args:
name (str): Registered name. This is the name by which the component will be accessed\ name (str): Registered name. This is the name by which the component will be accessed\
from within a template when using the [`{% component %}`](../template_tags#component) tag. Required. from within a template when using the [`{% component %}`](./template_tags.md#component) tag. Required.
registry (ComponentRegistry, optional): Specify the [registry](./#django_components.ComponentRegistry)\ registry (ComponentRegistry, optional): Specify the [registry](./#django_components.ComponentRegistry)\
to which to register this component. If omitted, component is registered to the default registry. to which to register this component. If omitted, component is registered to the default registry.

View file

@ -16,8 +16,8 @@ class DynamicComponent(Component):
Args: Args:
is (str | Type[Component]): Component that should be rendered. Either a registered name of a component, is (str | Type[Component]): Component that should be rendered. Either a registered name of a component,
or a [Component](../api#django_components.Component) class directly. Required. or a [Component](./api.md#django_components.Component) class directly. Required.
registry (ComponentRegistry, optional): Specify the [registry](../api#django_components.ComponentRegistry)\ registry (ComponentRegistry, optional): Specify the [registry](./api.md#django_components.ComponentRegistry)\
to search for the registered name. If omitted, all registries are searched until the first match. to search for the registered name. If omitted, all registries are searched until the first match.
*args: Additional data passed to the component. *args: Additional data passed to the component.
**kwargs: Additional data passed to the component. **kwargs: Additional data passed to the component.
@ -77,7 +77,7 @@ class DynamicComponent(Component):
By default, the dynamic component is registered under the name `"dynamic"`. In case of a conflict, By default, the dynamic component is registered under the name `"dynamic"`. In case of a conflict,
you can set the you can set the
[`COMPONENTS.dynamic_component_name`](../settings#django_components.app_settings.ComponentsSettings.dynamic_component_name) [`COMPONENTS.dynamic_component_name`](./settings.md#django_components.app_settings.ComponentsSettings.dynamic_component_name)
setting to change the name used for the dynamic components. setting to change the name used for the dynamic components.
```py ```py

View file

@ -214,8 +214,8 @@ class ExtensionComponentConfig:
`ExtensionComponentConfig` is the base class for all extension component configs. `ExtensionComponentConfig` is the base class for all extension component configs.
Extensions can define nested classes on the component class, Extensions can define nested classes on the component class,
such as [`Component.View`](../api#django_components.Component.View) or such as [`Component.View`](./api.md#django_components.Component.View) or
[`Component.Cache`](../api#django_components.Component.Cache): [`Component.Cache`](./api.md#django_components.Component.Cache):
```py ```py
class MyComp(Component): class MyComp(Component):
@ -249,19 +249,19 @@ class ExtensionComponentConfig:
""" """
component_cls: Type["Component"] component_cls: Type["Component"]
"""The [`Component`](../api#django_components.Component) class that this extension is defined on.""" """The [`Component`](./api.md#django_components.Component) class that this extension is defined on."""
# TODO_v1 - Remove, superseded by `component_cls` # TODO_v1 - Remove, superseded by `component_cls`
component_class: Type["Component"] component_class: Type["Component"]
"""The [`Component`](../api#django_components.Component) class that this extension is defined on.""" """The [`Component`](./api.md#django_components.Component) class that this extension is defined on."""
component: "Component" component: "Component"
""" """
When a [`Component`](../api#django_components.Component) is instantiated, When a [`Component`](./api.md#django_components.Component) is instantiated,
also the nested extension classes (such as `Component.View`) are instantiated, also the nested extension classes (such as `Component.View`) are instantiated,
receiving the component instance as an argument. receiving the component instance as an argument.
This attribute holds the owner [`Component`](../api#django_components.Component) instance This attribute holds the owner [`Component`](./api.md#django_components.Component) instance
that this extension is defined on. that this extension is defined on.
""" """
@ -273,7 +273,7 @@ class ExtensionComponentConfig:
BaseExtensionClass = ExtensionComponentConfig BaseExtensionClass = ExtensionComponentConfig
""" """
Deprecated. Will be removed in v1.0. Use Deprecated. Will be removed in v1.0. Use
[`ComponentConfig`](../api#django_components.ExtensionComponentConfig) instead. [`ComponentConfig`](./api.md#django_components.ExtensionComponentConfig) instead.
""" """
@ -293,7 +293,7 @@ class ComponentExtension(metaclass=ExtensionMeta):
""" """
Base class for all extensions. Base class for all extensions.
Read more on [Extensions](../../concepts/advanced/extensions). Read more on [Extensions](../concepts/advanced/extensions.md).
**Example:** **Example:**
@ -351,16 +351,16 @@ class ComponentExtension(metaclass=ExtensionMeta):
Name must be lowercase, and must be a valid Python identifier (e.g. `"my_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`](../api#django_components.Component) The extension may add new features to the [`Component`](./api.md#django_components.Component)
class by allowing users to define and access a nested class in class by allowing users to define and access a nested class in
the [`Component`](../api#django_components.Component) class. the [`Component`](./api.md#django_components.Component) class.
The extension name determines the name of the nested class in The extension name determines the name of the nested class in
the [`Component`](../api#django_components.Component) class, and the attribute the [`Component`](./api.md#django_components.Component) class, and the attribute
under which the extension will be accessible. under which the extension will be accessible.
E.g. if the extension name is `"my_extension"`, then the nested class in E.g. if the extension name is `"my_extension"`, then the nested class in
the [`Component`](../api#django_components.Component) class will be the [`Component`](./api.md#django_components.Component) class will be
`MyExtension`, and the extension will be accessible as `MyComp.my_extension`. `MyExtension`, and the extension will be accessible as `MyComp.my_extension`.
```python ```python
@ -377,7 +377,7 @@ class ComponentExtension(metaclass=ExtensionMeta):
!!! info !!! info
The extension class name can be customized by setting The extension class name can be customized by setting
the [`class_name`](../api#django_components.ComponentExtension.class_name) attribute. the [`class_name`](./api.md#django_components.ComponentExtension.class_name) attribute.
""" """
class_name: ClassVar[str] class_name: ClassVar[str]
@ -385,7 +385,7 @@ class ComponentExtension(metaclass=ExtensionMeta):
Name of the extension class. Name of the extension class.
By default, this is set automatically at class creation. The class name is the same as By default, this is set automatically at class creation. The class name is the same as
the [`name`](../api#django_components.ComponentExtension.name) attribute, but with snake_case the [`name`](./api.md#django_components.ComponentExtension.name) attribute, but with snake_case
converted to PascalCase. converted to PascalCase.
So if the extension name is `"my_extension"`, then the extension class name will be `"MyExtension"`. So if the extension name is `"my_extension"`, then the extension class name will be `"MyExtension"`.
@ -420,16 +420,16 @@ class ComponentExtension(metaclass=ExtensionMeta):
ComponentConfig: ClassVar[Type[ExtensionComponentConfig]] = ExtensionComponentConfig ComponentConfig: ClassVar[Type[ExtensionComponentConfig]] = ExtensionComponentConfig
""" """
Base class that the "component-level" extension config nested within Base class that the "component-level" extension config nested within
a [`Component`](../api#django_components.Component) class will inherit from. a [`Component`](./api.md#django_components.Component) class will inherit from.
This is where you can define new methods and attributes that will be available to the component This is where you can define new methods and attributes that will be available to the component
instance. instance.
Background: Background:
The extension may add new features to the [`Component`](../api#django_components.Component) class The extension may add new features to the [`Component`](./api.md#django_components.Component) class
by allowing users to define and access a nested class in by allowing users to define and access a nested class in
the [`Component`](../api#django_components.Component) class. E.g.: the [`Component`](./api.md#django_components.Component) class. E.g.:
```python ```python
class MyComp(Component): class MyComp(Component):
@ -462,7 +462,7 @@ class ComponentExtension(metaclass=ExtensionMeta):
These commands will be available to the user as `components ext run <extension> <command>`. These commands will be available to the user as `components ext run <extension> <command>`.
Commands are defined as subclasses of Commands are defined as subclasses of
[`ComponentCommand`](../extension_commands#django_components.ComponentCommand). [`ComponentCommand`](./extension_commands.md#django_components.ComponentCommand).
**Example:** **Example:**
@ -536,13 +536,13 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_component_class_created(self, ctx: OnComponentClassCreatedContext) -> None: def on_component_class_created(self, ctx: OnComponentClassCreatedContext) -> None:
""" """
Called when a new [`Component`](../api#django_components.Component) class is created. Called when a new [`Component`](./api.md#django_components.Component) class is created.
This hook is called after the [`Component`](../api#django_components.Component) class This hook is called after the [`Component`](./api.md#django_components.Component) class
is fully defined but before it's registered. is fully defined but before it's registered.
Use this hook to perform any initialization or validation of the Use this hook to perform any initialization or validation of the
[`Component`](../api#django_components.Component) class. [`Component`](./api.md#django_components.Component) class.
**Example:** **Example:**
@ -559,12 +559,12 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_component_class_deleted(self, ctx: OnComponentClassDeletedContext) -> None: def on_component_class_deleted(self, ctx: OnComponentClassDeletedContext) -> None:
""" """
Called when a [`Component`](../api#django_components.Component) class is being deleted. Called when a [`Component`](./api.md#django_components.Component) class is being deleted.
This hook is called before the [`Component`](../api#django_components.Component) class This hook is called before the [`Component`](./api.md#django_components.Component) class
is deleted from memory. is deleted from memory.
Use this hook to perform any cleanup related to the [`Component`](../api#django_components.Component) class. Use this hook to perform any cleanup related to the [`Component`](./api.md#django_components.Component) class.
**Example:** **Example:**
@ -581,10 +581,10 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_registry_created(self, ctx: OnRegistryCreatedContext) -> None: def on_registry_created(self, ctx: OnRegistryCreatedContext) -> None:
""" """
Called when a new [`ComponentRegistry`](../api#django_components.ComponentRegistry) is created. Called when a new [`ComponentRegistry`](./api.md#django_components.ComponentRegistry) is created.
This hook is called after a new This hook is called after a new
[`ComponentRegistry`](../api#django_components.ComponentRegistry) instance is initialized. [`ComponentRegistry`](./api.md#django_components.ComponentRegistry) instance is initialized.
Use this hook to perform any initialization needed for the registry. Use this hook to perform any initialization needed for the registry.
@ -603,10 +603,10 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_registry_deleted(self, ctx: OnRegistryDeletedContext) -> None: def on_registry_deleted(self, ctx: OnRegistryDeletedContext) -> None:
""" """
Called when a [`ComponentRegistry`](../api#django_components.ComponentRegistry) is being deleted. Called when a [`ComponentRegistry`](./api.md#django_components.ComponentRegistry) is being deleted.
This hook is called before This hook is called before
a [`ComponentRegistry`](../api#django_components.ComponentRegistry) instance is deleted. a [`ComponentRegistry`](./api.md#django_components.ComponentRegistry) instance is deleted.
Use this hook to perform any cleanup related to the registry. Use this hook to perform any cleanup related to the registry.
@ -625,10 +625,10 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_component_registered(self, ctx: OnComponentRegisteredContext) -> None: def on_component_registered(self, ctx: OnComponentRegisteredContext) -> None:
""" """
Called when a [`Component`](../api#django_components.Component) class is Called when a [`Component`](./api.md#django_components.Component) class is
registered with a [`ComponentRegistry`](../api#django_components.ComponentRegistry). registered with a [`ComponentRegistry`](./api.md#django_components.ComponentRegistry).
This hook is called after a [`Component`](../api#django_components.Component) class This hook is called after a [`Component`](./api.md#django_components.Component) class
is successfully registered. is successfully registered.
**Example:** **Example:**
@ -645,10 +645,10 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_component_unregistered(self, ctx: OnComponentUnregisteredContext) -> None: def on_component_unregistered(self, ctx: OnComponentUnregisteredContext) -> None:
""" """
Called when a [`Component`](../api#django_components.Component) class is Called when a [`Component`](./api.md#django_components.Component) class is
unregistered from a [`ComponentRegistry`](../api#django_components.ComponentRegistry). unregistered from a [`ComponentRegistry`](./api.md#django_components.ComponentRegistry).
This hook is called after a [`Component`](../api#django_components.Component) class This hook is called after a [`Component`](./api.md#django_components.Component) class
is removed from the registry. is removed from the registry.
**Example:** **Example:**
@ -669,17 +669,17 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_component_input(self, ctx: OnComponentInputContext) -> Optional[str]: def on_component_input(self, ctx: OnComponentInputContext) -> Optional[str]:
""" """
Called when a [`Component`](../api#django_components.Component) was triggered to render, Called when a [`Component`](./api.md#django_components.Component) was triggered to render,
but before a component's context and data methods are invoked. but before a component's context and data methods are invoked.
Use this hook to modify or validate component inputs before they're processed. Use this hook to modify or validate component inputs before they're processed.
This is the first hook that is called when rendering a component. As such this hook is called before This is the first hook that is called when rendering a component. As such this hook is called before
[`Component.get_template_data()`](../api#django_components.Component.get_template_data), [`Component.get_template_data()`](./api.md#django_components.Component.get_template_data),
[`Component.get_js_data()`](../api#django_components.Component.get_js_data), [`Component.get_js_data()`](./api.md#django_components.Component.get_js_data),
and [`Component.get_css_data()`](../api#django_components.Component.get_css_data) methods, and [`Component.get_css_data()`](./api.md#django_components.Component.get_css_data) methods,
and the and the
[`on_component_data`](../extension_hooks#django_components.extension.ComponentExtension.on_component_data) [`on_component_data`](./extension_hooks.md#django_components.extension.ComponentExtension.on_component_data)
hook. hook.
This hook also allows to skip the rendering of a component altogether. If the hook returns This hook also allows to skip the rendering of a component altogether. If the hook returns
@ -703,28 +703,28 @@ class ComponentExtension(metaclass=ExtensionMeta):
In this hook, the components' inputs are still mutable. In this hook, the components' inputs are still mutable.
As such, if a component defines [`Args`](../api#django_components.Component.Args), As such, if a component defines [`Args`](./api.md#django_components.Component.Args),
[`Kwargs`](../api#django_components.Component.Kwargs), [`Kwargs`](./api.md#django_components.Component.Kwargs),
[`Slots`](../api#django_components.Component.Slots) types, these types are NOT yet instantiated. [`Slots`](./api.md#django_components.Component.Slots) types, these types are NOT yet instantiated.
Instead, component fields like [`Component.args`](../api#django_components.Component.args), Instead, component fields like [`Component.args`](./api.md#django_components.Component.args),
[`Component.kwargs`](../api#django_components.Component.kwargs), [`Component.kwargs`](./api.md#django_components.Component.kwargs),
[`Component.slots`](../api#django_components.Component.slots) [`Component.slots`](./api.md#django_components.Component.slots)
are plain `list` / `dict` objects. are plain `list` / `dict` objects.
""" """
pass pass
def on_component_data(self, ctx: OnComponentDataContext) -> None: def on_component_data(self, ctx: OnComponentDataContext) -> None:
""" """
Called when a [`Component`](../api#django_components.Component) was triggered to render, Called when a [`Component`](./api.md#django_components.Component) was triggered to render,
after a component's context and data methods have been processed. after a component's context and data methods have been processed.
This hook is called after This hook is called after
[`Component.get_template_data()`](../api#django_components.Component.get_template_data), [`Component.get_template_data()`](./api.md#django_components.Component.get_template_data),
[`Component.get_js_data()`](../api#django_components.Component.get_js_data) [`Component.get_js_data()`](./api.md#django_components.Component.get_js_data)
and [`Component.get_css_data()`](../api#django_components.Component.get_css_data). and [`Component.get_css_data()`](./api.md#django_components.Component.get_css_data).
This hook runs after [`on_component_input`](../api#django_components.ComponentExtension.on_component_input). This hook runs after [`on_component_input`](./api.md#django_components.ComponentExtension.on_component_input).
Use this hook to modify or validate the component's data before rendering. Use this hook to modify or validate the component's data before rendering.
@ -743,13 +743,13 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_component_rendered(self, ctx: OnComponentRenderedContext) -> Optional[str]: def on_component_rendered(self, ctx: OnComponentRenderedContext) -> Optional[str]:
""" """
Called when a [`Component`](../api#django_components.Component) was rendered, including Called when a [`Component`](./api.md#django_components.Component) was rendered, including
all its child components. all its child components.
Use this hook to access or post-process the component's rendered output. Use this hook to access or post-process the component's rendered output.
This hook works similarly to This hook works similarly to
[`Component.on_render_after()`](../api#django_components.Component.on_render_after): [`Component.on_render_after()`](./api.md#django_components.Component.on_render_after):
1. To modify the output, return a new string from this hook. The original output or error will be ignored. 1. To modify the output, return a new string from this hook. The original output or error will be ignored.
@ -807,9 +807,9 @@ class ComponentExtension(metaclass=ExtensionMeta):
""" """
Called when a Component's template is loaded as a string. Called when a Component's template is loaded as a string.
This hook runs only once per [`Component`](../api#django_components.Component) class and works for both This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both
[`Component.template`](../api#django_components.Component.template) and [`Component.template`](./api.md#django_components.Component.template) and
[`Component.template_file`](../api#django_components.Component.template_file). [`Component.template_file`](./api.md#django_components.Component.template_file).
Use this hook to read or modify the template before it's compiled. Use this hook to read or modify the template before it's compiled.
@ -833,9 +833,9 @@ class ComponentExtension(metaclass=ExtensionMeta):
Called when a Component's template is compiled Called when a Component's template is compiled
into a [`Template`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.Template) object. into a [`Template`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.Template) object.
This hook runs only once per [`Component`](../api#django_components.Component) class and works for both This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both
[`Component.template`](../api#django_components.Component.template) and [`Component.template`](./api.md#django_components.Component.template) and
[`Component.template_file`](../api#django_components.Component.template_file). [`Component.template_file`](./api.md#django_components.Component.template_file).
Use this hook to read or modify the template (in-place) after it's compiled. Use this hook to read or modify the template (in-place) after it's compiled.
@ -855,9 +855,9 @@ class ComponentExtension(metaclass=ExtensionMeta):
""" """
Called when a Component's CSS is loaded as a string. Called when a Component's CSS is loaded as a string.
This hook runs only once per [`Component`](../api#django_components.Component) class and works for both This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both
[`Component.css`](../api#django_components.Component.css) and [`Component.css`](./api.md#django_components.Component.css) and
[`Component.css_file`](../api#django_components.Component.css_file). [`Component.css_file`](./api.md#django_components.Component.css_file).
Use this hook to read or modify the CSS. Use this hook to read or modify the CSS.
@ -880,9 +880,9 @@ class ComponentExtension(metaclass=ExtensionMeta):
""" """
Called when a Component's JS is loaded as a string. Called when a Component's JS is loaded as a string.
This hook runs only once per [`Component`](../api#django_components.Component) class and works for both This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both
[`Component.js`](../api#django_components.Component.js) and [`Component.js`](./api.md#django_components.Component.js) and
[`Component.js_file`](../api#django_components.Component.js_file). [`Component.js_file`](./api.md#django_components.Component.js_file).
Use this hook to read or modify the JS. Use this hook to read or modify the JS.
@ -907,7 +907,7 @@ class ComponentExtension(metaclass=ExtensionMeta):
def on_slot_rendered(self, ctx: OnSlotRenderedContext) -> Optional[str]: def on_slot_rendered(self, ctx: OnSlotRenderedContext) -> Optional[str]:
""" """
Called when a [`{% slot %}`](../template_tags#slot) tag was rendered. Called when a [`{% slot %}`](./template_tags.md#slot) tag was rendered.
Use this hook to access or post-process the slot's rendered output. Use this hook to access or post-process the slot's rendered output.
@ -926,12 +926,12 @@ class ComponentExtension(metaclass=ExtensionMeta):
**Access slot metadata:** **Access slot metadata:**
You can access the [`{% slot %}` tag](../template_tags#slot) You can access the [`{% slot %}` tag](./template_tags.md#slot)
node ([`SlotNode`](../api#django_components.SlotNode)) and its metadata using `ctx.slot_node`. node ([`SlotNode`](./api.md#django_components.SlotNode)) and its metadata using `ctx.slot_node`.
For example, to find the [`Component`](../api#django_components.Component) class to which For example, to find the [`Component`](./api.md#django_components.Component) class to which
belongs the template where the [`{% slot %}`](../template_tags#slot) tag is defined, you can use belongs the template where the [`{% slot %}`](./template_tags.md#slot) tag is defined, you can use
[`ctx.slot_node.template_component`](../api#django_components.SlotNode.template_component): [`ctx.slot_node.template_component`](./api.md#django_components.SlotNode.template_component):
```python ```python
from django_components import ComponentExtension, OnSlotRenderedContext from django_components import ComponentExtension, OnSlotRenderedContext

View file

@ -8,9 +8,9 @@ from django.template.library import Library
class TagProtectedError(Exception): class TagProtectedError(Exception):
""" """
The way the [`TagFormatter`](../../concepts/advanced/tag_formatter) works is that, The way the [`TagFormatter`](./../concepts/advanced/tag_formatters.md) works is that,
based on which start and end tags are used for rendering components, based on which start and end tags are used for rendering components,
the [`ComponentRegistry`](../api#django_components.ComponentRegistry) behind the scenes the [`ComponentRegistry`](./api.md#django_components.ComponentRegistry) behind the scenes
[un-/registers the template tags](https://docs.djangoproject.com/en/5.2/howto/custom-template-tags/#registering-the-tag) [un-/registers the template tags](https://docs.djangoproject.com/en/5.2/howto/custom-template-tags/#registering-the-tag)
with the associated instance of Django's with the associated instance of Django's
[`Library`](https://docs.djangoproject.com/en/5.2/howto/custom-template-tags/#code-layout). [`Library`](https://docs.djangoproject.com/en/5.2/howto/custom-template-tags/#code-layout).
@ -23,11 +23,11 @@ class TagProtectedError(Exception):
{% endtable %} {% endtable %}
``` ```
Then [`ComponentRegistry`](../api#django_components.ComponentRegistry) Then [`ComponentRegistry`](./api.md#django_components.ComponentRegistry)
registers the tag `table` onto the Django's Library instance. registers the tag `table` onto the Django's Library instance.
However, that means that if we registered a component `"slot"`, then we would overwrite However, that means that if we registered a component `"slot"`, then we would overwrite
the [`{% slot %}`](../template_tags#slot) tag from django_components. the [`{% slot %}`](./template_tags.md#slot) tag from django_components.
Thus, this exception is raised when a component is attempted to be registered under Thus, this exception is raised when a component is attempted to be registered under
a forbidden name, such that it would overwrite one of django_component's own template tags. a forbidden name, such that it would overwrite one of django_component's own template tags.