Browse Source

Added hooks for urls/api/context processors (#1309)

Rafał Pitoń 5 years ago
parent
commit
5f2b5082f2

+ 1 - 0
devproject/settings.py

@@ -294,6 +294,7 @@ TEMPLATES = [
                 "misago.legal.context_processors.legal_links",
                 "misago.legal.context_processors.legal_links",
                 "misago.menus.context_processors.menus",
                 "misago.menus.context_processors.menus",
                 "misago.users.context_processors.user_links",
                 "misago.users.context_processors.user_links",
+                "misago.core.context_processors.hooks",
                 # Data preloaders
                 # Data preloaders
                 "misago.conf.context_processors.preload_settings_json",
                 "misago.conf.context_processors.preload_settings_json",
                 "misago.core.context_processors.current_link",
                 "misago.core.context_processors.current_link",

+ 8 - 0
misago/core/context_processors.py

@@ -1,6 +1,7 @@
 from django.utils.translation import get_language
 from django.utils.translation import get_language
 
 
 from .. import __version__
 from .. import __version__
+from ..hooks import context_processors as context_processors_hooks
 from .momentjs import get_locale_url
 from .momentjs import get_locale_url
 
 
 
 
@@ -36,3 +37,10 @@ def frontend_context(request):
     if request.include_frontend_context:
     if request.include_frontend_context:
         return {"frontend_context": request.frontend_context}
         return {"frontend_context": request.frontend_context}
     return {}
     return {}
+
+
+def hooks(request):
+    context = {}
+    for hook in context_processors_hooks:
+        context.update(hook(request))
+    return context

+ 3 - 0
misago/hooks.py

@@ -0,0 +1,3 @@
+apipatterns = []
+urlpatterns = []
+context_processors = []

+ 1 - 0
misago/hooktypes/__init__.py

@@ -0,0 +1 @@
+from .applyfilters import apply_filters

+ 11 - 0
misago/hooktypes/applyfilters.py

@@ -0,0 +1,11 @@
+from functools import partial, reduce
+
+
+def apply_filters(action, hook, *args, **kwargs):
+    if not hook:
+        return action(*args, **kwargs)
+
+    filtered_action = reduce(
+        lambda chained_fns, next_fn: partial(next_fn, chained_fns), hook, action
+    )
+    return filtered_action(*args, **kwargs)

+ 0 - 0
misago/hooktypes/tests/__init__.py


+ 50 - 0
misago/hooktypes/tests/test_function_filtering.py

@@ -0,0 +1,50 @@
+from unittest.mock import Mock
+
+from ..applyfilters import apply_filters
+
+
+def test_filtering_calls_action_with_given_args():
+    action = Mock()
+    apply_filters(action, [], 1, 2)
+    action.assert_called_once_with(1, 2)
+
+
+def test_filtering_calls_action_with_given_kwargs():
+    action = Mock()
+    apply_filters(action, [], a=1, b=2)
+    action.assert_called_once_with(a=1, b=2)
+
+
+def test_filtering_returns_action_return_value():
+    action = Mock(return_value=42)
+    assert apply_filters(action, []) == 42
+
+
+def test_filter_is_called_with_action_as_first_arg():
+    filter_ = Mock()
+    action = Mock()
+    apply_filters(action, [filter_])
+    filter_.assert_called_once_with(action)
+
+
+def test_filter_is_called_with_given_args():
+    filter_ = Mock()
+    action = Mock()
+    apply_filters(action, [filter_], 1, 2)
+    filter_.assert_called_once_with(action, 1, 2)
+
+
+def test_filter_is_called_with_given_kwargs():
+    filter_ = Mock()
+    action = Mock()
+    apply_filters(action, [filter_], a=1, b=2)
+    filter_.assert_called_once_with(action, a=1, b=2)
+
+
+def test_filters_are_chained():
+    action = Mock(return_value=1)
+
+    def multiply_filter(action):
+        return action() * 2
+
+    assert apply_filters(action, [multiply_filter, multiply_filter]) == 4

+ 0 - 0
misago/plugins/hook.py


+ 3 - 2
misago/urls.py

@@ -1,13 +1,14 @@
 from django.conf.urls import include, url
 from django.conf.urls import include, url
 from django.views.generic import TemplateView
 from django.views.generic import TemplateView
 
 
+from . import hooks
 from .conf import settings
 from .conf import settings
 from .core.views import forum_index
 from .core.views import forum_index
 
 
 app_name = "misago"
 app_name = "misago"
 
 
 # Register Misago Apps
 # Register Misago Apps
-urlpatterns = [
+urlpatterns = hooks.urlpatterns + [
     url(r"^", include("misago.analytics.urls")),
     url(r"^", include("misago.analytics.urls")),
     url(r"^", include("misago.legal.urls")),
     url(r"^", include("misago.legal.urls")),
     url(r"^", include("misago.users.urls")),
     url(r"^", include("misago.users.urls")),
@@ -32,7 +33,7 @@ urlpatterns = [
 
 
 
 
 # Register API
 # Register API
-apipatterns = [
+apipatterns = hooks.apipatterns + [
     url(r"^", include("misago.categories.urls.api")),
     url(r"^", include("misago.categories.urls.api")),
     url(r"^", include("misago.legal.urls.api")),
     url(r"^", include("misago.legal.urls.api")),
     url(r"^", include("misago.markup.urls")),
     url(r"^", include("misago.markup.urls")),