Link to specific page in Wagtail CMS
Asked Answered
V

2

11

In Wagtail CMS I don't know how to construct a link to a specific page. I want a (fixed, not authored) link in the templates from my BlogIndexPage to my BlogIndexArchivePage and vice versa. In the official docs pageurl looks promising:

{% load wagtailcore_tags %}
...
<a href="{% pageurl self.blog_page %}">

but I don't understand the notation blog_page, but the page-classes are named like BlogPage or BlogIndexPage. Did I have to define the page I would link to in my models.py - and if so: how?

Varicose answered 1/8, 2015 at 21:1 Comment(0)
C
22

Before I give the detailed answer, I'll make a simple suggestion: assuming you've already given your blog index and blog archive pages sensible URLs like /blog/ and /blog/archive/, is there any reason to believe that they're ever going to change? If not, then just write a hard-coded <a href="/blog/"> link on your template and forget about it. That might seem like a cop-out, but you're going to need some persistent way of nominating a particular page as the blog index - whether that's based on page type, or ID, or location within your site structure - and doing that by URL is probably more sensible and future-proof than any other mechanism you could come up with. URLs are supposed to be persistent identifiers, after all...


OK. The detailed answer:

In the example for the pageurl documentation, self.blog_page is simply a variable that refers to a Page object. It's what you'd use if you had a setup like this, where blog_page is a field of your page, pointing to some other page:

class ExamplePage(Page):
    body = RichTextField()
    blog_page = models.ForeignKey('wagtailcore.Page')

    content_panels = Page.content_panels + [
        FieldPanel('body'),
        PageChooserPanel('blog_page'),
    ]

However, in your case, you want the linked page to be determined programmatically, not part of the authored page content, so you need some other way of obtaining the relevant Page object.

When you talk about "my BlogIndexPage", you're implying that exactly one page of that type will exist on your site at any one time. If that is indeed a valid assumption, then a suitable Django expression for retrieving that page would be: BlogIndexPage.objects.first(). (If that's not a valid assumption, then you'll need to decide for yourself how your site is going to pick one particular BlogIndexPage as the blog index.)

You now need to make that page object available on your template. One way of doing this is through a get_context method:

class ExamplePage(Page):
    body = RichTextField()

    def get_context(self, request):
        context = super(ExamplePage, self).get_context(request)
        context['blog_index'] = BlogIndexPage.objects.first()
        return context

This makes it available on the template as the variable blog_index, allowing you to write: {% pageurl blog_index %}.

Callean answered 2/8, 2015 at 1:44 Comment(3)
Thanks a lot! I took the first, easy first approach, you were totally right about the uniqueness of these two URLs. But even your detailed answer helped me with another Wagtail problem.Varicose
Thank you very much, I have tried your way using get_context and it is really working. I'm just curious, this post is 4 years old...does not have wagtail some better approach nowadays? I can't find anything...Dehypnotize
PageChooserPanel can be used to link to any wagtailcore.Page But how can I get the slug of that page from the parent page?Legging
N
9

slugurl should be much easier. For example, {% slugurl 'blog_index'%}

pageurl requires a page object which must be available in the questioning template.

Nape answered 13/4, 2017 at 1:57 Comment(3)
Thanks, you're right, I will definitely use this - and @Callean is also right.Varicose
How do you need to adjust the context to get the blog_index variable ready for slugurl? If I use the code from @Callean and just change pageurl into slugurl, by link coems out as <domain name>/NoneOrna
First, you can check that the blog_index has value. It should be a post which has been published. Just print it out in that method to see it is right one.Nape

© 2022 - 2024 — McMap. All rights reserved.