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?
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 %}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With