prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Wagtail 2.16 - Slim Sidebar open only settings
  ### Issue Summary
  When click on any menu item with submenu pages, the settings submenu always opens. 
  
  ### Steps to Reproduce
  
  1. Open admin page
  2. Click on any menu item with a submenu 
  3. Settings submenu always opens
  
  When click on the pages menu item, both submenus open. 
  
  ### Technical details
  
  * Python version: 3.9.9.
  * Django version: 3.2.12.
  * Wagtail version: 2.16
  * Browser version: firefox 96.0.3
  
  
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `wagtail/admin/menu.py`
  Content:
  ```
  1 from django.forms import Media, MediaDefiningClass
  2 from django.forms.utils import flatatt
  3 from django.template.loader import render_to_string
  4 from django.utils.safestring import mark_safe
  5 from django.utils.text import slugify
  6 
  7 from wagtail.admin.ui.sidebar import LinkMenuItem as LinkMenuItemComponent
  8 from wagtail.admin.ui.sidebar import SubMenuItem as SubMenuItemComponent
  9 from wagtail.core import hooks
  10 
  11 
  12 class MenuItem(metaclass=MediaDefiningClass):
  13     template = 'wagtailadmin/shared/menu_item.html'
  14 
  15     def __init__(self, label, url, name=None, classnames='', icon_name='', attrs=None, order=1000):
  16         self.label = label
  17         self.url = url
  18         self.classnames = classnames
  19         self.icon_name = icon_name
  20         self.name = (name or slugify(str(label)))
  21         self.order = order
  22 
  23         if attrs:
  24             self.attr_string = flatatt(attrs)
  25         else:
  26             self.attr_string = ""
  27 
  28     def is_shown(self, request):
  29         """
  30         Whether this menu item should be shown for the given request; permission
  31         checks etc should go here. By default, menu items are shown all the time
  32         """
  33         return True
  34 
  35     def is_active(self, request):
  36         return request.path.startswith(str(self.url))
  37 
  38     def get_context(self, request):
  39         """Defines context for the template, overridable to use more data"""
  40         return {
  41             'name': self.name,
  42             'url': self.url,
  43             'classnames': self.classnames,
  44             'icon_name': self.icon_name,
  45             'attr_string': self.attr_string,
  46             'label': self.label,
  47             'active': self.is_active(request)
  48         }
  49 
  50     def render_html(self, request):
  51         context = self.get_context(request)
  52         return render_to_string(self.template, context, request=request)
  53 
  54     def render_component(self, request):
  55         return LinkMenuItemComponent(self.name, self.label, self.url, icon_name=self.icon_name, classnames=self.classnames)
  56 
  57 
  58 class Menu:
  59     def __init__(self, register_hook_name, construct_hook_name=None):
  60         self.register_hook_name = register_hook_name
  61         self.construct_hook_name = construct_hook_name
  62         # _registered_menu_items will be populated on first access to the
  63         # registered_menu_items property. We can't populate it in __init__ because
  64         # we can't rely on all hooks modules to have been imported at the point that
  65         # we create the admin_menu and settings_menu instances
  66         self._registered_menu_items = None
  67 
  68     @property
  69     def registered_menu_items(self):
  70         if self._registered_menu_items is None:
  71             self._registered_menu_items = [fn() for fn in hooks.get_hooks(self.register_hook_name)]
  72         return self._registered_menu_items
  73 
  74     def menu_items_for_request(self, request):
  75         items = [item for item in self.registered_menu_items if item.is_shown(request)]
  76 
  77         # provide a hook for modifying the menu, if construct_hook_name has been set
  78         if self.construct_hook_name:
  79             for fn in hooks.get_hooks(self.construct_hook_name):
  80                 fn(request, items)
  81 
  82         return items
  83 
  84     def active_menu_items(self, request):
  85         return [item for item in self.menu_items_for_request(request) if item.is_active(request)]
  86 
  87     @property
  88     def media(self):
  89         media = Media()
  90         for item in self.registered_menu_items:
  91             media += item.media
  92         return media
  93 
  94     def render_html(self, request):
  95         menu_items = self.menu_items_for_request(request)
  96         rendered_menu_items = []
  97         for item in sorted(menu_items, key=lambda i: i.order):
  98             rendered_menu_items.append(item.render_html(request))
  99         return mark_safe(''.join(rendered_menu_items))
  100 
  101     def render_component(self, request):
  102         menu_items = self.menu_items_for_request(request)
  103         rendered_menu_items = []
  104         for item in sorted(menu_items, key=lambda i: i.order):
  105             rendered_menu_items.append(item.render_component(request))
  106         return rendered_menu_items
  107 
  108 
  109 class SubmenuMenuItem(MenuItem):
  110     template = 'wagtailadmin/shared/menu_submenu_item.html'
  111 
  112     """A MenuItem which wraps an inner Menu object"""
  113     def __init__(self, label, menu, **kwargs):
  114         self.menu = menu
  115         super().__init__(label, '#', **kwargs)
  116 
  117     def is_shown(self, request):
  118         # show the submenu if one or more of its children is shown
  119         return bool(self.menu.menu_items_for_request(request))
  120 
  121     def is_active(self, request):
  122         return bool(self.menu.active_menu_items(request))
  123 
  124     def get_context(self, request):
  125         context = super().get_context(request)
  126         context['menu_html'] = self.menu.render_html(request)
  127         context['request'] = request
  128         return context
  129 
  130     def render_component(self, request):
  131         return SubMenuItemComponent(self.name, self.label, self.menu.render_component(request), icon_name=self.icon_name, classnames=self.classnames)
  132 
  133 
  134 class AdminOnlyMenuItem(MenuItem):
  135     """A MenuItem which is only shown to superusers"""
  136 
  137     def is_shown(self, request):
  138         return request.user.is_superuser
  139 
  140 
  141 admin_menu = Menu(register_hook_name='register_admin_menu_item', construct_hook_name='construct_main_menu')
  142 settings_menu = Menu(register_hook_name='register_settings_menu_item', construct_hook_name='construct_settings_menu')
  143 reports_menu = Menu(register_hook_name='register_reports_menu_item', construct_hook_name='construct_reports_menu')
  144
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/wagtail/admin/menu.py b/wagtail/admin/menu.py
  --- a/wagtail/admin/menu.py
  +++ b/wagtail/admin/menu.py
  @@ -2,11 +2,11 @@
   from django.forms.utils import flatatt
   from django.template.loader import render_to_string
   from django.utils.safestring import mark_safe
  -from django.utils.text import slugify
   
   from wagtail.admin.ui.sidebar import LinkMenuItem as LinkMenuItemComponent
   from wagtail.admin.ui.sidebar import SubMenuItem as SubMenuItemComponent
   from wagtail.core import hooks
  +from wagtail.core.utils import cautious_slugify
   
   
   class MenuItem(metaclass=MediaDefiningClass):
  @@ -17,7 +17,7 @@
           self.url = url
           self.classnames = classnames
           self.icon_name = icon_name
  -        self.name = (name or slugify(str(label)))
  +        self.name = (name or cautious_slugify(str(label)))
           self.order = order
   
           if attrs:
  
verification_info: {"golden_diff": "diff --git a/wagtail/admin/menu.py b/wagtail/admin/menu.py\n--- a/wagtail/admin/menu.py\n+++ b/wagtail/admin/menu.py\n@@ -2,11 +2,11 @@\n from django.forms.utils import flatatt\n from django.template.loader import render_to_string\n from django.utils.safestring import mark_safe\n-from django.utils.text import slugify\n \n from wagtail.admin.ui.sidebar import LinkMenuItem as LinkMenuItemComponent\n from wagtail.admin.ui.sidebar import SubMenuItem as SubMenuItemComponent\n from wagtail.core import hooks\n+from wagtail.core.utils import cautious_slugify\n \n \n class MenuItem(metaclass=MediaDefiningClass):\n@@ -17,7 +17,7 @@\n         self.url = url\n         self.classnames = classnames\n         self.icon_name = icon_name\n-        self.name = (name or slugify(str(label)))\n+        self.name = (name or cautious_slugify(str(label)))\n         self.order = order\n \n         if attrs:\n", "issue": "Wagtail 2.16 - Slim Sidebar open only settings\n### Issue Summary\r\nWhen click on any menu item with submenu pages, the settings submenu always opens. \r\n\r\n### Steps to Reproduce\r\n\r\n1. Open admin page\r\n2. Click on any menu item with a submenu \r\n3. Settings submenu always opens\r\n\r\nWhen click on the pages menu item, both submenus open. \r\n\r\n### Technical details\r\n\r\n* Python version: 3.9.9.\r\n* Django version: 3.2.12.\r\n* Wagtail version: 2.16\r\n* Browser version: firefox 96.0.3\r\n\r\n\r\n\r\n\n", "before_files": [{"content": "from django.forms import Media, MediaDefiningClass\nfrom django.forms.utils import flatatt\nfrom django.template.loader import render_to_string\nfrom django.utils.safestring import mark_safe\nfrom django.utils.text import slugify\n\nfrom wagtail.admin.ui.sidebar import LinkMenuItem as LinkMenuItemComponent\nfrom wagtail.admin.ui.sidebar import SubMenuItem as SubMenuItemComponent\nfrom wagtail.core import hooks\n\n\nclass MenuItem(metaclass=MediaDefiningClass):\n    template = 'wagtailadmin/shared/menu_item.html'\n\n    def __init__(self, label, url, name=None, classnames='', icon_name='', attrs=None, order=1000):\n        self.label = label\n        self.url = url\n        self.classnames = classnames\n        self.icon_name = icon_name\n        self.name = (name or slugify(str(label)))\n        self.order = order\n\n        if attrs:\n            self.attr_string = flatatt(attrs)\n        else:\n            self.attr_string = \"\"\n\n    def is_shown(self, request):\n        \"\"\"\n        Whether this menu item should be shown for the given request; permission\n        checks etc should go here. By default, menu items are shown all the time\n        \"\"\"\n        return True\n\n    def is_active(self, request):\n        return request.path.startswith(str(self.url))\n\n    def get_context(self, request):\n        \"\"\"Defines context for the template, overridable to use more data\"\"\"\n        return {\n            'name': self.name,\n            'url': self.url,\n            'classnames': self.classnames,\n            'icon_name': self.icon_name,\n            'attr_string': self.attr_string,\n            'label': self.label,\n            'active': self.is_active(request)\n        }\n\n    def render_html(self, request):\n        context = self.get_context(request)\n        return render_to_string(self.template, context, request=request)\n\n    def render_component(self, request):\n        return LinkMenuItemComponent(self.name, self.label, self.url, icon_name=self.icon_name, classnames=self.classnames)\n\n\nclass Menu:\n    def __init__(self, register_hook_name, construct_hook_name=None):\n        self.register_hook_name = register_hook_name\n        self.construct_hook_name = construct_hook_name\n        # _registered_menu_items will be populated on first access to the\n        # registered_menu_items property. We can't populate it in __init__ because\n        # we can't rely on all hooks modules to have been imported at the point that\n        # we create the admin_menu and settings_menu instances\n        self._registered_menu_items = None\n\n    @property\n    def registered_menu_items(self):\n        if self._registered_menu_items is None:\n            self._registered_menu_items = [fn() for fn in hooks.get_hooks(self.register_hook_name)]\n        return self._registered_menu_items\n\n    def menu_items_for_request(self, request):\n        items = [item for item in self.registered_menu_items if item.is_shown(request)]\n\n        # provide a hook for modifying the menu, if construct_hook_name has been set\n        if self.construct_hook_name:\n            for fn in hooks.get_hooks(self.construct_hook_name):\n                fn(request, items)\n\n        return items\n\n    def active_menu_items(self, request):\n        return [item for item in self.menu_items_for_request(request) if item.is_active(request)]\n\n    @property\n    def media(self):\n        media = Media()\n        for item in self.registered_menu_items:\n            media += item.media\n        return media\n\n    def render_html(self, request):\n        menu_items = self.menu_items_for_request(request)\n        rendered_menu_items = []\n        for item in sorted(menu_items, key=lambda i: i.order):\n            rendered_menu_items.append(item.render_html(request))\n        return mark_safe(''.join(rendered_menu_items))\n\n    def render_component(self, request):\n        menu_items = self.menu_items_for_request(request)\n        rendered_menu_items = []\n        for item in sorted(menu_items, key=lambda i: i.order):\n            rendered_menu_items.append(item.render_component(request))\n        return rendered_menu_items\n\n\nclass SubmenuMenuItem(MenuItem):\n    template = 'wagtailadmin/shared/menu_submenu_item.html'\n\n    \"\"\"A MenuItem which wraps an inner Menu object\"\"\"\n    def __init__(self, label, menu, **kwargs):\n        self.menu = menu\n        super().__init__(label, '#', **kwargs)\n\n    def is_shown(self, request):\n        # show the submenu if one or more of its children is shown\n        return bool(self.menu.menu_items_for_request(request))\n\n    def is_active(self, request):\n        return bool(self.menu.active_menu_items(request))\n\n    def get_context(self, request):\n        context = super().get_context(request)\n        context['menu_html'] = self.menu.render_html(request)\n        context['request'] = request\n        return context\n\n    def render_component(self, request):\n        return SubMenuItemComponent(self.name, self.label, self.menu.render_component(request), icon_name=self.icon_name, classnames=self.classnames)\n\n\nclass AdminOnlyMenuItem(MenuItem):\n    \"\"\"A MenuItem which is only shown to superusers\"\"\"\n\n    def is_shown(self, request):\n        return request.user.is_superuser\n\n\nadmin_menu = Menu(register_hook_name='register_admin_menu_item', construct_hook_name='construct_main_menu')\nsettings_menu = Menu(register_hook_name='register_settings_menu_item', construct_hook_name='construct_settings_menu')\nreports_menu = Menu(register_hook_name='register_reports_menu_item', construct_hook_name='construct_reports_menu')\n", "path": "wagtail/admin/menu.py"}], "after_files": [{"content": "from django.forms import Media, MediaDefiningClass\nfrom django.forms.utils import flatatt\nfrom django.template.loader import render_to_string\nfrom django.utils.safestring import mark_safe\n\nfrom wagtail.admin.ui.sidebar import LinkMenuItem as LinkMenuItemComponent\nfrom wagtail.admin.ui.sidebar import SubMenuItem as SubMenuItemComponent\nfrom wagtail.core import hooks\nfrom wagtail.core.utils import cautious_slugify\n\n\nclass MenuItem(metaclass=MediaDefiningClass):\n    template = 'wagtailadmin/shared/menu_item.html'\n\n    def __init__(self, label, url, name=None, classnames='', icon_name='', attrs=None, order=1000):\n        self.label = label\n        self.url = url\n        self.classnames = classnames\n        self.icon_name = icon_name\n        self.name = (name or cautious_slugify(str(label)))\n        self.order = order\n\n        if attrs:\n            self.attr_string = flatatt(attrs)\n        else:\n            self.attr_string = \"\"\n\n    def is_shown(self, request):\n        \"\"\"\n        Whether this menu item should be shown for the given request; permission\n        checks etc should go here. By default, menu items are shown all the time\n        \"\"\"\n        return True\n\n    def is_active(self, request):\n        return request.path.startswith(str(self.url))\n\n    def get_context(self, request):\n        \"\"\"Defines context for the template, overridable to use more data\"\"\"\n        return {\n            'name': self.name,\n            'url': self.url,\n            'classnames': self.classnames,\n            'icon_name': self.icon_name,\n            'attr_string': self.attr_string,\n            'label': self.label,\n            'active': self.is_active(request)\n        }\n\n    def render_html(self, request):\n        context = self.get_context(request)\n        return render_to_string(self.template, context, request=request)\n\n    def render_component(self, request):\n        return LinkMenuItemComponent(self.name, self.label, self.url, icon_name=self.icon_name, classnames=self.classnames)\n\n\nclass Menu:\n    def __init__(self, register_hook_name, construct_hook_name=None):\n        self.register_hook_name = register_hook_name\n        self.construct_hook_name = construct_hook_name\n        # _registered_menu_items will be populated on first access to the\n        # registered_menu_items property. We can't populate it in __init__ because\n        # we can't rely on all hooks modules to have been imported at the point that\n        # we create the admin_menu and settings_menu instances\n        self._registered_menu_items = None\n\n    @property\n    def registered_menu_items(self):\n        if self._registered_menu_items is None:\n            self._registered_menu_items = [fn() for fn in hooks.get_hooks(self.register_hook_name)]\n        return self._registered_menu_items\n\n    def menu_items_for_request(self, request):\n        items = [item for item in self.registered_menu_items if item.is_shown(request)]\n\n        # provide a hook for modifying the menu, if construct_hook_name has been set\n        if self.construct_hook_name:\n            for fn in hooks.get_hooks(self.construct_hook_name):\n                fn(request, items)\n\n        return items\n\n    def active_menu_items(self, request):\n        return [item for item in self.menu_items_for_request(request) if item.is_active(request)]\n\n    @property\n    def media(self):\n        media = Media()\n        for item in self.registered_menu_items:\n            media += item.media\n        return media\n\n    def render_html(self, request):\n        menu_items = self.menu_items_for_request(request)\n        rendered_menu_items = []\n        for item in sorted(menu_items, key=lambda i: i.order):\n            rendered_menu_items.append(item.render_html(request))\n        return mark_safe(''.join(rendered_menu_items))\n\n    def render_component(self, request):\n        menu_items = self.menu_items_for_request(request)\n        rendered_menu_items = []\n        for item in sorted(menu_items, key=lambda i: i.order):\n            rendered_menu_items.append(item.render_component(request))\n        return rendered_menu_items\n\n\nclass SubmenuMenuItem(MenuItem):\n    template = 'wagtailadmin/shared/menu_submenu_item.html'\n\n    \"\"\"A MenuItem which wraps an inner Menu object\"\"\"\n    def __init__(self, label, menu, **kwargs):\n        self.menu = menu\n        super().__init__(label, '#', **kwargs)\n\n    def is_shown(self, request):\n        # show the submenu if one or more of its children is shown\n        return bool(self.menu.menu_items_for_request(request))\n\n    def is_active(self, request):\n        return bool(self.menu.active_menu_items(request))\n\n    def get_context(self, request):\n        context = super().get_context(request)\n        context['menu_html'] = self.menu.render_html(request)\n        context['request'] = request\n        return context\n\n    def render_component(self, request):\n        return SubMenuItemComponent(self.name, self.label, self.menu.render_component(request), icon_name=self.icon_name, classnames=self.classnames)\n\n\nclass AdminOnlyMenuItem(MenuItem):\n    \"\"\"A MenuItem which is only shown to superusers\"\"\"\n\n    def is_shown(self, request):\n        return request.user.is_superuser\n\n\nadmin_menu = Menu(register_hook_name='register_admin_menu_item', construct_hook_name='construct_main_menu')\nsettings_menu = Menu(register_hook_name='register_settings_menu_item', construct_hook_name='construct_settings_menu')\nreports_menu = Menu(register_hook_name='register_reports_menu_item', construct_hook_name='construct_reports_menu')\n", "path": "wagtail/admin/menu.py"}]}