diff --git a/pattern_library/cm_utils.py b/pattern_library/cm_utils.py index 643a499b..076ef530 100644 --- a/pattern_library/cm_utils.py +++ b/pattern_library/cm_utils.py @@ -1,7 +1,30 @@ import inspect +from importlib import import_module from typing import Callable +from django.apps import apps +from django.utils.module_loading import module_has_submodule + + +def get_app_modules(): + """ + Generator function that yields a module object for each installed app + yields tuples of (app_name, module) + """ + for app in apps.get_app_configs(): + yield app.name, app.module + + +def get_app_submodules(submodule_name): + """ + Searches each app module for the specified submodule + yields tuples of (app_name, module) + """ + for name, module in get_app_modules(): + if module_has_submodule(module, submodule_name): + yield name, import_module('%s.%s' % (name, submodule_name)) + def accepts_kwarg(func: Callable, kwarg: str) -> bool: """ diff --git a/pattern_library/context_modifiers.py b/pattern_library/context_modifiers.py index 4883d9bc..6eb2f084 100644 --- a/pattern_library/context_modifiers.py +++ b/pattern_library/context_modifiers.py @@ -4,7 +4,7 @@ from django.core.exceptions import ImproperlyConfigured -from .cm_utils import accepts_kwarg +from .cm_utils import accepts_kwarg, get_app_submodules GENERIC_CM_KEY = "__generic__" ORDER_ATTR_NAME = "__cm_order" @@ -18,6 +18,12 @@ class ContextModifierRegistry(defaultdict): def __init__(self): super().__init__(list) + self.searched_for_modifiers = False + + def search_for_modifiers(self) -> None: + if not self.searched_for_modifiers: + list(get_app_submodules('pattern_contexts')) + self.searched_for_modifiers = True def register(self, func: Callable, template: str = None, order: int = 0) -> None: """ @@ -50,6 +56,7 @@ def register_decorator(self, func: Callable = None, **kwargs): return self.register(func, **kwargs) def get_for_template(self, template: str): + self.search_for_modifiers() modifiers = self[GENERIC_CM_KEY] + self[template] return sorted(modifiers, key=attrgetter(ORDER_ATTR_NAME))