如何自定义Wagtail页面复印体验? [英] How do I customize the Wagtail page copy experience?

查看:64
本文介绍了如何自定义Wagtail页面复印体验?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些自定义逻辑(复杂的唯一性约束验证),我想检查一下用户何时尝试在Wagtail中复制(或移动)某种类型的Page.我还想给用户一个机会来更改与验证检查关联的字段.

I have some custom logic (complex unique constraint validation) I would like to check when a user attempts to copy (or move) a certain type of Page in Wagtail. I would also like to give the user an opportunity to change the fields associated with the validation check.

我知道Wagtail公开了一种通过挂钩自定义复制(和移动)体验的方式(

I am aware of the fact that Wagtail exposes a way of customizing the copy (and move) experiences through hooks (http://docs.wagtail.io/en/stable/reference/hooks.html#before-copy-page), but the best I can come up with using that tool is to create a completely new interface and return it in a HttpResponse. Is there a way to merely customize the existing copy (and move) interface for a specific page type?

@hooks.register('before-copy-page')
def before-copy-page(request, page):
    return HttpResponse("New copy interface", content_type="text/plain")

推荐答案

这三种方法可让您更深入地了解Wagtail页面副本视图和验证的自定义.您可能不需要全部执行这三个操作,但是下面的示例代码假定所有更改都已在某种程度上完成.

These three approaches get you deeper into a customisation for the Wagtail page copy view and validation. You may not need to do all three but the example code below assumes all changes have been done to some extent.

也许会有更好的方法来完成您想要的事情,但是希望这为您提供了一些方法来自定义整个副本视图/表单交互的一部分.

There might be better ways to do the exact thing you want but hopefully this gives you a few ways to customise parts of the entire copy view/form interaction.

这些方法应该适用于移动页面交互,但是还有更多的表单和视图.

These approaches should work for the move pages interaction but that has a few more forms and views.

  • Wagtail provides a way to easily override any admin templates.
  • Adding a template at templates/wagtailadmin/pages/copy.html will override the copy page form template.
  • We can also easily extend the original template for the copy page by adding {% extends "wagtailadmin/pages/copy.html" %} at the top, this saves us having to copy/past most of the page and only customise the blocks we need.
  • Remember {{ block.super }} could come in handy here if you only wanted to add something to the start or end of a block within the template.
  • In the example code below I have copied the entire content block (will need to be maintained for future releases) and added a custom field.
  • 您的urls.py中应配置为包括 Wagtail网址.
  • admin/网址上方添加新的URL路径,将首先访问该路径.
  • 例如 url(r'^ admin/pages/(\ d +)/copy/$',base_views.customCopy,name ='copy'),这将引导管理员复制页面到我们的 customCopy 视图.
  • 该视图可以是函数视图或类视图,可以完全自定义整个视图(和模板)或仅部分定制.
  • 此处使用的Wagtail视图是功能视图,因此无法轻松复制,因此此处的自定义设置受到限制.
  • 您可以在
  • In your urls.py which should be configured to include the Wagtail urls.
  • Add a new URL path above the admin/ urls, this will be accessed first.
  • For example url(r'^admin/pages/(\d+)/copy/$', base_views.customCopy, name='copy'),, this will direct the admin copy page to our customCopy view.
  • This view can be a function or class view and either completely customise the entire view (and template) or just parts of it.
  • The Wagtail view used here is a function view so it cannot be easily copied, so your customisations are a bit restricted here.
  • You can see the source for this view in admin/views/pages.py.
  • This may not be ideal, but you can always monkey patch the CopyForm and customise its __init__ or clean methods (or any others as needed).
  • You can view the source of CopyForm to see what you need to modify, if you wanted to add fields to the form, this (along with the template changes) will be needed.
{% extends "wagtailadmin/pages/copy.html" %}
{% load i18n %}
{% block content %}
    {% comment %} source - wagtail/admin/templates/wagtailadmin/pages/copy.html {% endcomment %}
    {% trans "Copy" as copy_str %}
    {% include "wagtailadmin/shared/header.html" with title=copy_str subtitle=page.get_admin_display_title icon="doc-empty-inverse" %}

    <div class="nice-padding">
        <form action="{% url 'wagtailadmin_pages:copy' page.id %}" method="POST" novalidate>
            {% csrf_token %}
            <input type="hidden" name="next" value="{{ next }}" />

            <ul class="fields">
                {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_title %}
                {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_slug %}
                {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_parent_page %}

                {% if form.copy_subpages %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.copy_subpages %}
                {% endif %}

                {% if form.publish_copies %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.publish_copies %}
                {% endif %}
                {% comment %} BEGIN CUSTOM CONTENT {% endcomment %}
                {% include "wagtailadmin/shared/field_as_li.html" with field=form.other %}
                {% comment %} END CUSTOM CONTENT {% endcomment %}
            </ul>

            <input type="submit" value="{% trans 'Copy this page' %}" class="button">
        </form>
    </div>
{% endblock %}

(2)urls.py

django.conf.urls中的

(2) urls.py

from django.conf.urls import include, url
from django.contrib import admin

from wagtail.admin import urls as wagtailadmin_urls
from wagtail.admin.views import pages
from wagtail.documents import urls as wagtaildocs_urls
from wagtail.core import urls as wagtail_urls

from myapp.base import views as base_views  # added

urlpatterns = [
    url(r'^django-admin/', admin.site.urls),
    url(r'^admin/pages/(\d+)/copy/$', base_views.customCopy, name='copy'),  # added
    url(r'^admin/', include(wagtailadmin_urls)),
    url(r'^documents/', include(wagtaildocs_urls)),
    url(r'', include(wagtail_urls)),
]

(2& 3)views.py


from django import forms
from django.core.exceptions import PermissionDenied

from wagtail.admin.forms.pages import CopyForm
from wagtail.admin.views import pages
from wagtail.core.models import Page


# BEGIN monkey patch of CopyForm
# See: wagtail/admin/forms/pages.py

original_form_init = CopyForm.__init__
original_form_clean = CopyForm.clean


def custom_form_init(self, *args, **kwargs):
    # note - the template will need to be overridden to show additional fields

    original_form_init(self, *args, **kwargs)
    self.fields['other'] = forms.CharField(initial="will fail", label="Other", required=False)


def custom_form_clean(self):
    cleaned_data = original_form_clean(self)

    other = cleaned_data.get('other')
    if other == 'will fail':
        self._errors['other'] = self.error_class(["This field failed due to custom form validation"])
        del cleaned_data['other']

    return cleaned_data


CopyForm.__init__ = custom_form_init
CopyForm.clean = custom_form_clean

# END monkey patch of CopyForm


def customCopy(request, page_id):
    """
    here we can inject any custom code for the response as a whole
    the template is a view function so we cannot easily customise it
    we can respond to POST or GET with any customisations though
    See: wagtail/admin/views/pages.py
    """

    page = Page.objects.get(id=page_id)

    # Parent page defaults to parent of source page
    parent_page = page.get_parent()

    # Check if the user has permission to publish subpages on the parent
    can_publish = parent_page.permissions_for_user(request.user).can_publish_subpage()

    # Create the form
    form = CopyForm(request.POST or None, user=request.user, page=page, can_publish=can_publish)

    if request.method == 'POST':
        if form.is_valid():
            # if the form has been validated (using the form clean above)
            # we get another chance here to fail the request, or redirect to another page
            # we can also easily access the specific page's model for any Page model methods
            try:
                if not page.specific.can_copy_check():
                    raise PermissionDenied
            except AttributeError:
                # continue through to the normal behaviour
                pass

    response = pages.copy(request, page_id)

    return response

这篇关于如何自定义Wagtail页面复印体验?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆