kopia lustrzana https://github.com/wagtail/wagtail
Add publish & unpublish page hooks
* Add `before_unpublish_page` and `before_unpublish_page` hooks * Add `before_publish_page` and `before_publish_page` hooks * Resolves #4590pull/4922/head
rodzic
b98e6d7549
commit
a7f58821a7
|
@ -14,6 +14,7 @@ Changelog
|
|||
* Add `pre_page_move` and `post_page_move` signals (Andy Babic)
|
||||
* Add ability to sort search promotions on listing page (Chris Ranjana, LB (Ben Johnston))
|
||||
* Upgrade internal JS tooling to Gulp v4 & Node v10 (Jim Jazwiecki, Kim LaRocca)
|
||||
* Add `after_publish_page`, `before_publish_page`, `after_unpublish_page` & `before_unpublish_page` hooks (Jonatas Baldin, Coen van der Kamp)
|
||||
* Fix: Support IPv6 domain (Alex Gleason, Coen van der Kamp)
|
||||
* Fix: Ensure link to add a new user works when no users are visible in the users list (LB (Ben Johnston))
|
||||
* Fix: `AbstractEmailForm` saved submission fields are now aligned with the email content fields, `form.cleaned_data` will be used instead of `form.fields` (Haydn Greatnews)
|
||||
|
|
|
@ -454,6 +454,7 @@ Contributors
|
|||
* François Poulain
|
||||
* Jim Jazwiecki
|
||||
* Kim LaRocca
|
||||
* Jonatas Baldin
|
||||
|
||||
Translators
|
||||
===========
|
||||
|
|
|
@ -505,6 +505,46 @@ Hooks for customising the way users are directed through the process of creating
|
|||
Uses the same behaviour as ``before_create_page``.
|
||||
|
||||
|
||||
.. _after_publish_page:
|
||||
|
||||
``after_publish_page``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Do something with a ``Page`` object after it has been published via page create view or page edit view.
|
||||
|
||||
The function does not have to return anything, but if an object with a ``status_code`` property is returned, Wagtail will use it as a response object and skip the rest of the view.
|
||||
|
||||
|
||||
.. _before_publish_page:
|
||||
|
||||
``before_publish_page``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Do something with a ``Page`` object before it has been published via page create view or page edit view.
|
||||
|
||||
The function does not have to return anything, but if an object with a ``status_code`` property is returned, Wagtail will use it as a response object and skip the rest of the view.
|
||||
|
||||
|
||||
.. _after_unpublish_page:
|
||||
|
||||
``after_unpublish_page``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Called after unpublish action in "unpublish" view passing in the request and the page object.
|
||||
|
||||
The function does not have to return anything, but if an object with a ``status_code`` property is returned, Wagtail will use it as a response object and skip the rest of the view.
|
||||
|
||||
|
||||
.. _before_unpublish_page:
|
||||
|
||||
``before_unpublish_page``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Called before unpublish action in "unpublish" view passing in the request and the page object.
|
||||
|
||||
The function does not have to return anything, but if an object with a ``status_code`` property is returned, Wagtail will use it as a response object and skip the rest of the view.
|
||||
|
||||
|
||||
.. _after_copy_page:
|
||||
|
||||
``after_copy_page``
|
||||
|
|
|
@ -23,6 +23,7 @@ Other features
|
|||
* Add ``pre_page_move`` and ``post_page_move`` signals. (Andy Babic)
|
||||
* Add ability to sort search promotions on listing page (Chris Ranjana, LB (Ben Johnston))
|
||||
* Upgrade internal JS tooling to Gulp v4 & Node v10 (Jim Jazwiecki, Kim LaRocca)
|
||||
* Add ``after_publish_page``, ``before_publish_page``, ``after_unpublish_page`` & ``before_unpublish_page`` hooks (Jonatas Baldin, Coen van der Kamp)
|
||||
|
||||
|
||||
Bug fixes
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.test import TestCase
|
|||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from wagtail.admin.tests.pages.timestamps import submittable_timestamp
|
||||
from wagtail.core.models import GroupPagePermission, Page, PageRevision
|
||||
|
@ -667,6 +668,54 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
# page should be created
|
||||
self.assertTrue(Page.objects.filter(title="New page!").exists())
|
||||
|
||||
def test_after_publish_page(self):
|
||||
def hook_func(request, page):
|
||||
self.assertIsInstance(request, HttpRequest)
|
||||
self.assertEqual(page.title, "New page!")
|
||||
|
||||
return HttpResponse("Overridden!")
|
||||
|
||||
with self.register_hook("after_publish_page", hook_func):
|
||||
post_data = {
|
||||
"title": "New page!",
|
||||
"content": "Some content",
|
||||
"slug": "hello-world",
|
||||
"action-publish": "Publish",
|
||||
}
|
||||
response = self.client.post(
|
||||
reverse("wagtailadmin_pages:add", args=("tests", "simplepage", self.root_page.id)),
|
||||
post_data
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content, b"Overridden!")
|
||||
self.root_page.refresh_from_db()
|
||||
self.assertEqual(self.root_page.get_children()[0].status_string, _("live"))
|
||||
|
||||
def test_before_publish_page(self):
|
||||
def hook_func(request, page):
|
||||
self.assertIsInstance(request, HttpRequest)
|
||||
self.assertEqual(page.title, "New page!")
|
||||
|
||||
return HttpResponse("Overridden!")
|
||||
|
||||
with self.register_hook("before_publish_page", hook_func):
|
||||
post_data = {
|
||||
"title": "New page!",
|
||||
"content": "Some content",
|
||||
"slug": "hello-world",
|
||||
"action-publish": "Publish",
|
||||
}
|
||||
response = self.client.post(
|
||||
reverse("wagtailadmin_pages:add", args=("tests", "simplepage", self.root_page.id)),
|
||||
post_data
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content, b"Overridden!")
|
||||
self.root_page.refresh_from_db()
|
||||
self.assertEqual(self.root_page.get_children()[0].status_string, _("live + draft"))
|
||||
|
||||
def test_display_moderation_button_by_default(self):
|
||||
"""
|
||||
Tests that by default the "Submit for Moderation" button is shown in the action menu.
|
||||
|
|
|
@ -11,6 +11,7 @@ from django.http import HttpRequest, HttpResponse
|
|||
from django.test import TestCase, modify_settings, override_settings
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from wagtail.admin.tests.pages.timestamps import submittable_timestamp
|
||||
from wagtail.core.models import Page, PageRevision, Site
|
||||
|
@ -884,6 +885,52 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
# page should be edited
|
||||
self.assertEqual(Page.objects.get(id=self.child_page.id).title, "I've been edited!")
|
||||
|
||||
def test_after_publish_page(self):
|
||||
def hook_func(request, page):
|
||||
self.assertIsInstance(request, HttpRequest)
|
||||
self.assertEqual(page.id, self.child_page.id)
|
||||
|
||||
return HttpResponse("Overridden!")
|
||||
|
||||
with self.register_hook("after_publish_page", hook_func):
|
||||
post_data = {
|
||||
'title': "I've been edited!",
|
||||
'content': "Some content",
|
||||
'slug': 'hello-world-new',
|
||||
'action-publish': "Publish",
|
||||
}
|
||||
response = self.client.post(
|
||||
reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content, b"Overridden!")
|
||||
self.child_page.refresh_from_db()
|
||||
self.assertEqual(self.child_page.status_string, _("live"))
|
||||
|
||||
def test_before_publish_page(self):
|
||||
def hook_func(request, page):
|
||||
self.assertIsInstance(request, HttpRequest)
|
||||
self.assertEqual(page.id, self.child_page.id)
|
||||
|
||||
return HttpResponse("Overridden!")
|
||||
|
||||
with self.register_hook("before_publish_page", hook_func):
|
||||
post_data = {
|
||||
'title': "I've been edited!",
|
||||
'content': "Some content",
|
||||
'slug': 'hello-world-new',
|
||||
'action-publish': "Publish",
|
||||
}
|
||||
response = self.client.post(
|
||||
reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content, b"Overridden!")
|
||||
self.child_page.refresh_from_db()
|
||||
self.assertEqual(self.child_page.status_string, _("live + draft"))
|
||||
|
||||
def test_override_default_action_menu_item(self):
|
||||
def hook_func(menu_items, request, context):
|
||||
for (index, item) in enumerate(menu_items):
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from unittest import mock
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from wagtail.core.models import Page
|
||||
from wagtail.core.signals import page_unpublished
|
||||
|
@ -87,6 +89,45 @@ class TestPageUnpublish(TestCase, WagtailTestUtils):
|
|||
self.assertEqual(mock_call['instance'], self.page)
|
||||
self.assertIsInstance(mock_call['instance'], self.page.specific_class)
|
||||
|
||||
def test_after_unpublish_page(self):
|
||||
def hook_func(request, page):
|
||||
self.assertIsInstance(request, HttpRequest)
|
||||
self.assertEqual(page.id, self.page.id)
|
||||
|
||||
return HttpResponse("Overridden!")
|
||||
|
||||
with self.register_hook('after_unpublish_page', hook_func):
|
||||
post_data = {}
|
||||
response = self.client.post(
|
||||
reverse('wagtailadmin_pages:unpublish', args=(self.page.id, )), post_data
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content, b"Overridden!")
|
||||
|
||||
self.page.refresh_from_db()
|
||||
self.assertEqual(self.page.status_string, _("draft"))
|
||||
|
||||
def test_before_unpublish_page(self):
|
||||
def hook_func(request, page):
|
||||
self.assertIsInstance(request, HttpRequest)
|
||||
self.assertEqual(page.id, self.page.id)
|
||||
|
||||
return HttpResponse("Overridden!")
|
||||
|
||||
with self.register_hook('before_unpublish_page', hook_func):
|
||||
post_data = {}
|
||||
response = self.client.post(
|
||||
reverse('wagtailadmin_pages:unpublish', args=(self.page.id, )), post_data
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content, b"Overridden!")
|
||||
|
||||
# The hook response is served before unpublish is called.
|
||||
self.page.refresh_from_db()
|
||||
self.assertEqual(self.page.status_string, _("live"))
|
||||
|
||||
def test_unpublish_descendants_view(self):
|
||||
"""
|
||||
This tests that the unpublish view responds with an unpublish confirm page that does not contain the form field 'include_descendants'
|
||||
|
|
|
@ -243,8 +243,18 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
|
|||
|
||||
# Publish
|
||||
if is_publishing:
|
||||
for fn in hooks.get_hooks('before_publish_page'):
|
||||
result = fn(request, page)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
|
||||
revision.publish()
|
||||
|
||||
for fn in hooks.get_hooks('after_publish_page'):
|
||||
result = fn(request, page)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
|
||||
# Notifications
|
||||
if is_publishing:
|
||||
if page.go_live_at and page.go_live_at > timezone.now():
|
||||
|
@ -399,11 +409,21 @@ def edit(request, page_id):
|
|||
|
||||
# Publish
|
||||
if is_publishing:
|
||||
for fn in hooks.get_hooks('before_publish_page'):
|
||||
result = fn(request, page)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
|
||||
revision.publish()
|
||||
# Need to reload the page because the URL may have changed, and we
|
||||
# need the up-to-date URL for the "View Live" button.
|
||||
page = page.specific_class.objects.get(pk=page.pk)
|
||||
|
||||
for fn in hooks.get_hooks('after_publish_page'):
|
||||
result = fn(request, page)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
|
||||
# Notifications
|
||||
if is_publishing:
|
||||
if go_live_at and go_live_at > timezone.now():
|
||||
|
@ -738,6 +758,11 @@ def unpublish(request, page_id):
|
|||
if request.method == 'POST':
|
||||
include_descendants = request.POST.get("include_descendants", False)
|
||||
|
||||
for fn in hooks.get_hooks('before_unpublish_page'):
|
||||
result = fn(request, page)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
|
||||
page.unpublish()
|
||||
|
||||
if include_descendants:
|
||||
|
@ -746,6 +771,11 @@ def unpublish(request, page_id):
|
|||
if user_perms.for_page(live_descendant_page).can_unpublish():
|
||||
live_descendant_page.unpublish()
|
||||
|
||||
for fn in hooks.get_hooks('after_unpublish_page'):
|
||||
result = fn(request, page)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
|
||||
messages.success(request, _("Page '{0}' unpublished.").format(page.get_admin_display_title()), buttons=[
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
|
||||
])
|
||||
|
|
Ładowanie…
Reference in New Issue