如何自定义Wagtail页面复印体验? [英] How do I customize the Wagtail page copy experience?
问题描述
我有一些自定义逻辑(复杂的唯一性约束验证),我想检查一下用户何时尝试在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提供了一种轻松地覆盖的方法任何管理模板.
- 在
templates/wagtailadmin/pages/copy.html
处添加模板将覆盖来轻松扩展复制页面的原始模板,这省去了我们复制/粘贴的麻烦页面的大部分内容,仅自定义我们需要的块. 如果只想在模板中的块的开头或结尾添加一些内容, - 记住
{{block.super}}
可能会派上用场. - 在下面的示例代码中,我复制了整个内容块(在将来的发行版中将需要维护)并添加了一个自定义字段.
- 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 ourcustomCopy
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.
- 这可能并不理想,但是您始终可以猴子补丁
CopyForm
并自定义其__ init __
或clean
方法(或根据需要的任何其他方法). - 您可以查看
CopyForm
来查看需要修改的内容,如果要向表单中添加字段,则需要这样做(以及模板更改).
- This may not be ideal, but you can always monkey patch the
CopyForm
and customise its__init__
orclean
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屋!