Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [AXIMST-28] expose editor for advanced xblocks #2528

Merged
merged 8 commits into from
Apr 9, 2024
114 changes: 113 additions & 1 deletion cms/djangoapps/contentstore/views/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from web_fragments.fragment import Fragment

from cms.lib.xblock.authoring_mixin import VISIBILITY_VIEW
from common.djangoapps.edxmako.shortcuts import render_to_string
from common.djangoapps.edxmako.shortcuts import render_to_response, render_to_string
from common.djangoapps.student.auth import (
has_studio_read_access,
has_studio_write_access,
Expand Down Expand Up @@ -300,6 +300,118 @@ def xblock_view_handler(request, usage_key_string, view_name):
return HttpResponse(status=406)


@require_http_methods("GET")
@login_required
def partial_edit_view_xblock(request, usage_key_string):
GlugovGrGlib marked this conversation as resolved.
Show resolved Hide resolved
"""
The restful handler for requests for rendered xblock views.
"""
usage_key = usage_key_with_run(usage_key_string)
if not has_studio_read_access(request.user, usage_key.course_key):
raise PermissionDenied()

store = modulestore()
xblock = store.get_item(usage_key)

# wrap the generated fragment in the xmodule_editor div so that the javascript
# can bind to it correctly
xblock.runtime.wrappers.append(
partial(
wrap_xblock,
"StudioRuntime",
usage_id_serializer=str,
request_token=request_token(request),
)
)

xblock.runtime.wrappers_asides.append(
partial(
wrap_xblock_aside,
"StudioRuntime",
usage_id_serializer=str,
request_token=request_token(request),
extra_classes=["wrapper-comp-plugins"],
)
)

load_services_for_studio(xblock.runtime, request.user)

# try:
GlugovGrGlib marked this conversation as resolved.
Show resolved Hide resolved
studio_fragment = xblock.render("studio_view")
# catch exceptions indiscriminately, since after this point they escape the
# dungeon and surface as uneditable, unsaveable, and undeletable
# component-goblins.
# except Exception as exc: # pylint: disable=broad-except
# log.debug(
# "Unable to render %s for %r", "STUDIO_VIEW", xblock, exc_info=True
# )
# fragment = Fragment(
# render_to_string("html_error.html", {"message": str(exc)})
# )

can_edit = has_studio_write_access(request.user, usage_key.course_key)

# Determine the items to be shown as reorderable. Note that the view
# 'reorderable_container_child_preview' is only rendered for xblocks that
# are being shown in a reorderable container, so the xblock is automatically
# added to the list.
# reorderable_items = set()

force_render = request.GET.get("force_render", None)

# Fetch tags of children components
tags_count_map = {}
if use_tagging_taxonomy_list_page():
tags_count_map = get_children_tags_count(xblock)

# Set up the context to be passed to each XBlock's render method.
context = request.GET.dict()
context.update(
{
# This setting disables the recursive wrapping of xblocks
"is_pages_view": True,
"is_unit_page": is_unit(xblock),
"can_edit": can_edit,
"root_xblock": None,
"reorderable_items": None,
"paging": None,
"force_render": force_render,
"item_url": "/container/{usage_key}",
"tags_count_map": tags_count_map,
}
)
wrapper_fragment = get_preview_fragment(request, xblock, context)

# Note that the container view recursively adds headers into the preview fragment,
# so only the "Pages" view requires that this extra wrapper be included.
display_label = xblock.display_name or xblock.scope_ids.block_type
if not xblock.display_name and xblock.scope_ids.block_type == "html":
display_label = _("Text")
wrapper_fragment.content = render_to_string(
GlugovGrGlib marked this conversation as resolved.
Show resolved Hide resolved
"component.html",
{
"xblock_context": context,
"xblock": xblock,
"locator": usage_key,
"preview": wrapper_fragment.content,
"label": display_label,
},
)

from ..utils import get_container_handler_context # pylint: disable=import-outside-toplevel
GlugovGrGlib marked this conversation as resolved.
Show resolved Hide resolved
from .component import _get_item_in_course # pylint: disable=import-outside-toplevel

usage_key = usage_key_with_run(usage_key_string)
with modulestore().bulk_operations(usage_key.course_key):
course, xblock, lms_link, preview_lms_link = _get_item_in_course(request, usage_key)

container_handler_context = get_container_handler_context(request, usage_key, course, xblock)
container_handler_context.update({
GlugovGrGlib marked this conversation as resolved.
Show resolved Hide resolved
"studio_fragment": studio_fragment,
})
return render_to_response('container_editor.html', container_handler_context)


@require_http_methods("GET")
@login_required
@expect_json
Expand Down
Loading
Loading