added default index_route for RoutablePageMixin

RoutablePageMixin has a default index_route method that is decorated
with `@route(r'^$')`. This way, including RoutablePageMixin doesn't
force you to re-enable the default functionality you would expect from a
Page anyways.
index_route behaves exactly like a standard Wagtail Page.
To override the default behaviour, one can simply override the route by
decorating another function with r'^$'.

(as disussed in issue #2866)
This commit is contained in:
Andreas Nüßlein 2017-02-07 17:20:19 +01:00 committed by Karl Hobley
parent e008838d53
commit 39bca11283
6 changed files with 33 additions and 21 deletions

View file

@ -9,6 +9,7 @@
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).
Per default a route for ``r'^$'`` exists, which serves the content exactly like a regular ``Page`` would. It can be overridden by using ``@route(r'^$')`` on any other method of the inheriting class.
Installation
@ -41,7 +42,7 @@ Here's an example of an ``EventPage`` with three views:
class EventPage(RoutablePageMixin, Page):
...
@route(r'^$')
@route(r'^$') # will override the default Page serving mechanism
def current_events(self, request):
"""
View function for the current events page

View file

@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
from django.conf.urls import url
from django.core.urlresolvers import RegexURLResolver
from django.http import Http404
from django.template.response import TemplateResponse
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.url_routing import RouteResult
@ -35,6 +36,16 @@ class RoutablePageMixin(object):
This class can be mixed in to a Page model, allowing extra routes to be
added to it.
"""
@route(r'^$')
def index_route(self, request, *args, **kwargs):
request.is_preview = getattr(request, 'is_preview', False)
return TemplateResponse(
request,
self.get_template(request, *args, **kwargs),
self.get_context(request, *args, **kwargs)
)
@classmethod
def get_subpage_urls(cls):
routes = []
@ -45,7 +56,7 @@ class RoutablePageMixin(object):
return tuple([
route[0]
for route in sorted(routes, key=lambda route: route[1])
for route in reversed(sorted(routes, key=lambda route: route[1]))
])
@classmethod

View file

@ -5,7 +5,7 @@ from django.test import RequestFactory, TestCase
from wagtail.contrib.wagtailroutablepage.templatetags.wagtailroutablepage_tags import \
routablepageurl
from wagtail.tests.routablepage.models import RoutablePageTest, RoutablePageWithoutIndexRouteTest
from wagtail.tests.routablepage.models import RoutablePageTest, RoutablePageWithOverriddenIndexRouteTest
from wagtail.wagtailcore.models import Page, Site
@ -19,10 +19,10 @@ class TestRoutablePage(TestCase):
live=True,
))
def test_resolve_main_view(self):
def test_resolve_index_route_view(self):
view, args, kwargs = self.routable_page.resolve_subpage('/')
self.assertEqual(view, self.routable_page.main)
self.assertEqual(view, self.routable_page.index_route)
self.assertEqual(args, ())
self.assertEqual(kwargs, {})
@ -54,8 +54,8 @@ class TestRoutablePage(TestCase):
self.assertEqual(args, ())
self.assertEqual(kwargs, {})
def test_reverse_main_view(self):
url = self.routable_page.reverse_subpage('main')
def test_reverse_index_route_view(self):
url = self.routable_page.reverse_subpage('index_route')
self.assertEqual(url, '')
@ -88,20 +88,21 @@ class TestRoutablePage(TestCase):
self.assertEqual(url, 'external-no-arg/')
def test_get_main_view(self):
def test_get_index_route_view(self):
response = self.client.get(self.routable_page.url)
self.assertContains(response, "MAIN VIEW")
self.assertContains(response, "DEFAULT PAGE TEMPLATE")
def test_get_routable_page_without_index_route(self):
def test_get_routable_page_with_overridden_index_route(self):
page = self.home_page.add_child(
instance=RoutablePageWithoutIndexRouteTest(
title="Routable Page without index",
instance=RoutablePageWithOverriddenIndexRouteTest(
title="Routable Page with overridden index",
live=True
)
)
response = self.client.get(page.url)
self.assertContains(response, "DEFAULT PAGE TEMPLATE")
self.assertContains(response, "OVERRIDDEN INDEX ROUTE")
self.assertNotContains(response, "DEFAULT PAGE TEMPLATE")
def test_get_archive_by_year_view(self):
response = self.client.get(self.routable_page.url + 'archive/year/2014/')
@ -156,9 +157,9 @@ class TestRoutablePageTemplateTag(TestCase):
self.request.site = Site.find_for_request(self.request)
self.context = {'request': self.request}
def test_templatetag_reverse_main_view(self):
def test_templatetag_reverse_index_route(self):
url = routablepageurl(self.context, self.routable_page,
'main')
'index_route')
self.assertEqual(url, self.routable_page.url)
def test_templatetag_reverse_archive_by_year_view(self):

View file

@ -16,7 +16,7 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
name='RoutablePageWithoutIndexRouteTest',
name='RoutablePageWithOverriddenIndexRouteTest',
fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')),
],

View file

@ -10,9 +10,6 @@ def routable_page_external_view(request, arg="ARG NOT SET"):
class RoutablePageTest(RoutablePage):
@route(r'^$')
def main(self, request):
return HttpResponse("MAIN VIEW")
@route(r'^archive/year/(\d+)/$')
def archive_by_year(self, request, year):
@ -34,5 +31,7 @@ class RoutablePageTest(RoutablePage):
pass
class RoutablePageWithoutIndexRouteTest(RoutablePage):
pass
class RoutablePageWithOverriddenIndexRouteTest(RoutablePage):
@route(r'^$')
def main(self, request):
return HttpResponse("OVERRIDDEN INDEX ROUTE")