鹡鸰单页站点

Wagtail single-page site

我在静态 HTML 中制作了一个单页网站,带有闪亮的屏幕高度 div,以及来自导航栏的平滑滚动功能。该网站预计将包含简单的正文、一些图像和卡片组。一切都很好,我很高兴。

虽然我过去曾将 wagtail 用于非常简单的网站,但我无法想出一种方法来制作主页位于顶部的单页网站,然后依次是所有子页面。这可以用 Wagtail 的页面模型实现吗?

如果您使用 Django 模板构建一个页面,您应该能够使用 get_context() 方法将页面列表传递给您的模板。

如果是 SPA,您可以使用 AJAX 请求从内置 Wagtail API. If it doesn't fully suit your needs, you could still build your own API with e.g. the Django Rest Framework.

中获取其他页面数据

我不久前做过类似的事情,将我的 HomePage class 的子页面呈现为 HomePage 的部分。在涉及的各个地方有一些小的定制(见下文)。也许最困难的部分是重写 "section pages" 的页面 url 以指向 HomePage 和此 HomePage 上的正确锚点(见下文 get_url_parts)。

我回收了 wagtail 页面 class 内置 in_menu 以生成导航栏 with/to 相关部分。

虽然我一直在努力抓住一切,但我希望我没有忘记任何相关的事情...

代码

models/pages.py

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

models/sections.py


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):
    ...

其余部分通过模板层完成:遍历主页上的所有子部分:

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