RoutablePageMixin

The RoutablePageMixin mixin provides a convenient way for a page to respond on multiple sub-URLs with different views. For example, a blog section on a site might provide several different types of index page at URLs like /blog/2013/06/, /blog/authors/bob/, /blog/tagged/python/, all served by the same page instance.

A Page using RoutablePageMixin exists within the page tree like any other page, but URL paths underneath it are checked against a list of patterns. If none of the patterns match, control is passed to subpages as usual (or failing that, a 404 error is thrown).

The basics

To use RoutablePageMixin, you need to make your class inherit from both wagtail.contrib.wagtailroutablepage.models.RoutablePageMixin and wagtail.wagtailcore.models.Page, then define some view methods and decorate them with wagtail.contrib.wagtailroutablepage.models.route.

Here’s an example of an EventPage with three views:

from wagtail.wagtailcore.models import Page
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route


class EventPage(RoutablePageMixin, Page):
    ...

    @route(r'^$')
    def current_events(self, request):
        """
        View function for the current events page
        """
        ...

    @route(r'^past/$')
    def past_events(self, request):
        """
        View function for the past events page
        """
        ...

    # Multiple routes!
    @route(r'^year/(\d+)/$')
    @route(r'^year/current/$')
    def events_for_year(self, request, year=None):
        """
        View function for the events for year page
        """
        ...

Reversing URLs

RoutablePageMixin adds a reverse_subpage() method to your page model which you can use for reversing URLs. For example:

# The URL name defaults to the view method name.
>>> event_page.reverse_subpage('events_for_year', args=(2015, ))
'year/2015/'

This method only returns the part of the URL within the page. To get the full URL, you must append it to the values of either the url or the full_url attribute on your page:

>>> event_page.url + event_page.reverse_subpage('events_for_year', args=(2015, ))
'/events/year/2015/'

>>> event_page.full_url + event_page.reverse_subpage('events_for_year', args=(2015, ))
'http://example.com/events/year/2015/'

Changing route names

The route name defaults to the name of the view. You can override this name with the name keyword argument on @route:

from wagtail.wagtailcore.models import Page
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route


class EventPage(RoutablePageMixin, Page):
    ...

    @route(r'^year/(\d+)/$', name='year')
    def events_for_year(self, request, year):
        """
        View function for the events for year page
        """
        ...
>>> event_page.reverse_subpage('year', args=(2015, ))
'/events/year/2015/'

The RoutablePageMixin class

class wagtail.contrib.wagtailroutablepage.models.RoutablePageMixin

This class can be mixed in to a Page model, allowing extra routes to be added to it.

classmethod get_subpage_urls()
resolve_subpage(path)

This method takes a URL path and finds the view to call.

Example:

view, args, kwargs = page.resolve_subpage('/past/')
response = view(request, *args, **kwargs)
reverse_subpage(name, args=None, kwargs=None)

This method takes a route name/arguments and returns a URL path.

Example:

url = page.url + page.reverse_subpage('events_for_year', kwargs={'year': '2014'})

The routablepageurl template tag

wagtail.contrib.wagtailroutablepage.templatetags.wagtailroutablepage_tags.routablepageurl(context, page, url_name, *args, **kwargs)

routablepageurl is similar to pageurl, but works with RoutablePages. It behaves like a hybrid between the built-in reverse, and pageurl from Wagtail.

page is the RoutablePage that URLs will be generated from.

url_name is a URL name defined in page.subpage_urls.

Positional arguments and keyword arguments should be passed as normal positional arguments and keyword arguments.

Example:

{% load wagtailroutablepage_tags %}

{% routablepageurl page "feed" %}
{% routablepageurl page "archive" 2014 08 14 %}
{% routablepageurl page "food" foo="bar" baz="quux" %}