diff --git a/wagtail/wagtailadmin/menu.py b/wagtail/wagtailadmin/menu.py
index 86a3c4705..4aae05cd3 100644
--- a/wagtail/wagtailadmin/menu.py
+++ b/wagtail/wagtailadmin/menu.py
@@ -27,16 +27,24 @@ class MenuItem(object):
else:
self.attr_string = ""
+ def is_shown(self, request):
+ return True
+
def render_html(self):
return format_html(
"""
""",
self.name, self.url, self.classnames, self.attr_string, self.label)
-_menu_items = None
-def get_menu_items():
- global _menu_items
- if _menu_items is None:
- _menu_items = [fn() for fn in hooks.get_hooks('register_admin_menu_item')]
+_master_menu_item_list = None
+def get_master_menu_item_list():
+ """
+ Return the list of menu items registered with the 'register_admin_menu_item' hook.
+ This is the "master list" because the final admin menu may vary per request
+ according to the value of is_shown() and the construct_main_menu hook.
+ """
+ global _master_menu_item_list
+ if _master_menu_item_list is None:
+ _master_menu_item_list = [fn() for fn in hooks.get_hooks('register_admin_menu_item')]
- return _menu_items
+ return _master_menu_item_list
diff --git a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py
index b14eabf2d..94bc14dde 100644
--- a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py
+++ b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py
@@ -6,7 +6,7 @@ from django import template
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.models import get_navigation_menu_items, UserPagePermissionsProxy, PageViewRestriction
from wagtail.wagtailcore.utils import camelcase_to_underscore
-from wagtail.wagtailadmin.menu import get_menu_items
+from wagtail.wagtailadmin.menu import get_master_menu_item_list
register = template.Library()
@@ -28,9 +28,8 @@ def explorer_subnav(nodes):
@register.inclusion_tag('wagtailadmin/shared/main_nav.html', takes_context=True)
def main_nav(context):
- menu_items = get_menu_items()[:] # need to clone with [:] because the return value of get_menu_items is global, and construct_main_menu hooks will mutate it
-
request = context['request']
+ menu_items = [item for item in get_master_menu_item_list() if item.is_shown(request)]
for fn in hooks.get_hooks('construct_main_menu'):
fn(request, menu_items)