Prepare directories that may contain component files:
Searches for dirs set in COMPONENTS.dirs
settings. If none set, defaults to searching for a "components" app. The dirs in COMPONENTS.dirs
must be absolute paths.
In addition to that, also all apps are checked for [app]/components
dirs.
Paths are accepted only if they resolve to a directory. E.g. /path/to/django_project/my_app/components/
.
BASE_DIR
setting is required.
Source code in src/django_components/template_loader.py
| def get_dirs(self, include_apps: bool = True) -> List[Path]:
"""
Prepare directories that may contain component files:
Searches for dirs set in `COMPONENTS.dirs` settings. If none set, defaults to searching
for a "components" app. The dirs in `COMPONENTS.dirs` must be absolute paths.
In addition to that, also all apps are checked for `[app]/components` dirs.
Paths are accepted only if they resolve to a directory.
E.g. `/path/to/django_project/my_app/components/`.
`BASE_DIR` setting is required.
"""
# Allow to configure from settings which dirs should be checked for components
component_dirs = app_settings.DIRS
# TODO_REMOVE_IN_V1
is_legacy_paths = (
# Use value of `STATICFILES_DIRS` ONLY if `COMPONENT.dirs` not set
not getattr(settings, "COMPONENTS", {}).get("dirs", None) is not None
and hasattr(settings, "STATICFILES_DIRS")
and settings.STATICFILES_DIRS
)
if is_legacy_paths:
# NOTE: For STATICFILES_DIRS, we use the defaults even for empty list.
# We don't do this for COMPONENTS.dirs, so user can explicitly specify "NO dirs".
component_dirs = settings.STATICFILES_DIRS or [settings.BASE_DIR / "components"]
source = "STATICFILES_DIRS" if is_legacy_paths else "COMPONENTS.dirs"
logger.debug(
"Template loader will search for valid template dirs from following options:\n"
+ "\n".join([f" - {str(d)}" for d in component_dirs])
)
# Add `[app]/[APP_DIR]` to the directories. This is, by default `[app]/components`
app_paths: List[Path] = []
if include_apps:
for conf in apps.get_app_configs():
for app_dir in app_settings.APP_DIRS:
comps_path = Path(conf.path).joinpath(app_dir)
if comps_path.exists():
app_paths.append(comps_path)
directories: Set[Path] = set(app_paths)
# Validate and add other values from the config
for component_dir in component_dirs:
# Consider tuples for STATICFILES_DIRS (See #489)
# See https://docs.djangoproject.com/en/5.0/ref/settings/#prefixes-optional
if isinstance(component_dir, (tuple, list)):
component_dir = component_dir[1]
try:
Path(component_dir)
except TypeError:
logger.warning(
f"{source} expected str, bytes or os.PathLike object, or tuple/list of length 2. "
f"See Django documentation for STATICFILES_DIRS. Got {type(component_dir)} : {component_dir}"
)
continue
if not Path(component_dir).is_absolute():
raise ValueError(f"{source} must contain absolute paths, got '{component_dir}'")
else:
directories.add(Path(component_dir).resolve())
logger.debug(
"Template loader matched following template dirs:\n" + "\n".join([f" - {str(d)}" for d in directories])
)
return list(directories)
|