mirror of
https://github.com/django-components/django-components.git
synced 2025-08-10 09:17:59 +00:00
feat: extensions (#1009)
* feat: extensions * refactor: remove support for passing in extensions as instances
This commit is contained in:
parent
cff252c566
commit
4d35bc97a2
24 changed files with 1884 additions and 57 deletions
|
@ -1,6 +1,7 @@
|
|||
import re
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from importlib import import_module
|
||||
from os import PathLike
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
|
@ -15,6 +16,7 @@ from typing import (
|
|||
Optional,
|
||||
Sequence,
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
Union,
|
||||
cast,
|
||||
|
@ -25,6 +27,7 @@ from django.conf import settings
|
|||
from django_components.util.misc import default
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from django_components.extension import ComponentExtension
|
||||
from django_components.tag_formatter import TagFormatterABC
|
||||
|
||||
|
||||
|
@ -146,6 +149,25 @@ class ComponentsSettings(NamedTuple):
|
|||
```
|
||||
"""
|
||||
|
||||
extensions: Optional[Sequence[Union[Type["ComponentExtension"], str]]] = None
|
||||
"""
|
||||
List of [extensions](../../concepts/advanced/extensions) to be loaded.
|
||||
|
||||
The extensions can be specified as:
|
||||
|
||||
- Python import path, e.g. `"path.to.my_extension.MyExtension"`.
|
||||
- Extension class, e.g. `my_extension.MyExtension`.
|
||||
|
||||
```python
|
||||
COMPONENTS = ComponentsSettings(
|
||||
extensions=[
|
||||
"path.to.my_extension.MyExtension",
|
||||
StorybookExtension,
|
||||
],
|
||||
)
|
||||
```
|
||||
"""
|
||||
|
||||
autodiscover: Optional[bool] = None
|
||||
"""
|
||||
Toggle whether to run [autodiscovery](../../concepts/fundamentals/autodiscovery) at the Django server startup.
|
||||
|
@ -647,6 +669,7 @@ defaults = ComponentsSettings(
|
|||
debug_highlight_components=False,
|
||||
debug_highlight_slots=False,
|
||||
dynamic_component_name="dynamic",
|
||||
extensions=[],
|
||||
libraries=[], # E.g. ["mysite.components.forms", ...]
|
||||
multiline_tags=True,
|
||||
reload_on_file_change=False,
|
||||
|
@ -709,6 +732,9 @@ class InternalSettings:
|
|||
components_settings.dynamic_component_name, defaults.dynamic_component_name
|
||||
),
|
||||
libraries=default(components_settings.libraries, defaults.libraries),
|
||||
# NOTE: Internally we store the extensions as a list of instances, but the user
|
||||
# can pass in either a list of classes or a list of import strings.
|
||||
extensions=self._prepare_extensions(components_settings), # type: ignore[arg-type]
|
||||
multiline_tags=default(components_settings.multiline_tags, defaults.multiline_tags),
|
||||
reload_on_file_change=self._prepare_reload_on_file_change(components_settings),
|
||||
template_cache_size=default(components_settings.template_cache_size, defaults.template_cache_size),
|
||||
|
@ -718,6 +744,33 @@ class InternalSettings:
|
|||
tag_formatter=default(components_settings.tag_formatter, defaults.tag_formatter), # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
def _prepare_extensions(self, new_settings: ComponentsSettings) -> List["ComponentExtension"]:
|
||||
extensions: Sequence[Union[Type["ComponentExtension"], str]] = default(
|
||||
new_settings.extensions, cast(List[str], defaults.extensions)
|
||||
)
|
||||
|
||||
# Prepend built-in extensions
|
||||
from django_components.extensions.view import ViewExtension
|
||||
|
||||
extensions = [ViewExtension] + list(extensions)
|
||||
|
||||
# Extensions may be passed in either as classes or import strings.
|
||||
extension_instances: List["ComponentExtension"] = []
|
||||
for extension in extensions:
|
||||
if isinstance(extension, str):
|
||||
import_path, class_name = extension.rsplit(".", 1)
|
||||
extension_module = import_module(import_path)
|
||||
extension = cast(Type["ComponentExtension"], getattr(extension_module, class_name))
|
||||
|
||||
if isinstance(extension, type):
|
||||
extension_instance = extension()
|
||||
else:
|
||||
extension_instances.append(extension)
|
||||
|
||||
extension_instances.append(extension_instance)
|
||||
|
||||
return extension_instances
|
||||
|
||||
def _prepare_reload_on_file_change(self, new_settings: ComponentsSettings) -> bool:
|
||||
val = new_settings.reload_on_file_change
|
||||
# TODO_REMOVE_IN_V1
|
||||
|
@ -780,6 +833,10 @@ class InternalSettings:
|
|||
def LIBRARIES(self) -> List[str]:
|
||||
return self._settings.libraries # type: ignore[return-value]
|
||||
|
||||
@property
|
||||
def EXTENSIONS(self) -> List["ComponentExtension"]:
|
||||
return self._settings.extensions # type: ignore[return-value]
|
||||
|
||||
@property
|
||||
def MULTILINE_TAGS(self) -> bool:
|
||||
return self._settings.multiline_tags # type: ignore[return-value]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue