Stuart Axon
Stuart Axon

Reputation: 1874

wagtail - menus how to include homepage as well?

The wagtail bakerydemo has a nice set of menus, I'd like to include the home page as well.

Wagtail expects pages to be children of home, which is at the root, while the menus follow the hierachy -

So if I change top_menu in navigation_tags

https://github.com/wagtail/bakerydemo/blob/master/bakerydemo/base/templatetags/navigation_tags.py#L42

to get menu items like this:

menuitems = (parent.get_siblings()).live().in_menu()

The homepage shows up, but the menus treat it as an anscestor, not an equal.

Any idea how I can change this so that 'home' is the same as its immediate children ?

Upvotes: 0

Views: 591

Answers (1)

LB Ben Johnston
LB Ben Johnston

Reputation: 5186

A way to achieve this would be to prepend a new menuitem which will be the homepage.

Assuming you have only used this top_menu tag for the main menu, you can also assume that the parent passed into the tag will always be the site_root, which in turn is the home page.

The only changes are after the for loop of menuitems and before the returning of the template context.

Example: Updated navigation_tags.py

    @register.inclusion_tag('tags/top_menu.html', takes_context=True)
    def top_menu(context, parent, calling_page=None):
        menuitems = parent.get_children().live().in_menu()
        for menuitem in menuitems:
            menuitem.show_dropdown = has_menu_children(menuitem)
            # We don't directly check if calling_page is None since the template
            # engine can pass an empty string to calling_page
            # if the variable passed as calling_page does not exist.
            menuitem.active = (calling_page.url.startswith(menuitem.url)
                               if calling_page else False)
        # assumes menu is only called with parent=site_root and is live + ignores `in_menu` field on homepage
        home_page = parent
        home_page.show_dropdown = False
        home_page.active = (
            # must match urls exactly as all URLs will start with homepage URL
            (calling_page.url == home_page.url) if calling_page else False
        )
        # append the home page (site_root) to the start of the menuitems
        # menuitems is actually a queryset so we need to force it into a list
        menuitems = [home_page] + list(menuitems)
        return {
            'calling_page': calling_page,
            'menuitems': menuitems,
            # required by the pageurl tag that we want to use within this template
            'request': context['request'],
        }

Note: menuitems is actually a queryset not a list, which means to append an item to it we need to force it to become a list. This may not be the most performant way to do this, you could adjust the queryset query to always include the homepage but this gets the job done.

Upvotes: 2

Related Questions