Search code examples
djangobreadcrumbswagtail

RoutablePageMixin and breadcrumbs


A standard Wagtail breadcrumb system like this works perfectly if all of your pages are in a tree (parents/children):

{% block main %}
    {% if self.get_ancestors|length > 1 %}
        <ul class="breadcrumb">
            {% for page in self.get_ancestors %}
                {% if page.is_root == False and page.url != '/' %}
                    <li><a href="{% pageurl page %}">{{ page.title }}</a></li>
                {% endif %}
            {% endfor %}
            <li class="active">{{ self.title }}</li>
        </ul>
    {% endif %}
{% endblock main %}

But it falls down if some of your sub-pages are not actual children, but instead use RoutablePageMixin. Because the routable pages are really different instances of the parent, the breadcrumb trail stops short of making it down to the routable page.

I thought I could add some extra info to the context to detect the situation and special-case it, but all of the WT URL methods return the URL of the "parent" page (i.e. the actual instance), and besides there is no programmatic "title" that could be used in the breadcrumb.

What's the best way to have a breadcrumb system that works equally well for child pages and routable pages?


Solution

  • Answering my own question (Thanks Robert for the hint). In the route definition in the model, add something like:

    ctx['routed_title'] = 'Staff'
    

    Then modify the breadcrumb example above like this (check for existence of the new element on context and append to breadcrumbs):

    {% block main %}
        {% if self.get_ancestors|length > 1 %}
            <ul class="breadcrumb">
                {% for page in self.get_ancestors %}
                    {% if page.is_root == False and page.url != '/' %}
                        <li><a href="{% pageurl page %}">{{ page.title }}</a></li>
                    {% endif %}
                {% endfor %}
                {# If this is a routable, add non-parent/child link from context #}
                {% if routed_title %}
                    <li><a href="{% pageurl page %}">{{ page.title }}</a></li>
                    <li class="active">{{ routed_title }}</li>
                {% else %}
                    <li class="active">{{ self.title }}</li>
                {% endif %}
            </ul>
        {% endif %}
    {% endblock main %}