跳转到主要内容

增强无头设置中的Wagtail预览。

项目描述

Wagtail Headless 预览

Build status PyPI Ruff pre-commit.ci status

概述

使用Wagtail作为后端,并使用单独的应用作为前端(例如单页React应用),编辑者将无法预览他们的更改。这是因为前端不再受Wagtail的直接控制。因此,预览数据需要暴露给前端应用。

此包通过将预览路由到指定的前端URL,使Wagtail页面在无头设置中使用时能够启用预览。

设置

使用pip安装

pip install wagtail-headless-preview

安装模块后,将wagtail_headless_preview添加到设置文件中已安装的应用程序

# settings.py

INSTALLED_APPS = [
    # ...
    "wagtail_headless_preview",
]

运行迁移

$ python manage.py migrate

然后使用WAGTAIL_HEADLESS_PREVIEW设置中的CLIENT_URLS选项配置预览客户端URL。

配置

wagtail_headless_preview使用单个设置字典

# settings.py

WAGTAIL_HEADLESS_PREVIEW = {
    "CLIENT_URLS": {},  # defaults to an empty dict. You must at the very least define the default client URL.
    "SERVE_BASE_URL": None,  # can be used for HeadlessServeMixin
    "REDIRECT_ON_PREVIEW": False,  # set to True to redirect to the preview instead of using the Wagtail default mechanism
    "ENFORCE_TRAILING_SLASH": True,  # set to False in order to disable the trailing slash enforcement
}

单站设置

对于单站,将前端URL作为默认条目添加

WAGTAIL_HEADLESS_PREVIEW = {
    "CLIENT_URLS": {
        "default": "http://localhost:8020",
    }
}

如果您已将Wagtail Site条目配置为使用前端URL,则可以更新您的配置为

WAGTAIL_HEADLESS_PREVIEW = {
    "CLIENT_URLS": {
        "default": "{SITE_ROOT_URL}",
    }
}

{SITE_ROOT_URL}占位符将替换为预览页面所属的Siteroot_url属性。

多站设置

对于多站设置,将每个站点作为WAGTAIL_HEADLESS_PREVIEW设置中的CLIENT_URLS选项中的单独条目添加

WAGTAIL_HEADLESS_PREVIEW = {
    "CLIENT_URLS": {
        "default": "https://wagtail.org",  # adjust to match your front-end URL. e.g. locally it may be something like http://localhost:8020
        "cms.wagtail.org": "https://wagtail.org",
        "cms.torchbox.com": "http://torchbox.com",
    },
    # ...
}

服务URL

为了使编辑体验更加流畅,并避免因缺失模板而导致的服务器错误,可以使用结合了HeadlessServeMixinHeadlessPreviewMixin混入的HeadlessMixin

HeadlessServeMixin覆盖了Wagtail的Page.serve方法,将其重定向到客户端URL。默认情况下,它使用CLIENT_URLS中定义的宿主。但是,您可以提供一个统一的URL来管理所有这些

# settings.py

WAGTAIL_HEADLESS_PREVIEW = {
    # ...
    "SERVE_BASE_URL": "https://my.headless.site",
}

强制尾随斜杠

默认情况下,wagtail_headless_preview强制在客户端URL上使用尾随斜杠。您可以通过将ENFORCE_TRAILING_SLASH设置为False来禁用此行为

# settings.py
WAGTAIL_HEADLESS_PREVIEW = {
    # ...
    "ENFORCE_TRAILING_SLASH": False
}

用法

要启用预览并在Wagtail UI中集成“查看实时”按钮,请将HeadlessMixin添加到您的Page

from wagtail.models import Page
from wagtail_headless_preview.models import HeadlessMixin


class MyWonderfulPage(HeadlessMixin, Page):
    pass

如果您需要更细粒度的控制,或者您已修改Page模型的serve方法,则可以将HeadlessPreviewMixin添加到您的Page类中,以仅处理预览

from wagtail.models import Page
from wagtail_headless_preview.models import HeadlessPreviewMixin


class MyWonderfulPage(HeadlessPreviewMixin, Page):
    pass

我的前端应用将如何显示预览内容?

这取决于您的项目,因为它将由您的前端应用的需求决定。

以下示例使用Wagtail API端点来访问预览 - 您的应用程序可以选择使用GraphQL来访问页面预览。

示例

此示例设置了一个API端点,该端点将返回页面的预览,然后在简化的演示前端应用程序中显示该数据。

  • wagtail.api.v2添加到已安装的应用程序
# settings.py

INSTALLED_APPS = [
    # ...
    "wagtail.api.v2",
]
  • 在您的项目目录中创建一个api.py文件
from django.contrib.contenttypes.models import ContentType

from wagtail.api.v2.router import WagtailAPIRouter
from wagtail.api.v2.views import PagesAPIViewSet

from wagtail_headless_preview.models import PagePreview
from rest_framework.response import Response


# Create the router. "wagtailapi" is the URL namespace
api_router = WagtailAPIRouter("wagtailapi")


class PagePreviewAPIViewSet(PagesAPIViewSet):
    known_query_parameters = PagesAPIViewSet.known_query_parameters.union(
        ["content_type", "token"]
    )

    def listing_view(self, request):
        # Delegate to detail_view, specifically so there's no
        # difference between serialization formats.
        self.action = "detail_view"
        return self.detail_view(request, 0)

    def detail_view(self, request, pk):
        page = self.get_object()
        serializer = self.get_serializer(page)
        return Response(serializer.data)

    def get_object(self):
        app_label, model = self.request.GET["content_type"].split(".")
        content_type = ContentType.objects.get(app_label=app_label, model=model)

        page_preview = PagePreview.objects.get(
            content_type=content_type, token=self.request.GET["token"]
        )
        page = page_preview.as_page()
        if not page.pk:
            # fake primary key to stop API URL routing from complaining
            page.pk = 0

        return page


api_router.register_endpoint("page_preview", PagePreviewAPIViewSet)
  • 注册API URL,以便Django可以将请求路由到API
# urls.py

from .api import api_router

urlpatterns = [
    # ...
    path("api/v2/", api_router.urls),
    # ...
    # Ensure that the api_router line appears above the default Wagtail page serving route
    path("", include(wagtail_urls)),
]

有关配置wagtail API的更多信息,请参阅Wagtail API v2配置指南

  • 接下来,在项目根目录中添加一个client/index.html文件。这将查询API以显示我们的预览
<!DOCTYPE html>
<html>
<head>
    <script>
        function go() {
            var querystring = window.location.search.replace(/^\?/, '');
            var params = {};
            querystring.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
                params[decodeURIComponent(key)] = decodeURIComponent(value);
            });

            var apiUrl = 'http://localhost:8000/api/v2/page_preview/1/?content_type=' + encodeURIComponent(params['content_type']) + '&token=' + encodeURIComponent(params['token']) + '&format=json';
            fetch(apiUrl).then(function(response) {
                response.text().then(function(text) {
                    document.body.innerText = text;
                });
            });
        }
    </script>
</head>
<body onload="go()"></body>
</html>
  • 安装django-cors-headerspip install django-cors-headers
  • 将CORS配置添加到您的设置文件中,以允许前端访问API
# settings.py
CORS_ORIGIN_ALLOW_ALL = True
CORS_URLS_REGEX = r"^/api/v2/"

并遵循django-cors-headers的设置说明

  • 正常启动您的站点:python manage.py runserver 0:8000
  • http://localhost:8020/ 上提供前端 client/index.html
    • 这可以通过在客户端目录中运行 python3 -m http.server 8020 来实现
  • 从 wagtail 管理界面编辑(或创建)并预览使用 HeadlessPreviewMixin 的页面

预览页面现在应该显示预览的 API 响应!🎉

这就是真正的前端接手并显示预览的地方,就像在实时网站上看到的那样。

贡献

欢迎所有贡献!

注意,该项目使用 pre-commit。要在本地设置

# if you don't have it yet
$ pip install pre-commit
# go to the project directory
$ cd wagtail-headless-preview
# initialize pre-commit
$ pre-commit install

# Optional, run all checks once for this, then the checks will run only on the changed files
$ pre-commit run --all-files

如何运行测试

现在您可以根据以下示例运行测试

tox -p

或者,您可以为特定环境运行它们 tox -e py311-django4.2-wagtail5.1 或特定测试 tox -e py311-django4.2-wagtail5.0 -- wagtail_headless_preview.tests.test_frontend.TestFrontendViews.test_redirect_on_preview

鸣谢

  • Matthew Westcott (@gasman), 初始概念证明
  • Karl Hobley (@kaedroho), 概念证明改进

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分发

wagtail_headless_preview-0.8.0.tar.gz (14.0 kB 查看哈希值)

上传时间

构建分发

wagtail_headless_preview-0.8.0-py3-none-any.whl (12.3 kB 查看哈希值)

上传时间 Python 3

支持者