I made a single-page site in static HTML with shiny screen-height divs, and a smooth scrolling function from a navbar. The website is expected to have a mixture of simple body text, a few images, and a card-deck. It all worked nicely and I was happy.
While I have used wagtail for very simple websites in the past, I cannot work out a way of making a single page site where the home page goes at the top followed by all the child pages in order. Is this possible with Wagtail's page models?
I've done something like this a while ago by rendering subpages of my HomePage class as section on this HomePage. There was some minor customization at various places involved (see below). Perhaps the hardest part was rewriting the page-urls of the "section pages" to point to the HomePage and the correct anchor on this HomePage (see below get_url_parts).
I've recycled the wagtail page class build-in in_menu to generate a navbar with/to the relevant sections.
While I've been trying to catch everything, I hope nothing relevant has slipped my mind...
class HomePage(Page):
"""
We only have one frontend page, on which we render child pages as subsections.
"""
parent_page_types = [
'wagtailcore.Page',
]
# The following page types (here named "sections") are standard wagtail
# page models, but rendered on this HomePage.
subpage_types = [
'TextSection',
'WhereSection',
'ContactSection',
...
]
# fields...
# panels...
def get_subsections(self):
"""
Return page queryset with sections to render on the HomePage.
"""
return (
self
.get_children()
.specific()
.live()
.public()
)
def get_context(self, request):
context = super().get_context(request)
context['subsections'] = self.get_subsections()
context['nav_sections'] = self.get_subsections().in_menu()
return context
class BaseSection(models.Model):
"""
BaseSection abstract base class. All HomePage sections should inherit
from this class.
"""
parent_page_types = ['HomePage']
subpage_types = []
fields...
panels...
class Meta:
abstract = True
def get_url_parts(self, request=None, *args, **kwargs):
"""
Customising URL patterns for a page model
http://docs.wagtail.io/en/latest/topics/pages.html#customising-url-patterns-for-a-page-model
Rewrite page path to corresponding anchor of this section on the
containing page.
"""
url_parts = super().get_url_parts(request=request)
if url_parts is None:
return None
else:
site_id, root_url, page_path = url_parts
_cust_page_path = '#section-{}'.format(page_path.replace('/', ''))
return (site_id, root_url, _cust_page_path)
class TextSection(BaseSection, Page):
template = 'sections/text_section.html'
body = RichTextField()
content_panels = BaseSection.content_panels + [
FieldPanel('body'),
]
class FooSection(BaseSection, Page):
...
The rest is done via the template layer: looping over all subsection on the homepage:
# templates/home_page.html
{% extends 'base.html' %}
{% block navbar %}
{% include 'includes/navbar.html' %}
{% endblock navbar %}
{% block page_content %}
{% for subsection in subsections.all %}
{% with subsection.specific as subsection %}
{% include subsection.template with subsection=subsection %}
{% endwith %}
{% endfor %}
{% endblock %}
# templates/includes/navbar.html
{% load wagtailroutablepage_tags %}
<nav>
{% for item in nav_sections %}
<a
href="{% if not is_homepage %}{% routablepageurl page 'homepage' %}{% endif %}#section-{{ item.slug }}"
>
{{ item.title }}
</a>
{% endfor %}
</nav>
# templates/sections/section_base.html
<section id="section-{{ subsection.slug }}" class="{{ subsection.content_type|slugify }}">
{{ subsection.title }}
{% block content %}
{% endblock content %}
</section>
# templates/sections/text_section.html
{% extends 'sections/section_base.html' %}
{% block content %}
{{ subsection.body|richtext }}
{% endblock content %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With