diff --git a/wagtail/admin/views/pages/__init__.py b/wagtail/admin/views/pages/__init__.py
index b7fe651f14..02f27e2b6a 100644
--- a/wagtail/admin/views/pages/__init__.py
+++ b/wagtail/admin/views/pages/__init__.py
@@ -6,15 +6,12 @@ from django.core.paginator import Paginator
from django.db import transaction
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect
-from django.template.loader import render_to_string
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.decorators import method_decorator
-from django.utils.safestring import mark_safe
from django.utils.translation import gettext as _
from wagtail.admin import messages
-from wagtail.admin.action_menu import PageActionMenu
from wagtail.admin.auth import user_has_any_page_permission, user_passes_test
from wagtail.admin.filters import PageHistoryReportFilterSet
from wagtail.admin.views.pages.utils import get_valid_next_url_from_request
@@ -31,6 +28,7 @@ from wagtail.admin.views.pages.lock import * # noqa
from wagtail.admin.views.pages.moderation import * # noqa
from wagtail.admin.views.pages.move import * # noqa
from wagtail.admin.views.pages.preview import * # noqa
+from wagtail.admin.views.pages.revisions import * # noqa
from wagtail.admin.views.pages.search import * # noqa
from wagtail.admin.views.pages.workflow import * # noqa
@@ -179,175 +177,6 @@ def set_page_position(request, page_to_move_id):
return HttpResponse('')
-@user_passes_test(user_has_any_page_permission)
-def revisions_index(request, page_id):
- page = get_object_or_404(Page, id=page_id).specific
-
- # Get page ordering
- ordering = request.GET.get('ordering', '-created_at')
- if ordering not in ['created_at', '-created_at', ]:
- ordering = '-created_at'
-
- revisions = page.revisions.order_by(ordering)
-
- paginator = Paginator(revisions, per_page=20)
- revisions = paginator.get_page(request.GET.get('p'))
-
- return TemplateResponse(request, 'wagtailadmin/pages/revisions/index.html', {
- 'page': page,
- 'ordering': ordering,
- 'pagination_query_params': "ordering=%s" % ordering,
- 'revisions': revisions,
- })
-
-
-def revisions_revert(request, page_id, revision_id):
- page = get_object_or_404(Page, id=page_id).specific
- page_perms = page.permissions_for_user(request.user)
- if not page_perms.can_edit():
- raise PermissionDenied
-
- revision = get_object_or_404(page.revisions, id=revision_id)
- revision_page = revision.as_page_object()
-
- content_type = ContentType.objects.get_for_model(page)
- page_class = content_type.model_class()
-
- edit_handler = page_class.get_edit_handler()
- edit_handler = edit_handler.bind_to(instance=revision_page,
- request=request)
- form_class = edit_handler.get_form_class()
-
- form = form_class(instance=revision_page)
- edit_handler = edit_handler.bind_to(form=form)
-
- user_avatar = render_to_string('wagtailadmin/shared/user_avatar.html', {'user': revision.user})
-
- messages.warning(request, mark_safe(
- _("You are viewing a previous version of this page from %(created_at)s by %(user)s") % {
- 'created_at': revision.created_at.strftime("%d %b %Y %H:%M"),
- 'user': user_avatar,
- }
- ))
-
- return TemplateResponse(request, 'wagtailadmin/pages/edit.html', {
- 'page': page,
- 'revision': revision,
- 'is_revision': True,
- 'content_type': content_type,
- 'edit_handler': edit_handler,
- 'errors_debug': None,
- 'action_menu': PageActionMenu(request, view='revisions_revert', page=page),
- 'preview_modes': page.preview_modes,
- 'form': form, # Used in unit tests
- })
-
-
-@user_passes_test(user_has_any_page_permission)
-def revisions_view(request, page_id, revision_id):
- page = get_object_or_404(Page, id=page_id).specific
-
- perms = page.permissions_for_user(request.user)
- if not (perms.can_publish() or perms.can_edit()):
- raise PermissionDenied
-
- revision = get_object_or_404(page.revisions, id=revision_id)
- revision_page = revision.as_page_object()
-
- try:
- preview_mode = page.default_preview_mode
- except IndexError:
- raise PermissionDenied
-
- return revision_page.make_preview_request(request, preview_mode)
-
-
-def revisions_compare(request, page_id, revision_id_a, revision_id_b):
- page = get_object_or_404(Page, id=page_id).specific
-
- # Get revision to compare from
- if revision_id_a == 'live':
- if not page.live:
- raise Http404
-
- revision_a = page
- revision_a_heading = _("Live")
- elif revision_id_a == 'earliest':
- revision_a = page.revisions.order_by('created_at', 'id').first()
- if revision_a:
- revision_a = revision_a.as_page_object()
- revision_a_heading = _("Earliest")
- else:
- raise Http404
- else:
- revision_a = get_object_or_404(page.revisions, id=revision_id_a).as_page_object()
- revision_a_heading = str(get_object_or_404(page.revisions, id=revision_id_a).created_at)
-
- # Get revision to compare to
- if revision_id_b == 'live':
- if not page.live:
- raise Http404
-
- revision_b = page
- revision_b_heading = _("Live")
- elif revision_id_b == 'latest':
- revision_b = page.revisions.order_by('created_at', 'id').last()
- if revision_b:
- revision_b = revision_b.as_page_object()
- revision_b_heading = _("Latest")
- else:
- raise Http404
- else:
- revision_b = get_object_or_404(page.revisions, id=revision_id_b).as_page_object()
- revision_b_heading = str(get_object_or_404(page.revisions, id=revision_id_b).created_at)
-
- comparison = page.get_edit_handler().get_comparison()
- comparison = [comp(revision_a, revision_b) for comp in comparison]
- comparison = [comp for comp in comparison if comp.has_changed()]
-
- return TemplateResponse(request, 'wagtailadmin/pages/revisions/compare.html', {
- 'page': page,
- 'revision_a_heading': revision_a_heading,
- 'revision_a': revision_a,
- 'revision_b_heading': revision_b_heading,
- 'revision_b': revision_b,
- 'comparison': comparison,
- })
-
-
-def revisions_unschedule(request, page_id, revision_id):
- page = get_object_or_404(Page, id=page_id).specific
-
- user_perms = UserPagePermissionsProxy(request.user)
- if not user_perms.for_page(page).can_unschedule():
- raise PermissionDenied
-
- revision = get_object_or_404(page.revisions, id=revision_id)
-
- next_url = get_valid_next_url_from_request(request)
-
- subtitle = _('revision {0} of "{1}"').format(revision.id, page.get_admin_display_title())
-
- if request.method == 'POST':
- revision.approved_go_live_at = None
- revision.save(user=request.user, update_fields=['approved_go_live_at'])
-
- messages.success(request, _('Version {0} of "{1}" unscheduled.').format(revision.id, page.get_admin_display_title()), buttons=[
- messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
- ])
-
- if next_url:
- return redirect(next_url)
- return redirect('wagtailadmin_pages:history', page.id)
-
- return TemplateResponse(request, 'wagtailadmin/pages/revisions/confirm_unschedule.html', {
- 'page': page,
- 'revision': revision,
- 'next': next_url,
- 'subtitle': subtitle
- })
-
-
def workflow_history(request, page_id):
page = get_object_or_404(Page, id=page_id)
diff --git a/wagtail/admin/views/pages/revisions.py b/wagtail/admin/views/pages/revisions.py
new file mode 100644
index 0000000000..c7bff8a0b5
--- /dev/null
+++ b/wagtail/admin/views/pages/revisions.py
@@ -0,0 +1,185 @@
+from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import PermissionDenied
+from django.core.paginator import Paginator
+from django.http import Http404
+from django.shortcuts import get_object_or_404, redirect
+from django.template.loader import render_to_string
+from django.template.response import TemplateResponse
+from django.urls import reverse
+from django.utils.safestring import mark_safe
+from django.utils.translation import gettext as _
+
+from wagtail.admin import messages
+from wagtail.admin.action_menu import PageActionMenu
+from wagtail.admin.auth import user_has_any_page_permission, user_passes_test
+from wagtail.admin.views.pages.utils import get_valid_next_url_from_request
+from wagtail.core.models import Page, UserPagePermissionsProxy
+
+
+@user_passes_test(user_has_any_page_permission)
+def revisions_index(request, page_id):
+ page = get_object_or_404(Page, id=page_id).specific
+
+ # Get page ordering
+ ordering = request.GET.get('ordering', '-created_at')
+ if ordering not in ['created_at', '-created_at', ]:
+ ordering = '-created_at'
+
+ revisions = page.revisions.order_by(ordering)
+
+ paginator = Paginator(revisions, per_page=20)
+ revisions = paginator.get_page(request.GET.get('p'))
+
+ return TemplateResponse(request, 'wagtailadmin/pages/revisions/index.html', {
+ 'page': page,
+ 'ordering': ordering,
+ 'pagination_query_params': "ordering=%s" % ordering,
+ 'revisions': revisions,
+ })
+
+
+def revisions_revert(request, page_id, revision_id):
+ page = get_object_or_404(Page, id=page_id).specific
+ page_perms = page.permissions_for_user(request.user)
+ if not page_perms.can_edit():
+ raise PermissionDenied
+
+ revision = get_object_or_404(page.revisions, id=revision_id)
+ revision_page = revision.as_page_object()
+
+ content_type = ContentType.objects.get_for_model(page)
+ page_class = content_type.model_class()
+
+ edit_handler = page_class.get_edit_handler()
+ edit_handler = edit_handler.bind_to(instance=revision_page,
+ request=request)
+ form_class = edit_handler.get_form_class()
+
+ form = form_class(instance=revision_page)
+ edit_handler = edit_handler.bind_to(form=form)
+
+ user_avatar = render_to_string('wagtailadmin/shared/user_avatar.html', {'user': revision.user})
+
+ messages.warning(request, mark_safe(
+ _("You are viewing a previous version of this page from %(created_at)s by %(user)s") % {
+ 'created_at': revision.created_at.strftime("%d %b %Y %H:%M"),
+ 'user': user_avatar,
+ }
+ ))
+
+ return TemplateResponse(request, 'wagtailadmin/pages/edit.html', {
+ 'page': page,
+ 'revision': revision,
+ 'is_revision': True,
+ 'content_type': content_type,
+ 'edit_handler': edit_handler,
+ 'errors_debug': None,
+ 'action_menu': PageActionMenu(request, view='revisions_revert', page=page),
+ 'preview_modes': page.preview_modes,
+ 'form': form, # Used in unit tests
+ })
+
+
+@user_passes_test(user_has_any_page_permission)
+def revisions_view(request, page_id, revision_id):
+ page = get_object_or_404(Page, id=page_id).specific
+
+ perms = page.permissions_for_user(request.user)
+ if not (perms.can_publish() or perms.can_edit()):
+ raise PermissionDenied
+
+ revision = get_object_or_404(page.revisions, id=revision_id)
+ revision_page = revision.as_page_object()
+
+ try:
+ preview_mode = page.default_preview_mode
+ except IndexError:
+ raise PermissionDenied
+
+ return revision_page.make_preview_request(request, preview_mode)
+
+
+def revisions_compare(request, page_id, revision_id_a, revision_id_b):
+ page = get_object_or_404(Page, id=page_id).specific
+
+ # Get revision to compare from
+ if revision_id_a == 'live':
+ if not page.live:
+ raise Http404
+
+ revision_a = page
+ revision_a_heading = _("Live")
+ elif revision_id_a == 'earliest':
+ revision_a = page.revisions.order_by('created_at', 'id').first()
+ if revision_a:
+ revision_a = revision_a.as_page_object()
+ revision_a_heading = _("Earliest")
+ else:
+ raise Http404
+ else:
+ revision_a = get_object_or_404(page.revisions, id=revision_id_a).as_page_object()
+ revision_a_heading = str(get_object_or_404(page.revisions, id=revision_id_a).created_at)
+
+ # Get revision to compare to
+ if revision_id_b == 'live':
+ if not page.live:
+ raise Http404
+
+ revision_b = page
+ revision_b_heading = _("Live")
+ elif revision_id_b == 'latest':
+ revision_b = page.revisions.order_by('created_at', 'id').last()
+ if revision_b:
+ revision_b = revision_b.as_page_object()
+ revision_b_heading = _("Latest")
+ else:
+ raise Http404
+ else:
+ revision_b = get_object_or_404(page.revisions, id=revision_id_b).as_page_object()
+ revision_b_heading = str(get_object_or_404(page.revisions, id=revision_id_b).created_at)
+
+ comparison = page.get_edit_handler().get_comparison()
+ comparison = [comp(revision_a, revision_b) for comp in comparison]
+ comparison = [comp for comp in comparison if comp.has_changed()]
+
+ return TemplateResponse(request, 'wagtailadmin/pages/revisions/compare.html', {
+ 'page': page,
+ 'revision_a_heading': revision_a_heading,
+ 'revision_a': revision_a,
+ 'revision_b_heading': revision_b_heading,
+ 'revision_b': revision_b,
+ 'comparison': comparison,
+ })
+
+
+def revisions_unschedule(request, page_id, revision_id):
+ page = get_object_or_404(Page, id=page_id).specific
+
+ user_perms = UserPagePermissionsProxy(request.user)
+ if not user_perms.for_page(page).can_unschedule():
+ raise PermissionDenied
+
+ revision = get_object_or_404(page.revisions, id=revision_id)
+
+ next_url = get_valid_next_url_from_request(request)
+
+ subtitle = _('revision {0} of "{1}"').format(revision.id, page.get_admin_display_title())
+
+ if request.method == 'POST':
+ revision.approved_go_live_at = None
+ revision.save(user=request.user, update_fields=['approved_go_live_at'])
+
+ messages.success(request, _('Version {0} of "{1}" unscheduled.').format(revision.id, page.get_admin_display_title()), buttons=[
+ messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
+ ])
+
+ if next_url:
+ return redirect(next_url)
+ return redirect('wagtailadmin_pages:history', page.id)
+
+ return TemplateResponse(request, 'wagtailadmin/pages/revisions/confirm_unschedule.html', {
+ 'page': page,
+ 'revision': revision,
+ 'next': next_url,
+ 'subtitle': subtitle
+ })