【问题标题】:Wagtail single-page site鹡鸰单页网站
【发布时间】:2019-02-06 14:58:37
【问题描述】:

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

虽然我过去曾在非常简单的网站上使用过 wagtail,但我无法找到一种方法来制作一个主页在顶部,然后依次为所有子页面的单页网站。 Wagtail 的页面模型可以做到这一点吗?

【问题讨论】:

  • 只是为了确保我理解正确:您想要一个设置,其中内容在后端作为多个页面输入,但在前端它显示为一个页面,内容为所有页面一个接一个地输出...?
  • 是的,烦人的是,我必须在后端将它们作为单独的页面进行处理,因为虽然有固定类型的数据(标题 + 正文、标题 + 卡片等),但这些数据的数量未知我想让他们灵活地添加、删除或重新排序部分/页面。

标签: python html django wagtail


【解决方案1】:

不久前我通过将我的HomePage 类的子页面渲染为HomePage 上的部分来完成类似的操作。在涉及的各个地方都有一些小的定制(见下文)。也许最困难的部分是重写“部分页面”的页面 URL 以指向 HomePage 和此 HomePage 上的正确锚点(见下文 get_url_parts)。

我已经回收了 wagtail 页面类内置 in_menu 来生成带有/到相关部分的导航栏。

虽然我一直在尝试捕捉所有内容,但我希望没有任何相关的东西让我忘记...

代码

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

【讨论】:

  • 谢谢!它确实帮助我弄清楚了我需要做什么,这对我来说非常有用。感谢您的宝贵时间和经验!
  • 不客气!如果此答案对您有帮助 @kelceyswain ,您可以将其标记为“已解决”。
【解决方案2】:

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

如果是 SPA,您可以使用 AJAX 请求从内置的Wagtail API 中获取其他页面数据。如果它不能完全满足您的需求,您仍然可以使用例如构建自己的 API。 Django Rest Framework

【讨论】:

  • 我从这条路线开始,并在父页面下的 iframe 中渲染子页面,但后来我无法让它表现得像一个页面(即没有 iframe-ness )。我将研究一个 API,但这可能需要我抛弃 Wagtail 并使用纯 Django,这让我有点害怕。谢谢!
  • 您可以保留 Wagtail 而不使用其内置 API。就像在任何普通的 Django 项目中一样编写自己的 DRF 代码。
  • 另外,我不明白为什么不使用 iframe 会有问题。如果您可以获取您的页面数据,如果放在 iframe 或 div/section/ul/whatever 中会有什么不同?
  • 用 Django 编写 AJAX 视图一开始很可怕,但并不像看起来那么复杂。查看 godjango.com/18-basic-ajax 以了解这些视图的工作原理,然后查看 youtube.com/… 以获取 DRF 的完整示例。
  • 但是,如果您碰巧使用 Django 模板而不是成熟的 SPA,请使用 get_context() 路线。
猜你喜欢
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
相关资源
最近更新 更多