Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link to specific page in Wagtail CMS

Tags:

wagtail

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?

like image 368
tombreit Avatar asked Aug 01 '15 21:08

tombreit


2 Answers

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 %}.

like image 112
gasman Avatar answered Oct 21 '22 09:10

gasman


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

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

like image 38
Dat TT Avatar answered Oct 21 '22 08:10

Dat TT