Skip to content
Advertisement

Wagtail/Django – How to find the template name of wagtail root home page?

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.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement