Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 881
shacker Avatar asked Sep 08 '25 16:09

shacker


2 Answers

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 %}
like image 126
shacker Avatar answered Sep 10 '25 05:09

shacker


Maybe this can be of any help.

@route(_(r'^detail/(?P<activity_slug>[-\w]+)/$'))
def show_activity(self, request, activity_slug):
    activity_model_class = self.activity_model_class
    if not activity_model_class:
        raise Http404('No activity model.')
    else:
        queryset = self.get_activity(activity_slug)
        try:
            activity = queryset.get()
        except activity_model_class.DoesNotExist:
            raise Http404('activity not found')
        else:
            self.current_url = self.get_url(
                'show_activity',
                kwargs = {'activity_slug': activity_slug}
            )

Now the routable page has a current_url

def get_context(self, request, *args, **kwargs):
        context = super().get_context(request)
        context['current_url']= self.current_url
    return context

And now it’s in the context.

like image 29
Robert Avatar answered Sep 10 '25 07:09

Robert