diff --git a/docs/reference/commands.md b/docs/reference/commands.md index aacbca67..cee43b33 100644 --- a/docs/reference/commands.md +++ b/docs/reference/commands.md @@ -54,7 +54,8 @@ python manage.py components ext run ## `components create` ```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] -See source code +See source code @@ -461,8 +462,8 @@ ProjectDashboardAction project.components.dashboard_action.ProjectDashboardAc ## `upgradecomponent` ```txt -usage: upgradecomponent [-h] [--path PATH] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] - [--skip-checks] +usage: upgradecomponent [-h] [--path PATH] [--version] [-v {0,1,2,3}] [--settings SETTINGS] + [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks] ``` @@ -506,8 +507,9 @@ Deprecated. Use `components upgrade` instead. ## `startcomponent` ```txt -usage: startcomponent [-h] [--path PATH] [--js JS] [--css CSS] [--template TEMPLATE] [--force] [--verbose] [--dry-run] [--version] [-v {0,1,2,3}] - [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks] +usage: startcomponent [-h] [--path PATH] [--js JS] [--css CSS] [--template TEMPLATE] [--force] [--verbose] + [--dry-run] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] + [--traceback] [--no-color] [--force-color] [--skip-checks] name ``` diff --git a/docs/reference/template_tags.md b/docs/reference/template_tags.md index d5c9145f..7119e936 100644 --- a/docs/reference/template_tags.md +++ b/docs/reference/template_tags.md @@ -20,7 +20,7 @@ Import as -See source code +See source code @@ -43,7 +43,7 @@ If you insert this tag multiple times, ALL CSS links will be duplicately inserte -See source code +See source code @@ -67,7 +67,7 @@ If you insert this tag multiple times, ALL JS scripts will be duplicately insert -See source code +See source code diff --git a/docs/scripts/reference.py b/docs/scripts/reference.py index 28963a22..a092a16e 100644 --- a/docs/scripts/reference.py +++ b/docs/scripts/reference.py @@ -44,6 +44,7 @@ from pathlib import Path from textwrap import dedent from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Tuple, Type, Union +import mkdocs_gen_files from django.conf import settings from django.core.management.base import BaseCommand from django.urls import URLPattern, URLResolver @@ -80,11 +81,11 @@ def gen_reference_api(): module = import_module("django_components") preface = "\n\n" - preface += (root / "docs/templates/reference_api.md").read_text() - out_file = root / "docs/reference/api.md" + template_path = "docs/templates/reference_api.md" + preface += (root / template_path).read_text() + out_path = "reference/api.md" - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") for name, obj in inspect.getmembers(module): @@ -112,6 +113,8 @@ def gen_reference_api(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_testing_api(): """ @@ -122,11 +125,11 @@ def gen_reference_testing_api(): module = import_module("django_components.testing") preface = "\n\n" - preface += (root / "docs/templates/reference_testing_api.md").read_text() - out_file = root / "docs/reference/testing_api.md" + template_path = "docs/templates/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 out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") for name, obj in inspect.getmembers(module): @@ -143,6 +146,8 @@ def gen_reference_testing_api(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_exceptions(): """ @@ -151,11 +156,11 @@ def gen_reference_exceptions(): module = import_module("django_components") preface = "\n\n" - preface += (root / "docs/templates/reference_exceptions.md").read_text() - out_file = root / "docs/reference/exceptions.md" + template_path = "docs/templates/reference_exceptions.md" + preface += (root / template_path).read_text() + out_path = "reference/exceptions.md" - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") for name, obj in inspect.getmembers(module): @@ -177,6 +182,8 @@ def gen_reference_exceptions(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_components(): """ @@ -186,11 +193,11 @@ def gen_reference_components(): module = import_module("django_components.components") preface = "\n\n" - preface += (root / "docs/templates/reference_components.md").read_text() - out_file = root / "docs/reference/components.md" + template_path = "docs/templates/reference_components.md" + preface += (root / template_path).read_text() + out_path = "reference/components.md" - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") for name, obj in inspect.getmembers(module): @@ -234,6 +241,8 @@ def gen_reference_components(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_settings(): """ @@ -242,11 +251,11 @@ def gen_reference_settings(): module = import_module("django_components.app_settings") preface = "\n\n" - preface += (root / "docs/templates/reference_settings.md").read_text() - out_file = root / "docs/reference/settings.md" + template_path = "docs/templates/reference_settings.md" + preface += (root / template_path).read_text() + out_path = "reference/settings.md" - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: # 1. Insert section from `reference_settings.md` f.write(preface + "\n\n") @@ -288,6 +297,8 @@ def gen_reference_settings(): ) f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + # Get attributes / methods that are unique to the subclass def _get_unique_methods(base_class: Type, sub_class: Type): @@ -347,8 +358,9 @@ def gen_reference_tagformatters(): module = import_module("django_components") preface = "\n\n" - preface += (root / "docs/templates/reference_tagformatters.md").read_text() - out_file = root / "docs/reference/tag_formatters.md" + template_path = "docs/templates/reference_tagformatters.md" + preface += (root / template_path).read_text() + out_path = "reference/tag_formatters.md" tag_formatter_classes: Dict[str, Type[TagFormatterABC]] = {} tag_formatter_instances: Dict[str, TagFormatterABC] = {} @@ -358,8 +370,7 @@ def gen_reference_tagformatters(): elif _is_tag_formatter_cls(obj): tag_formatter_classes[name] = obj - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") # Generate a summary of available tag formatters. @@ -402,6 +413,8 @@ def gen_reference_tagformatters(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_urls(): """ @@ -410,13 +423,13 @@ def gen_reference_urls(): module = import_module("django_components.urls") preface = "\n\n" - preface += (root / "docs/templates/reference_urls.md").read_text() - out_file = root / "docs/reference/urls.md" + template_path = "docs/templates/reference_urls.md" + preface += (root / template_path).read_text() + out_path = "reference/urls.md" all_urls = _list_urls(module.urlpatterns) - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") # 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`. """ preface = "\n\n" - preface += (root / "docs/templates/reference_commands.md").read_text() - out_file = root / "docs/reference/commands.md" + template_path = "docs/templates/reference_commands.md" + preface += (root / template_path).read_text() + out_path = "reference/commands.md" - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") # Document all commands defined by django-components @@ -530,6 +543,8 @@ def gen_reference_commands(): f"{cmd_desc}\n\n" ) + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_template_tags(): """ @@ -544,11 +559,11 @@ def gen_reference_template_tags(): ] preface = "\n\n" - preface += (root / "docs/templates/reference_template_tags.md").read_text() - out_file = root / "docs/reference/template_tags.md" + template_path = "docs/templates/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 out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") for mod_name, mod_path in tags_modules: @@ -591,6 +606,8 @@ def gen_reference_template_tags(): f"{docstring}\n\n" ) + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_template_variables(): """ @@ -598,16 +615,18 @@ def gen_reference_template_variables(): under the `{{ component_vars }}` variable, as defined by `ComponentVars`. """ preface = "\n\n" - preface += (root / "docs/templates/reference_template_variables.md").read_text() - out_file = root / "docs/reference/template_variables.md" + template_path = "docs/templates/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 out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") for field in ComponentVars._fields: 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(): """ @@ -616,11 +635,11 @@ def gen_reference_extension_hooks(): module = import_module("django_components.extension") preface = "\n\n" - preface += (root / "docs/templates/reference_extension_hooks.md").read_text() - out_file = root / "docs/reference/extension_hooks.md" + template_path = "docs/templates/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 out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: # 1. Insert section from `reference_extension_hooks.md` f.write(preface + "\n\n") @@ -700,6 +719,8 @@ def gen_reference_extension_hooks(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_extension_commands(): """ @@ -708,11 +729,11 @@ def gen_reference_extension_commands(): module = import_module("django_components") preface = "\n\n" - preface += (root / "docs/templates/reference_extension_commands.md").read_text() - out_file = root / "docs/reference/extension_commands.md" + template_path = "docs/templates/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 out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: # 1. Insert section from `reference_extension_commands.md` f.write(preface + "\n\n") @@ -737,6 +758,8 @@ def gen_reference_extension_commands(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def gen_reference_extension_urls(): """ @@ -745,11 +768,11 @@ def gen_reference_extension_urls(): module = import_module("django_components") preface = "\n\n" - preface += (root / "docs/templates/reference_extension_urls.md").read_text() - out_file = root / "docs/reference/extension_urls.md" + template_path = "docs/templates/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 out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: # 1. Insert section from `reference_extension_urls.md` f.write(preface + "\n\n") @@ -774,6 +797,8 @@ def gen_reference_extension_urls(): f.write("\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + forward_ref_pattern = re.compile(r"ForwardRef\('(.+?)'\)") class_repr_pattern = re.compile(r"") @@ -890,13 +915,15 @@ def gen_reference_signals(): send by or during the use of django-components. """ preface = "\n\n" - preface += (root / "docs/templates/reference_signals.md").read_text() - out_file = root / "docs/reference/signals.md" + template_path = "docs/templates/reference_signals.md" + preface += (root / template_path).read_text() + out_path = "reference/signals.md" - out_file.parent.mkdir(parents=True, exist_ok=True) - with out_file.open("w", encoding="utf-8") as f: + with mkdocs_gen_files.open(out_path, "w", encoding="utf-8") as f: f.write(preface + "\n\n") + mkdocs_gen_files.set_edit_path(out_path, template_path) + def _list_urls(urlpatterns: Sequence[Union[URLPattern, URLResolver]], prefix=""): """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 -gen_reference() +if __name__ == "__main__": + gen_reference() diff --git a/mkdocs.yml b/mkdocs.yml index 0328a549..41b1a0a7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,10 +1,11 @@ --- +# See https://www.mkdocs.org/user-guide/configuration site_name: Django-Components site_description: A way to create simple reusable template components in Django. site_url: https://django-components.github.io/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/ dev_addr: "127.0.0.1:9000" diff --git a/src/django_components/app_settings.py b/src/django_components/app_settings.py index 68f0f9e7..a6eddefd 100644 --- a/src/django_components/app_settings.py +++ b/src/django_components/app_settings.py @@ -40,9 +40,9 @@ ContextBehaviorType = Literal["django", "isolated"] class ContextBehavior(str, Enum): """ 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:** @@ -56,7 +56,7 @@ class ContextBehavior(str, Enum): That is, they enrich the context, and pass it along. 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. **Example:** @@ -98,7 +98,7 @@ class ContextBehavior(str, Enum): """ This setting makes the component fills behave similar to Vue or React, where 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:** @@ -151,14 +151,14 @@ class ComponentsSettings(NamedTuple): 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: - Python import path, e.g. `"path.to.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:** @@ -176,7 +176,7 @@ class ComponentsSettings(NamedTuple): """ 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:** @@ -197,7 +197,7 @@ class ComponentsSettings(NamedTuple): 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` @@ -217,8 +217,8 @@ class ComponentsSettings(NamedTuple): Directories must be full paths, same as with [STATICFILES_DIRS](https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-STATICFILES_DIRS). - These locations are searched during [autodiscovery](../../concepts/fundamentals/autodiscovery), - or when you [define HTML, JS, or CSS as separate files](../../concepts/fundamentals/html_js_css_files). + 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.md). ```python COMPONENTS = ComponentsSettings( @@ -251,8 +251,8 @@ class ComponentsSettings(NamedTuple): To search for `/my_comps/`. - These locations are searched during [autodiscovery](../../concepts/fundamentals/autodiscovery), - or when you [define HTML, JS, or CSS as separate files](../../concepts/fundamentals/html_js_css_files). + 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.md). Set to empty list to disable app-level components: @@ -273,7 +273,7 @@ class ComponentsSettings(NamedTuple): Defaults to `None`. - Read more about [caching](../../guides/setup/caching). + Read more about [caching](../guides/setup/caching.md). ```python COMPONENTS = ComponentsSettings( @@ -285,12 +285,12 @@ class ComponentsSettings(NamedTuple): context_behavior: Optional[ContextBehaviorType] = None """ Configure whether, inside a component template, you can use variables from the outside - ([`"django"`](../api#django_components.ContextBehavior.DJANGO)) - or not ([`"isolated"`](../api#django_components.ContextBehavior.ISOLATED)). - This also affects what variables are available inside the [`{% fill %}`](../template_tags#fill) + ([`"django"`](./api.md#django_components.ContextBehavior.DJANGO)) + or not ([`"isolated"`](./api.md#django_components.ContextBehavior.ISOLATED)). + This also affects 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). Defaults to `"django"`. @@ -313,11 +313,11 @@ class ComponentsSettings(NamedTuple): debug_highlight_components: Optional[bool] = None """ 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. 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`. @@ -332,11 +332,11 @@ class ComponentsSettings(NamedTuple): debug_highlight_slots: Optional[bool] = None """ 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. 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`. @@ -349,7 +349,7 @@ class ComponentsSettings(NamedTuple): 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"`. 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. - 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 a structure of components that is independent from your apps. @@ -409,7 +409,7 @@ class ComponentsSettings(NamedTuple): # Manually loading libraries 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 from django_components import import_libraries @@ -421,7 +421,7 @@ class ComponentsSettings(NamedTuple): multiline_tags: Optional[bool] = None """ 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. Defaults to `True`. @@ -439,7 +439,7 @@ class ComponentsSettings(NamedTuple): # TODO_REMOVE_IN_V1 reload_on_template_change: Optional[bool] = None """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 reload_on_file_change: Optional[bool] = None @@ -458,12 +458,12 @@ class ComponentsSettings(NamedTuple): HTML, JS, or CSS changes. 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 - [`COMPONENTS.app_dirs`](../settings/#django_components.app_settings.ComponentsSettings.app_dirs) + [`COMPONENTS.app_dirs`](./settings.md#django_components.app_settings.ComponentsSettings.app_dirs) 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`. @@ -475,9 +475,9 @@ class ComponentsSettings(NamedTuple): static_files_allowed: Optional[List[Union[str, re.Pattern]]] = None """ 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 - [`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/). 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 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 forbidden_static_files: Optional[List[Union[str, re.Pattern]]] = None """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 static_files_forbidden: Optional[List[Union[str, re.Pattern]]] = None """ 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 - [`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/). 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`](../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 - [`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. 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 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 """ 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"`. - 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: @@ -637,7 +637,7 @@ class ComponentsSettings(NamedTuple): 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()`](../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. ```python @@ -655,7 +655,7 @@ class ComponentsSettings(NamedTuple): ``` 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 from django_components import cached_template diff --git a/src/django_components/component_registry.py b/src/django_components/component_registry.py index f0d902b7..2142582f 100644 --- a/src/django_components/component_registry.py +++ b/src/django_components/component_registry.py @@ -33,9 +33,9 @@ TComponent = TypeVar("TComponent", bound="Component") 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 - [ComponentRegistry](../api#django_components.ComponentRegistry). + [ComponentRegistry](./api.md#django_components.ComponentRegistry). """ pass @@ -43,9 +43,9 @@ class AlreadyRegistered(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 - [ComponentRegistry](../api#django_components.ComponentRegistry). + [ComponentRegistry](./api.md#django_components.ComponentRegistry). """ pass @@ -67,7 +67,7 @@ class ComponentRegistryEntry(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. @@ -86,11 +86,11 @@ class RegistrySettings(NamedTuple): context_behavior: Optional[ContextBehaviorType] = None """ 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. 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. """ @@ -100,22 +100,22 @@ class RegistrySettings(NamedTuple): _Deprecated. Use `context_behavior` instead. Will be removed in v1._ 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. 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. """ tag_formatter: Optional[Union["TagFormatterABC", str]] = None """ 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. 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. """ @@ -125,11 +125,11 @@ class RegistrySettings(NamedTuple): _Deprecated. Use `tag_formatter` instead. Will be removed in v1._ 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. 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. """ @@ -147,7 +147,7 @@ ALL_REGISTRIES: AllRegistries = [] 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"] = [] for reg_ref in ALL_REGISTRIES: @@ -159,8 +159,8 @@ def all_registries() -> List["ComponentRegistry"]: class ComponentRegistry: """ - Manages [components](../api#django_components.Component) and makes them available - in the template, by default as [`{% component %}`](../template_tags#component) + Manages [components](./api.md#django_components.Component) and makes them available + in the template, by default as [`{% component %}`](./template_tags.md#component) tags. ```django @@ -175,7 +175,7 @@ class ComponentRegistry: 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. - See [Registering components](../../concepts/advanced/component_registry). + See [Registering components](../concepts/advanced/component_registry.md). Args: 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. settings (Union[RegistrySettings, Callable[[ComponentRegistry], RegistrySettings]], optional): Configure\ 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\ - [`COMPONENTS`](../settings#django_components.app_settings.ComponentsSettings) are used. + [`COMPONENTS`](./settings.md#django_components.app_settings.ComponentsSettings) are used. **Notes:** - - The default registry is available as [`django_components.registry`](../api#django_components.registry). - - The default registry is used when registering components with [`@register`](../api#django_components.register) + - 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.md#django_components.register) decorator. **Example:** @@ -302,7 +302,7 @@ class ComponentRegistry: @property 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 # so the settings can respond to changes. @@ -325,7 +325,7 @@ class ComponentRegistry: 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. A component MUST be registered before it can be used in a template such as: @@ -340,7 +340,7 @@ class ComponentRegistry: **Raises:** - - [`AlreadyRegistered`](../exceptions#django_components.AlreadyRegistered) + - [`AlreadyRegistered`](./exceptions.md#django_components.AlreadyRegistered) if a different component was already registered under the same name. **Example:** @@ -377,7 +377,7 @@ class ComponentRegistry: 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. Once a component is unregistered, it is no longer available in the templates. @@ -387,7 +387,7 @@ class ComponentRegistry: **Raises:** - - [`NotRegistered`](../exceptions#django_components.NotRegistered) + - [`NotRegistered`](./exceptions.md#django_components.NotRegistered) if the given name is not registered. **Example:** @@ -438,7 +438,7 @@ class ComponentRegistry: 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. Args: @@ -449,7 +449,7 @@ class ComponentRegistry: **Raises:** - - [`NotRegistered`](../exceptions#django_components.NotRegistered) + - [`NotRegistered`](./exceptions.md#django_components.NotRegistered) if the given name is not registered. **Example:** @@ -469,7 +469,7 @@ class ComponentRegistry: 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. Args: @@ -492,7 +492,7 @@ class ComponentRegistry: 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: 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 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: -See [Registering components](../../concepts/advanced/component_registry). +See [Registering components](../concepts/advanced/component_registry.md). ```python # Register components @@ -621,11 +621,11 @@ def register(name: str, registry: Optional[ComponentRegistry] = None) -> Callabl Class decorator for registering a [component](./#django_components.Component) to a [component registry](./#django_components.ComponentRegistry). - See [Registering components](../../concepts/advanced/component_registry). + See [Registering components](../concepts/advanced/component_registry.md). Args: 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)\ to which to register this component. If omitted, component is registered to the default registry. diff --git a/src/django_components/components/dynamic.py b/src/django_components/components/dynamic.py index 70b9e32f..db959227 100644 --- a/src/django_components/components/dynamic.py +++ b/src/django_components/components/dynamic.py @@ -16,8 +16,8 @@ class DynamicComponent(Component): Args: 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. - registry (ComponentRegistry, optional): Specify the [registry](../api#django_components.ComponentRegistry)\ + or a [Component](./api.md#django_components.Component) class directly. Required. + 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. *args: 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, 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. ```py diff --git a/src/django_components/extension.py b/src/django_components/extension.py index a95d9755..1f8ec233 100644 --- a/src/django_components/extension.py +++ b/src/django_components/extension.py @@ -214,8 +214,8 @@ class ExtensionComponentConfig: `ExtensionComponentConfig` is the base class for all extension component configs. Extensions can define nested classes on the component class, - such as [`Component.View`](../api#django_components.Component.View) or - [`Component.Cache`](../api#django_components.Component.Cache): + such as [`Component.View`](./api.md#django_components.Component.View) or + [`Component.Cache`](./api.md#django_components.Component.Cache): ```py class MyComp(Component): @@ -249,19 +249,19 @@ class ExtensionComponentConfig: """ 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` 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" """ - 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, 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. """ @@ -273,7 +273,7 @@ class ExtensionComponentConfig: BaseExtensionClass = ExtensionComponentConfig """ 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. - Read more on [Extensions](../../concepts/advanced/extensions). + Read more on [Extensions](../concepts/advanced/extensions.md). **Example:** @@ -351,16 +351,16 @@ class ComponentExtension(metaclass=ExtensionMeta): 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 - 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 [`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. 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`. ```python @@ -377,7 +377,7 @@ class ComponentExtension(metaclass=ExtensionMeta): !!! info 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] @@ -385,7 +385,7 @@ class ComponentExtension(metaclass=ExtensionMeta): Name of the extension class. 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. 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 """ 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 instance. 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 - the [`Component`](../api#django_components.Component) class. E.g.: + the [`Component`](./api.md#django_components.Component) class. E.g.: ```python class MyComp(Component): @@ -462,7 +462,7 @@ class ComponentExtension(metaclass=ExtensionMeta): These commands will be available to the user as `components ext run `. Commands are defined as subclasses of - [`ComponentCommand`](../extension_commands#django_components.ComponentCommand). + [`ComponentCommand`](./extension_commands.md#django_components.ComponentCommand). **Example:** @@ -536,13 +536,13 @@ class ComponentExtension(metaclass=ExtensionMeta): 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. 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:** @@ -559,12 +559,12 @@ class ComponentExtension(metaclass=ExtensionMeta): 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. - 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:** @@ -581,10 +581,10 @@ class ComponentExtension(metaclass=ExtensionMeta): 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 - [`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. @@ -603,10 +603,10 @@ class ComponentExtension(metaclass=ExtensionMeta): 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 - 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. @@ -625,10 +625,10 @@ class ComponentExtension(metaclass=ExtensionMeta): def on_component_registered(self, ctx: OnComponentRegisteredContext) -> None: """ - Called when a [`Component`](../api#django_components.Component) class is - registered with a [`ComponentRegistry`](../api#django_components.ComponentRegistry). + Called when a [`Component`](./api.md#django_components.Component) class is + 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. **Example:** @@ -645,10 +645,10 @@ class ComponentExtension(metaclass=ExtensionMeta): def on_component_unregistered(self, ctx: OnComponentUnregisteredContext) -> None: """ - Called when a [`Component`](../api#django_components.Component) class is - unregistered from a [`ComponentRegistry`](../api#django_components.ComponentRegistry). + Called when a [`Component`](./api.md#django_components.Component) class is + 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. **Example:** @@ -669,17 +669,17 @@ class ComponentExtension(metaclass=ExtensionMeta): 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. 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 - [`Component.get_template_data()`](../api#django_components.Component.get_template_data), - [`Component.get_js_data()`](../api#django_components.Component.get_js_data), - and [`Component.get_css_data()`](../api#django_components.Component.get_css_data) methods, + [`Component.get_template_data()`](./api.md#django_components.Component.get_template_data), + [`Component.get_js_data()`](./api.md#django_components.Component.get_js_data), + and [`Component.get_css_data()`](./api.md#django_components.Component.get_css_data) methods, 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. 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. - As such, if a component defines [`Args`](../api#django_components.Component.Args), - [`Kwargs`](../api#django_components.Component.Kwargs), - [`Slots`](../api#django_components.Component.Slots) types, these types are NOT yet instantiated. + As such, if a component defines [`Args`](./api.md#django_components.Component.Args), + [`Kwargs`](./api.md#django_components.Component.Kwargs), + [`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), - [`Component.kwargs`](../api#django_components.Component.kwargs), - [`Component.slots`](../api#django_components.Component.slots) + Instead, component fields like [`Component.args`](./api.md#django_components.Component.args), + [`Component.kwargs`](./api.md#django_components.Component.kwargs), + [`Component.slots`](./api.md#django_components.Component.slots) are plain `list` / `dict` objects. """ pass 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. This hook is called after - [`Component.get_template_data()`](../api#django_components.Component.get_template_data), - [`Component.get_js_data()`](../api#django_components.Component.get_js_data) - and [`Component.get_css_data()`](../api#django_components.Component.get_css_data). + [`Component.get_template_data()`](./api.md#django_components.Component.get_template_data), + [`Component.get_js_data()`](./api.md#django_components.Component.get_js_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. @@ -743,13 +743,13 @@ class ComponentExtension(metaclass=ExtensionMeta): 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. Use this hook to access or post-process the component's rendered output. 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. @@ -807,9 +807,9 @@ class ComponentExtension(metaclass=ExtensionMeta): """ 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 - [`Component.template`](../api#django_components.Component.template) and - [`Component.template_file`](../api#django_components.Component.template_file). + This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both + [`Component.template`](./api.md#django_components.Component.template) and + [`Component.template_file`](./api.md#django_components.Component.template_file). 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 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 - [`Component.template`](../api#django_components.Component.template) and - [`Component.template_file`](../api#django_components.Component.template_file). + This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both + [`Component.template`](./api.md#django_components.Component.template) and + [`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. @@ -855,9 +855,9 @@ class ComponentExtension(metaclass=ExtensionMeta): """ 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 - [`Component.css`](../api#django_components.Component.css) and - [`Component.css_file`](../api#django_components.Component.css_file). + This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both + [`Component.css`](./api.md#django_components.Component.css) and + [`Component.css_file`](./api.md#django_components.Component.css_file). 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. - This hook runs only once per [`Component`](../api#django_components.Component) class and works for both - [`Component.js`](../api#django_components.Component.js) and - [`Component.js_file`](../api#django_components.Component.js_file). + This hook runs only once per [`Component`](./api.md#django_components.Component) class and works for both + [`Component.js`](./api.md#django_components.Component.js) and + [`Component.js_file`](./api.md#django_components.Component.js_file). 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]: """ - 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. @@ -926,12 +926,12 @@ class ComponentExtension(metaclass=ExtensionMeta): **Access slot metadata:** - You can access the [`{% slot %}` tag](../template_tags#slot) - node ([`SlotNode`](../api#django_components.SlotNode)) and its metadata using `ctx.slot_node`. + You can access the [`{% slot %}` tag](./template_tags.md#slot) + 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 - belongs the template where the [`{% slot %}`](../template_tags#slot) tag is defined, you can use - [`ctx.slot_node.template_component`](../api#django_components.SlotNode.template_component): + For example, to find the [`Component`](./api.md#django_components.Component) class to which + belongs the template where the [`{% slot %}`](./template_tags.md#slot) tag is defined, you can use + [`ctx.slot_node.template_component`](./api.md#django_components.SlotNode.template_component): ```python from django_components import ComponentExtension, OnSlotRenderedContext diff --git a/src/django_components/library.py b/src/django_components/library.py index 5cff7d5f..f04fde18 100644 --- a/src/django_components/library.py +++ b/src/django_components/library.py @@ -8,9 +8,9 @@ from django.template.library import Library 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, - 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) with the associated instance of Django's [`Library`](https://docs.djangoproject.com/en/5.2/howto/custom-template-tags/#code-layout). @@ -23,11 +23,11 @@ class TagProtectedError(Exception): {% endtable %} ``` - Then [`ComponentRegistry`](../api#django_components.ComponentRegistry) + Then [`ComponentRegistry`](./api.md#django_components.ComponentRegistry) registers the tag `table` onto the Django's Library instance. 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 a forbidden name, such that it would overwrite one of django_component's own template tags.