Browse Source

Add `{% fullpageurl %}` for resolving absolute URLs to pages

Jake Howard 2 years ago
parent
commit
0f209ee848

+ 1 - 0
CHANGELOG.txt

@@ -19,6 +19,7 @@ Changelog
  * Snippet models extending `DraftStateMixin` now automatically define a "Publish" permission type (Sage Abdullah)
  * Users now remain on the edit page after saving a snippet as draft (Sage Abdullah)
  * Base project template now populates the meta description tag from the search description field (Aman Pandey)
+ * Create `{% fullpageurl %}` for getting the absolute URL of a page (Jake Howard)
  * Fix: Make sure workflow timeline icons are visible in high-contrast mode (Loveth Omokaro)
  * Fix: Ensure authentication forms (login, password reset) have a visible border in Windows high-contrast mode (Loveth Omokaro)
  * Fix: Ensure visual consistency between buttons and links as buttons in Windows high-contrast mode (Albina Starykova)

+ 1 - 1
docs/advanced_topics/performance.md

@@ -62,7 +62,7 @@ To fully resolve the URL of a page, Wagtail requires information from a few diff
 
 The methods used to get the URL of a `Page` such as `Page.get_url` and `Page.get_full_url` optionally accept extra arguments for `request` and `current_site`. Passing these arguments enable much of underlying site-level URL information to be reused for the current request. In situations such as navigation menu generation, plus any links that appear in page content, providing `request` or `current_site` can result in a drastic reduction in the number of cache or database queries your site will generate for a given page load.
 
-When using the [`{% pageurl %}`](page_urls) template tag, the request is automatically passed in, so no further optimisation is needed.
+When using the [`{% pageurl %}`](pageurl_tag) or [`{% fullpageurl %}`](fullpageurl_tag) template tags, the request is automatically passed in, so no further optimisation is needed.
 
 ## Search
 

+ 1 - 1
docs/topics/pages.md

@@ -179,7 +179,7 @@ class LandingPage(Page):
 
 ### Page URLs
 
-The most common method of retrieving page URLs is by using the `{% pageurl %}` template tag. Since it's called from a template, `pageurl` automatically includes the optimizations mentioned below. For more information, see [pageurl](pageurl_tag).
+The most common method of retrieving page URLs is by using the [`{% pageurl %}`](pageurl_tag) or [`{% fullpageurl %}`](fullpageurl_tag) template tags. Since it's called from a template, these automatically includes the optimizations mentioned below.
 
 Page models also include several low-level methods for overriding or accessing page URLs.
 

+ 14 - 0
docs/topics/writing_templates.md

@@ -173,6 +173,20 @@ A `fallback` keyword argument can be provided - this can be a URL string, a name
 {% endfor %}
 ```
 
+(fullpageurl_tag)=
+
+### `fullpageurl`
+
+Takes a Page object and returns its absolute (`http://example.com/foo/bar/`).
+
+```html+django
+{% load wagtailcore_tags %}
+...
+<meta property="og:url" content="{% fullpageurl page %}" />
+```
+
+Much like `pageurl`, a `fallback` keyword argument may be provided.
+
 (slugurl_tag)=
 
 ### `slugurl`

+ 18 - 0
wagtail/templatetags/wagtailcore_tags.py

@@ -29,6 +29,24 @@ def pageurl(context, page, fallback=None):
     return page.get_url(request=context.get("request"))
 
 
+@register.simple_tag(takes_context=True)
+def fullpageurl(context, page, fallback=None):
+    """
+    Outputs a page's absolute URL (http://example.com/foo/bar/)
+    If kwargs contains a fallback view name and page is None, the fallback view url will be returned.
+    """
+    if page is None and fallback:
+        fallback_url = resolve_url(fallback)
+        if fallback_url and "request" in context and fallback_url[0] == "/":
+            fallback_url = context["request"].build_absolute_uri(fallback_url)
+        return fallback_url
+
+    if not isinstance(page, Page):
+        raise ValueError("fullpageurl tag expected a Page object, got %r" % page)
+
+    return page.get_full_url(request=context.get("request"))
+
+
 @register.simple_tag(takes_context=True)
 def slugurl(context, slug):
     """

+ 27 - 0
wagtail/tests/tests.py

@@ -196,6 +196,33 @@ class TestPageUrlTags(TestCase):
         result = slugurl(template.Context({"request": request}), "events")
         self.assertEqual(result, "/events/")
 
+    def test_fullpageurl(self):
+        tpl = template.Template(
+            """{% load wagtailcore_tags %}<a href="{% fullpageurl page %}">Fallback</a>"""
+        )
+        page = Page.objects.get(url_path="/home/events/")
+        with self.assertNumQueries(7):
+            result = tpl.render(template.Context({"page": page}))
+        self.assertIn('<a href="http://localhost/events/">Fallback</a>', result)
+
+    def test_fullpageurl_with_named_url_fallback(self):
+        tpl = template.Template(
+            """{% load wagtailcore_tags %}<a href="{% fullpageurl page fallback='fallback' %}">Fallback</a>"""
+        )
+        with self.assertNumQueries(0):
+            result = tpl.render(template.Context({"page": None}))
+        self.assertIn('<a href="/fallback/">Fallback</a>', result)
+
+    def test_fullpageurl_with_absolute_fallback(self):
+        tpl = template.Template(
+            """{% load wagtailcore_tags %}<a href="{% fullpageurl page fallback='fallback' %}">Fallback</a>"""
+        )
+        with self.assertNumQueries(0):
+            result = tpl.render(
+                template.Context({"page": None, "request": get_dummy_request()})
+            )
+        self.assertIn('<a href="http://localhost/fallback/">Fallback</a>', result)
+
 
 class TestWagtailSiteTag(TestCase):
     fixtures = ["test.json"]