Browse Source

Fixes #3847 by adding page as a third argument to construct_wagtail_userbar hooks along with a deprecation warning.

Claude Meyer 3 months ago
parent
commit
aa08e86cba

+ 2 - 2
docs/advanced_topics/accessibility_considerations.md

@@ -169,7 +169,7 @@ class CustomAccessibilityItem(AccessibilityItem):
 
 
 @hooks.register('construct_wagtail_userbar')
-def replace_userbar_accessibility_item(request, items):
+def replace_userbar_accessibility_item(request, items, page):
     items[:] = [CustomAccessibilityItem() if isinstance(item, AccessibilityItem) else item for item in items]
 ```
 
@@ -204,7 +204,7 @@ class CustomAccessibilityItem(AccessibilityItem):
 
 
 @hooks.register('construct_wagtail_userbar')
-def replace_userbar_accessibility_item(request, items):
+def replace_userbar_accessibility_item(request, items, page):
     items[:] = [CustomAccessibilityItem() if isinstance(item, AccessibilityItem) else item for item in items]
 ```
 

+ 2 - 2
docs/reference/hooks.md

@@ -870,7 +870,7 @@ def make_publish_default_action(menu_items, request, context):
 
 ### `construct_wagtail_userbar`
 
-Add or remove items from the Wagtail [user bar](wagtailuserbar_tag). Actions for adding and editing are provided by default. The callable passed into the hook must take the `request` object and a list of menu objects, `items`. The menu item objects must have a `render` method which can take a `request` object and return the HTML string representing the menu item. See the userbar templates and menu item classes for more information. See also the {class}`~wagtail.admin.userbar.AccessibilityItem` class for the accessibility checker item in particular.
+Add or remove items from the Wagtail [user bar](wagtailuserbar_tag). Actions for adding and editing are provided by default. The callable passed into the hook must take the `request` object, a list of menu objects `items`, and an instance of page object `page`. The menu item objects must have a `render` method which can take a `request` object and return the HTML string representing the menu item. See the userbar templates and menu item classes for more information. See also the {class}`~wagtail.admin.userbar.AccessibilityItem` class for the accessibility checker item in particular.
 
 ```python
 from wagtail import hooks
@@ -881,7 +881,7 @@ class UserbarPuppyLinkItem:
             + 'target="_parent" role="menuitem" class="action">Puppies!</a></li>'
 
 @hooks.register('construct_wagtail_userbar')
-def add_puppy_link_item(request, items):
+def add_puppy_link_item(request, items, page):
     return items.append( UserbarPuppyLinkItem() )
 ```
 

+ 15 - 1
wagtail/admin/templatetags/wagtailuserbar.py

@@ -1,3 +1,5 @@
+from warnings import warn
+
 from django import template
 from django.template.loader import render_to_string
 from django.utils import translation
@@ -10,8 +12,12 @@ from wagtail.admin.userbar import (
     EditPageItem,
     ExplorePageItem,
 )
+from wagtail.coreutils import (
+    accepts_kwarg,
+)
 from wagtail.models import PAGE_TEMPLATE_VAR, Page, Revision
 from wagtail.users.models import UserProfile
+from wagtail.utils.deprecation import RemovedInWagtail70Warning
 
 register = template.Library()
 
@@ -90,7 +96,15 @@ def wagtailuserbar(context, position="bottom-right"):
             ]
 
         for fn in hooks.get_hooks("construct_wagtail_userbar"):
-            fn(request, items)
+            if accepts_kwarg(fn, "page"):
+                fn(request, items, page)
+            else:
+                warn(
+                    "`construct_wagtail_userbar` hook functions should accept a `page` argument in third position -"
+                    f" {fn.__module__}.{fn.__name__} needs to be updated",
+                    category=RemovedInWagtail70Warning,
+                )
+                fn(request, items)
 
         # Render the items
         rendered_items = [item.render(request) for item in items]

+ 37 - 1
wagtail/admin/tests/test_userbar.py

@@ -11,6 +11,7 @@ from wagtail.coreutils import get_dummy_request
 from wagtail.models import PAGE_TEMPLATE_VAR, Page, Site
 from wagtail.test.testapp.models import BusinessChild, BusinessIndex, SimplePage
 from wagtail.test.utils import WagtailTestUtils
+from wagtail.utils.deprecation import RemovedInWagtail70Warning
 
 
 class TestUserbarTag(WagtailTestUtils, TestCase):
@@ -184,7 +185,7 @@ class TestAccessibilityCheckerConfig(WagtailTestUtils, TestCase):
         return json.loads(self.get_script().string)
 
     def get_hook(self, item_class):
-        def customise_accessibility_checker(request, items):
+        def customise_accessibility_checker(request, items, page):
             items[:] = [
                 item_class() if isinstance(item, AccessibilityItem) else item
                 for item in items
@@ -455,6 +456,41 @@ class TestUserbarInPageServe(WagtailTestUtils, TestCase):
         self.assertEqual(response.status_code, 200)
         self.assertNotContains(response, '<template id="wagtail-userbar-template">')
 
+    def test_construct_wagtail_userbar_hook_passes_page(self):
+        kwargs = {}
+
+        def construct_wagtail_userbar(request, items, page):
+            kwargs["page"] = page
+            return items
+
+        with hooks.register_temporarily(
+            "construct_wagtail_userbar",
+            construct_wagtail_userbar,
+        ):
+            response = self.page.serve(self.request)
+            response.render()
+
+            self.assertEqual(kwargs.get("page"), self.page)
+
+    def test_deprecated_construct_wagtail_userbar_hook_without_page(self):
+        kwargs = {}
+
+        def construct_wagtail_userbar(request, items):
+            kwargs["called"] = True
+            return items
+
+        with self.assertWarnsMessage(
+            RemovedInWagtail70Warning,
+            "`construct_wagtail_userbar` hook functions should accept a `page` argument in third position",
+        ), hooks.register_temporarily(
+            "construct_wagtail_userbar",
+            construct_wagtail_userbar,
+        ):
+            response = self.page.serve(self.request)
+            response.render()
+
+            self.assertTrue(kwargs.get("called"))
+
 
 class TestUserbarAddLink(WagtailTestUtils, TestCase):
     fixtures = ["test.json"]

+ 2 - 1
wagtail/admin/ui/side_panels.py

@@ -329,8 +329,9 @@ class ChecksSidePanel(BaseSidePanel):
     def get_axe_configuration(self):
         # Retrieve the Axe configuration from the userbar.
         userbar_items = [AccessibilityItem()]
+        page = self.object if issubclass(self.model, Page) else None
         for fn in hooks.get_hooks("construct_wagtail_userbar"):
-            fn(self.request, userbar_items)
+            fn(self.request, userbar_items, page)
 
         for item in userbar_items:
             if isinstance(item, AccessibilityItem):