I have a root home page made using the default model that comes out of the box with Wagtail. I’m currently trying to create a navbar header that maps out children pages in the following manner:
{% for menu_page in home_page.get_children.live.in_menu %}
The problem here is, I’m using the wrong tag. Above I use home_page
, but that does not seem to work.
I am able to use:
{% for menu_page in page.get_children.live.in_menu %}
Which then lists out the menu_pages
, but this does not work for a navbar because it won’t always select children pages from the root, due to the general page
tag. Any ideas on how I can locate the actual template or page name before adding the: page.get_children.live.in_menu
.
To re-iterate, I am using the out of the box home page model:
from wagtail.core.models import Page class HomePage(Page): pass
The title of the root page is called Home and the type is Home Page
Thanks for any possible help.
Advertisement
Answer
create a templatetag say nav_tags.py
from django import template from wagtail.core.models import Page, Site register = template.Library() @register.simple_tag(takes_context=True) def get_site_root(context): # This returns a core.Page. The main menu needs to have the site.root_page # defined else will return an object attribute error ('str' object has no # attribute 'get_children') return Site.find_for_request(context['request']).root_page def has_menu_children(page): # This is used by the top_menu property # get_children is a Treebeard API thing # https://tabo.pe/projects/django-treebeard/docs/4.0.1/api.html return page.get_children().live().in_menu().exists() def has_children(page): # Generically allow index pages to list their children return page.get_children().live().exists() def is_active(page, current_page): # To give us active state on main navigation return (current_page.url_path.startswith(page.url_path) if current_page else False) # Retrieves the top menu items - the immediate children of the parent page # The has_menu_children method is necessary because the Foundation menu requires # a dropdown class to be applied to a parent @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_path.startswith(menuitem.url_path) if calling_page else False) return { 'calling_page': calling_page, 'menuitems': menuitems, # required by the pageurl tag that we want to use within this template 'request': context['request'], } # Retrieves the children of the top menu items for the drop downs @register.inclusion_tag('tags/top_menu_children.html', takes_context=True) def top_menu_children(context, parent, calling_page=None): menuitems_children = parent.get_children() menuitems_children = menuitems_children.live().in_menu() for menuitem in menuitems_children: menuitem.has_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_path.startswith(menuitem.url_path) if calling_page else False) menuitem.children = menuitem.get_children().live().in_menu() return { 'parent': parent, 'menuitems_children': menuitems_children, 'request': context['request'], }
in the templates in can do so top_menu.html
{% load navigation_tags wagtailcore_tags %} {% get_site_root as site_root %} {% for menuitem in menuitems %} <li class="presentation {{ menuitem.title|lower|cut:" " }}{% if menuitem.active %} active{% endif %}{% if menuitem.show_dropdown %} has-submenu{% endif %}"> {% if menuitem.show_dropdown %} <a href="{% pageurl menuitem %}" class="allow-toggle">{{ menuitem.title }} <span><a class="caret-custom dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a></span></a> {% top_menu_children parent=menuitem %} {# Used to display child menu items #} {% else %} <a href="{% pageurl menuitem %}" role="menuitem">{{ menuitem.title }}</a> {% endif %} </li> {% endfor %}
And so for top_menu_children.html
{% load navigation_tags wagtailcore_tags %} <ul class="dropdown-menu" role="menu"> {% for child in menuitems_children %} <li><a href="{% pageurl child %}" role="menuitem">{{ child.title }}</a></li> {% endfor %} </ul>
you check from here wagtailbakerydemo hope that was helpful.