diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 5a0da7afe0..aeb04a69df 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -35,6 +35,7 @@ Changelog
* Fix: "X minutes ago" timestamps are now marked for translation (Janneke Janssen, Matt Westcott)
* Fix: Avoid indexing unsaved field content on `save(update_fields=[...])` operations (Matt Westcott)
* Fix: Corrected ordering of arguments passed to ModelAdmin `get_extra_class_names_for_field_col` / `get_extra_attrs_for_field_col` methods (Andy Babic)
+ * `pageurl` / `slugurl` tags now function when request.site is not available (Tobias McNulty, Matt Westcott)
1.8.1 (26.01.2017)
diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst
index 2d322fffe0..b8b419057d 100644
--- a/CONTRIBUTORS.rst
+++ b/CONTRIBUTORS.rst
@@ -210,6 +210,7 @@ Contributors
* Martey Dodoo
* David Ray
* Alasdair Nicol
+* Tobias McNulty
* Vorlif
* Kjartan Sverrisson
* LB (Ben Johnston)
diff --git a/docs/releases/1.9.rst b/docs/releases/1.9.rst
index 1d9b2ac75e..8bbef5ba03 100644
--- a/docs/releases/1.9.rst
+++ b/docs/releases/1.9.rst
@@ -64,6 +64,7 @@ Bug fixes
* "X minutes ago" timestamps are now marked for translation (Janneke Janssen, Matt Westcott)
* Avoid indexing unsaved field content on `save(update_fields=[...])` operations (Matt Westcott)
* Corrected ordering of arguments passed to ModelAdmin ``get_extra_class_names_for_field_col`` / ``get_extra_attrs_for_field_col`` methods (Andy Babic)
+ * ``pageurl`` / ``slugurl`` tags now function when request.site is not available (Tobias McNulty, Matt Westcott)
Upgrade considerations
diff --git a/wagtail/wagtailcore/templatetags/wagtailcore_tags.py b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py
index 13dac2e6e2..291153c885 100644
--- a/wagtail/wagtailcore/templatetags/wagtailcore_tags.py
+++ b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py
@@ -18,7 +18,13 @@ def pageurl(context, page):
Outputs a page's URL as relative (/foo/bar/) if it's within the same site as the
current page, or absolute (http://example.com/foo/bar/) if not.
"""
- return page.relative_url(context['request'].site)
+ try:
+ current_site = context['request'].site
+ except (KeyError, AttributeError):
+ # request.site not available in the current context; fall back on page.url
+ return page.url
+
+ return page.relative_url(current_site)
@register.simple_tag(takes_context=True)
@@ -26,11 +32,17 @@ def slugurl(context, slug):
"""Returns the URL for the page that has the given slug."""
page = Page.objects.filter(slug=slug).first()
- if page:
- return page.relative_url(context['request'].site)
- else:
+ if not page:
return None
+ try:
+ current_site = context['request'].site
+ except (KeyError, AttributeError):
+ # request.site not available in the current context; fall back on page.url
+ return page.url
+
+ return page.relative_url(current_site)
+
@register.simple_tag
def wagtail_version():
diff --git a/wagtail/wagtailcore/tests/tests.py b/wagtail/wagtailcore/tests/tests.py
index fcbce0b095..036ee3bf82 100644
--- a/wagtail/wagtailcore/tests/tests.py
+++ b/wagtail/wagtailcore/tests/tests.py
@@ -1,6 +1,8 @@
from __future__ import absolute_import, unicode_literals
+from django import template
from django.core.cache import cache
+from django.http import HttpRequest
from django.test import TestCase
from django.utils.safestring import SafeText
@@ -25,6 +27,29 @@ class TestPageUrlTags(TestCase):
self.assertContains(response,
'Back to events index')
+ def test_pageurl_without_request_in_context(self):
+ page = Page.objects.get(url_path='/home/events/')
+ tpl = template.Template('''{% load wagtailcore_tags %}{{ page.title }}''')
+
+ # no 'request' object in context
+ result = tpl.render(template.Context({'page': page}))
+ self.assertIn('Events', result)
+
+ # 'request' object in context, but no 'site' attribute
+ result = tpl.render(template.Context({'page': page, 'request': HttpRequest()}))
+ self.assertIn('Events', result)
+
+ def test_slugurl_without_request_in_context(self):
+ tpl = template.Template('''{% load wagtailcore_tags %}Events''')
+
+ # no 'request' object in context
+ result = tpl.render(template.Context({}))
+ self.assertIn('Events', result)
+
+ # 'request' object in context, but no 'site' attribute
+ result = tpl.render(template.Context({'request': HttpRequest()}))
+ self.assertIn('Events', result)
+
class TestSiteRootPathsCache(TestCase):
fixtures = ['test.json']