Wagtailmenus 2.3.0 release notes

What’s new?

Introducing the AbstractLinkPage model!

The newly added AbstractLinkPage model can be easily sub-classed and used in projects to create ‘link pages’ that act in a similar fashion to menu items when appearing in menus, but can be placed in any part of the page tree.

Find out more about this feature

Introducing the MenuPageMixin model!

Most of the functionality from MenuPage model has been abstracted out to a MenuPageMixin model, that can more easily be mixed in to existing page type models.

All Menu classes are now ‘request aware’

A new set_request() method on all Menu classes is used to set a request attribute on the Menu instance, immediately after initialisation, allowing you to referencing self.request from most methods to access the current HttpRequest object

Added get_base_page_queryset() method to all Menu classes

That can be overridden to change the base QuerySet used when identifying pages to be included in a menu when rendering. For example developers could use self.request.user to only ever include pages that the current user has some permissions for.

Overridable menu classes for section_menu and children_menu tags

Added the WAGTAILMENUS_SECTION_MENU_CLASS_PATH setting, which can be used to override the Menu class used when using the {% section_menu %} tag.

Added the WAGTAILMENUS_CHILDREN_MENU_CLASS_PATH setting, which can be used to override the Menu class used when using the {% children_menu %} tag.

Other minor changes

  • Added wagtail 1.10 and django 1.11 test environments to tox

  • Renamed test_frontend.py to test_menu_rendering.py

  • In situations where request.site hasn’t been set by wagtail’s SiteMiddleware, the wagtailmenus context processor will now use the default site to generate menus with.

  • Updated AbstractMenuItem.clean() to only ever return field-specific validation errors, because Wagtail doesn’t render non-field errors for related models added to the editor interface using InlinePanel.

  • Refactored runtest.py to accept a deprecation argument that can be used to surface deprecation warnings that arise when running tests.

  • Added Russian translations (submitted by Alex @einsfr).

Upgrade considerations

Several methods on the MenuPage model have been updated to accept a request parameter. If you’re upgrading to version 2.3.0 from a previous version, it’s not necessary to make any changes immediately in order for wagtailmenus to work, but if you’re using the MenuPage class in your project, and are overriding any of the following methods:

  • modify_submenu_items()

  • has_submenu_items()

  • get_repeated_menu_item()

Then you should think about updating the signatures of those methods to accept the new argument and pass it through when calling super(). See the following code for an example:

from wagtailmenus.models import MenuPage


class ContactPage(MenuPage):
    ...

    def modify_submenu_items(
        self, menu_items, current_page, current_ancestor_ids,
        current_site, allow_repeating_parents, apply_active_classes,
        original_menu_tag, menu_instance, request
    ):
        # Apply default modifications first of all
        menu_items = super(ContactPage, self).modify_submenu_items(
            menu_items, current_page, current_ancestor_ids, current_site, allow_repeating_parents, apply_active_classes, original_menu_tag,
            menu_instance, request)
        """
        If rendering a 'main_menu', add some additional menu items to the end
        of the list that link to various anchored sections on the same page
        """
        if original_menu_tag == 'main_menu':
            base_url = self.relative_url(current_site)
            """
            Additional menu items can be objects with the necessary attributes,
            or simple dictionaries. `href` is used for the link URL, and `text`
            is the text displayed for each link. Below, I've also used
            `active_class` to add some additional CSS classes to these items,
            so that I can target them with additional CSS
            """
            menu_items.extend((
                {
                    'text': 'Get support',
                    'href': base_url + '#support',
                    'active_class': 'support',
                },
                {
                    'text': 'Speak to someone',
                    'href': base_url + '#call',
                    'active_class': 'call',
                },
                {
                    'text': 'Map & directions',
                    'href': base_url + '#map',
                    'active_class': 'map',
                },
            ))
        return menu_items

    def has_submenu_items(
        self, current_page, allow_repeating_parents, original_menu_tag,
        menu_instance, request
    ):
        """
        Because `modify_submenu_items` is being used to add additional menu
        items, we need to indicate in menu templates that `ContactPage` objects
        do have submenu items in main menus, even if they don't have children
        pages.
        """
        if original_menu_tag == 'main_menu':
            return True
        return super(ContactPage, self).has_submenu_items(
            current_page, allow_repeating_parents, original_menu_tag,
            menu_instance, request)

If you choose NOT to update your versions of those methods to accept the request keyword argument, you will continue to see deprecation warnings until version 2.5.0, when it will be a requirement, and your existing code will no longer work.