0
votes

I tried to look for solution but probably missed it, probably because I am unsure what exactly to ask.

I am new to Wagtail/Django. How can I make variables from a parent page visible on child page?

I am trying to make a page that has Header, Content and Footer. I enclosed those inside {% block name_of_section %}. Now I have a child page (actually grandchild, but whatever) which template consists only of:

{% extends main_page.html %}
{% load wagtailcore_tags wagtailimages_tags static wagtailuserbar %}

{% block content%}
   {{ page.photo }}
   {{ page.article }}
{% endblock %}

and the main page template (truncated of course):

{% load wagtailcore_tags wagtailimages_tags static wagtailuserbar %}
htmlcode
{% block header %}some stuff here{% endblock %}
{% block content %}stuff to be replaced in child pages here{% endblock%}
{% block footer %}{{ page.address }} {{ page.links }} {{% endblock %}}
finishing html code here

Now the problem I am having is that when I load the child page, the header, content and footer display almost fine. The exceptions are those variables address and links from the footer. I assume it is because it gets passed to the child page still as {{ page.address }} and of course the child page has no address so the result is empty string.

My workaround was to (probably very wrongly) do this in the models.py:

def address(self):
    getattr(HomePage.objects.first(), 'address')
    return address

So when the home page is loaded, the template loads the variable and when the child page is loaded the template calls the method which (also probably in wrong way - but working) fetches the variable's value.

But it feels wrong. What is the proper way?

1

1 Answers

1
votes

It sounds like address is not really a field that belongs on the HomePage, but a global property of the site as a whole. If so, moving it to a Site Settings model would be a better fit - that way you can easily make it available on all pages using the same base template.

More generally, if you have some global information to be displayed in the header / footer of all pages, but don't want to have to include the logic for retrieving that information in every page type, an inclusion template tag is a good approach: write the retrieval logic in the function body of the template tag, then hand off to a template to render it. You then just need to insert that tag into your base template.