跳转到主要内容

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

项目描述

Wagtail Headless Preview

Build status PyPI black 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), PoC改进

测试

项目详情


下载文件

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

源代码发行版

pythonitalia_wagtail_headless-0.8.1.tar.gz (13.3 kB 查看哈希值)

上传时间 源代码

构建发行版

pythonitalia_wagtail_headless-0.8.1-py3-none-any.whl (12.2 kB 查看哈希值)

上传时间 Python 3

由以下组织支持