Skip to content

Commit

Permalink
refactor: inheritable authoring mixin callbacks for editing & duplica…
Browse files Browse the repository at this point in the history
…tion (#33756)
  • Loading branch information
DanielVZ96 authored Jul 25, 2024
1 parent 238dca7 commit 78b691b
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 49 deletions.
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/views/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from opaque_keys.edx.keys import CourseKey
from web_fragments.fragment import Fragment

from cms.djangoapps.contentstore.utils import load_services_for_studio
from cms.lib.xblock.authoring_mixin import VISIBILITY_VIEW
from common.djangoapps.edxmako.shortcuts import render_to_string
from common.djangoapps.student.auth import (
Expand Down Expand Up @@ -47,7 +48,6 @@
from cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers import (
handle_xblock,
create_xblock_info,
load_services_for_studio,
get_block_info,
get_xblock,
delete_orphans,
Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/views/preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
wrap_xblock_aside
)

from ..utils import get_visibility_partition_info, StudioPermissionsService
from ..utils import StudioPermissionsService, get_visibility_partition_info
from .access import get_user_role
from .session_kv_store import SessionKeyValueStore

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,10 @@ def _update_with_callback(xblock, user, old_metadata=None, old_content=None):
old_metadata = own_metadata(xblock)
if old_content is None:
old_content = xblock.get_explicitly_set_fields_by_scope(Scope.content)
if hasattr(xblock, "editor_saved"):
load_services_for_studio(xblock.runtime, user)
xblock.editor_saved(user, old_metadata, old_content)
load_services_for_studio(xblock.runtime, user)
xblock.editor_saved(user, old_metadata, old_content)
xblock_updated = modulestore().update_item(xblock, user.id)
if hasattr(xblock_updated, "post_editor_saved"):
load_services_for_studio(xblock_updated.runtime, user)
xblock_updated.post_editor_saved(user, old_metadata, old_content)
xblock_updated.post_editor_saved(user, old_metadata, old_content)
return xblock_updated


Expand Down
16 changes: 16 additions & 0 deletions cms/lib/xblock/authoring_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from xblock.core import XBlock, XBlockMixin
from xblock.fields import String, Scope


log = logging.getLogger(__name__)

VISIBILITY_VIEW = 'visibility_view'
Expand All @@ -21,6 +22,7 @@ class AuthoringMixin(XBlockMixin):
"""
Mixin class that provides authoring capabilities for XBlocks.
"""

def _get_studio_resource_url(self, relative_url):
"""
Returns the Studio URL to a static resource.
Expand Down Expand Up @@ -51,3 +53,17 @@ def visibility_view(self, _context=None):
scope=Scope.settings,
enforce_type=True,
)

def editor_saved(self, user, old_metadata, old_content) -> None: # pylint: disable=unused-argument
"""
Called right *before* the block is written to the DB. Can be used, e.g., to modify fields before saving.
By default, is a no-op. Can be overriden in subclasses.
"""

def post_editor_saved(self, user, old_metadata, old_content) -> None: # pylint: disable=unused-argument
"""
Called right *after* the block is written to the DB. Can be used, e.g., to spin up followup tasks.
By default, is a no-op. Can be overriden in subclasses.
"""
43 changes: 2 additions & 41 deletions xmodule/studio_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Mixin to support editing in Studio.
"""
from xblock.core import XBlock, XBlockMixin

from xmodule.x_module import AUTHOR_VIEW, STUDENT_VIEW


Expand All @@ -12,6 +13,7 @@ class StudioEditableBlock(XBlockMixin):
This class is only intended to be used with an XBlock!
"""

has_author_view = True

def render_children(self, context, fragment, can_reorder=False, can_add=False):
Expand Down Expand Up @@ -49,47 +51,6 @@ def get_preview_view_name(block):
"""
return AUTHOR_VIEW if has_author_view(block) else STUDENT_VIEW

# Some parts of the code use getattr to dynamically check for the following methods on subclasses.
# We'd like to refactor so that we can actually declare them here as overridable methods.
# For now, we leave them here as documentation.
# See https://github.com/openedx/edx-platform/issues/33715.
#
# def editor_saved(self, old_metadata, old_content) -> None: # pylint: disable=unused-argument
# """
# Called right *before* the block is written to the DB. Can be used, e.g., to modify fields before saving.
#
# By default, is a no-op. Can be overriden in subclasses.
# """
#
# def post_editor_saved(self, old_metadata, old_content) -> None: # pylint: disable=unused-argument
# """
# Called right *after* the block is written to the DB. Can be used, e.g., to spin up followup tasks.
#
# By default, is a no-op. Can be overriden in subclasses.
# """
#
# def studio_post_duplicate(self, store, source_block) -> bool: # pylint: disable=unused-argument
# """
# Called when a the block is duplicated. Can be used, e.g., for special handling of child duplication.
#
# Returns 'True' if children have been handled and thus shouldn't be handled by the standard
# duplication logic.
#
# By default, is a no-op. Can be overriden in subclasses.
# """
# return False
#
# def studio_post_paste(self, store, source_node) -> bool: # pylint: disable=unused-argument
# """
# Called after a block is copy-pasted. Can be used, e.g., for special handling of child duplication.
#
# Returns 'True' if children have been handled and thus shouldn't be handled by the standard
# duplication logic.
#
# By default, is a no-op. Can be overriden in subclasses.
# """
# return False


def has_author_view(block):
"""
Expand Down

0 comments on commit 78b691b

Please sign in to comment.