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.