diff --git a/server/core/templates/wagtailadmin/pages/listing/_list.html b/server/core/templates/wagtailadmin/pages/listing/_list.html index 49ad3173..69d831d0 100644 --- a/server/core/templates/wagtailadmin/pages/listing/_list.html +++ b/server/core/templates/wagtailadmin/pages/listing/_list.html @@ -64,6 +64,7 @@ {% elif show_bulk_actions %} {% include "wagtailadmin/bulk_actions/listing_checkbox_cell.html" with obj_type="page" obj=page aria_labelledby_prefix="page_" aria_labelledby=page.pk|unlocalize aria_labelledby_suffix="_title" %} {% endif %} + {% block page_title %} diff --git a/server/core/wagtail_hooks.py b/server/core/wagtail_hooks.py index 0c82c954..7c9dbf14 100644 --- a/server/core/wagtail_hooks.py +++ b/server/core/wagtail_hooks.py @@ -1,3 +1,4 @@ +import wagtail.admin.views.pages.ordering from django.db.models import ProtectedError from django.shortcuts import redirect from wagtail.admin import messages @@ -14,6 +15,7 @@ from books.models.chapter import Chapter from books.models.contentblock import ContentBlock from core.logger import get_logger from django.conf import settings +from .wagtail_patch import set_page_position logger = get_logger(__name__) @@ -31,6 +33,11 @@ else: primary = "#17A887" secondary = "#078CC6" +# Monkey patching wagtail.admin.views.pages.ordering.set_page_position because there is a bug in the original code +# github issue: + +wagtail.admin.views.pages.ordering.set_page_position = set_page_position + # 1. Use the register_rich_text_features hook. @hooks.register("register_rich_text_features") @@ -111,6 +118,8 @@ def register_secondary_feature(features): @hooks.register("construct_explorer_page_queryset") def remove_page_types_from_menu(parent_page, pages, request): + # Modify the queryset used to populate the explorer menu, to exclude content that is created by the teachers. + # or: Show only content that is created by the content team. return ( pages.not_type(ContentBlockSnapshot) .not_type(BasicKnowledge) diff --git a/server/core/wagtail_patch.py b/server/core/wagtail_patch.py new file mode 100644 index 00000000..f0b36cc6 --- /dev/null +++ b/server/core/wagtail_patch.py @@ -0,0 +1,61 @@ +from django.core.exceptions import PermissionDenied +from django.http import HttpResponse +from django.shortcuts import get_object_or_404 +from wagtail import hooks + +from wagtail.models import Page + + +def set_page_position(request, page_to_move_id): + page_to_move = get_object_or_404(Page, id=page_to_move_id) + parent_page = page_to_move.get_parent() + position = None + + if not parent_page.permissions_for_user(request.user).can_reorder_children(): + raise PermissionDenied + + if request.method == "POST": + # Get target_position parameter + visible_target_position = request.GET.get("position", None) + + # Get position within all children. the frontend position is determined explorer_page queryset. + if visible_target_position is not None: + current_page = get_visible_children(parent_page, request)[int(visible_target_position)] + position = list(parent_page.get_children()).index(current_page) + + # Find page that's already in this position + position_page = None + + if position is not None: + try: + position_page = parent_page.get_children()[position] + except IndexError: + pass # No page in this position + + # Move page + # any invalid moves *should* be caught by the permission check above, + # so don't bother to catch InvalidMoveToDescendant + + if position_page: + # If the page has been moved to the right, insert it to the + # right. If left, then left. + old_position = list(parent_page.get_children()).index(page_to_move) + if position < old_position: + page_to_move.move(position_page, pos="left", user=request.user) + elif position > old_position: + page_to_move.move(position_page, pos="right", user=request.user) + else: + # Move page to end + page_to_move.move(parent_page, pos="last-child", user=request.user) + + return HttpResponse("") + +def get_visible_children(parent_page, request): + """ + Get the pages of parent which are visible to the user. If a hook is used the visible pages are returned by the hook. + """ + pages = parent_page.get_children() + + for hook in hooks.get_hooks("construct_explorer_page_queryset"): + pages = hook(parent_page, pages, request) + return pages