Source code for render_static.loaders.mixins

"""
Helper classes for augmenting loader behavior.
"""

from glob import glob
from os.path import relpath
from pathlib import Path
from typing import Generator, List, Union

from django.core.exceptions import SuspiciousFileOperation
from django.template.loaders.filesystem import safe_join  # type: ignore[attr-defined]

__all__ = ["BatchLoaderMixin"]


[docs] class BatchLoaderMixin: """ A mixin for Jinja2 loaders that enables glob pattern selectors to load batches of templates from the file system. Yields batches of template names in order of preference, where preference is defined by the order directories are listed in. """ def get_dirs(self) -> List[Union[str, Path]]: """ Return a priority ordered list of directories on the search path of this loader. """ raise NotImplementedError(f"{self.__class__.__name__} must implement get_dirs!") def select_templates(self, selector: str) -> Generator[List[str], None, None]: """ Yields template names matching the selector pattern. :param selector: A glob pattern, or file name """ for template_dir in self.get_dirs(): try: pattern = safe_join(template_dir, selector) except SuspiciousFileOperation: # The joined path was located outside of this template_dir # (it might be inside another one, so this isn't fatal). continue templates = [] for file in glob(pattern, recursive=True): pth = relpath(file, template_dir) if "__pycache__" in Path(pth).parts: continue templates.append(pth) yield templates