Skip to content

Commit 21399b4

Browse files
authored
fix: recurse through pasted block data to replace static paths (#36723)
Fixes an error that is triggered when trying to copy/pasting Drag-and-drop block into Courses. When a block is pasted into a Course or Library, we perform a search/replace on block's data to replace any old static URLs with their new path. Ordinary blocks like HTML and Video have a simple string of data where static URLs may live, but DnDv2 blocks have a dict of data which can contain other dicts and lists of strings that need to be modified. Other XBlocks may have similarly complex structures, and so this fix will resolve them as well. This fixes the issue by recursing into the data structure to locate all the strings where replacements may need to be made. This fix helps Course Authors use content staging in their Courses.
1 parent 91247fa commit 21399b4

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

cms/djangoapps/contentstore/helpers.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ def _insert_static_files_into_downstream_xblock(
315315
if hasattr(downstream_xblock, "data") and substitutions:
316316
data_with_substitutions = downstream_xblock.data
317317
for old_static_ref, new_static_ref in substitutions.items():
318-
data_with_substitutions = data_with_substitutions.replace(
318+
data_with_substitutions = _replace_strings(
319+
data_with_substitutions,
319320
old_static_ref,
320321
new_static_ref,
321322
)
@@ -325,6 +326,26 @@ def _insert_static_files_into_downstream_xblock(
325326
return notices
326327

327328

329+
def _replace_strings(obj: dict | list | str, old_str: str, new_str: str):
330+
"""
331+
Replacing any instances of the given `old_str` string with `new_str` in any strings found in the the given object.
332+
333+
Returns the updated object.
334+
"""
335+
if isinstance(obj, dict):
336+
for key, value in obj.items():
337+
obj[key] = _replace_strings(value, old_str, new_str)
338+
339+
elif isinstance(obj, list):
340+
for index, item in enumerate(obj):
341+
obj[index] = _replace_strings(item, old_str, new_str)
342+
343+
elif isinstance(obj, str):
344+
return obj.replace(old_str, new_str)
345+
346+
return obj
347+
348+
328349
def import_staged_content_from_user_clipboard(parent_key: UsageKey, request) -> tuple[XBlock | None, StaticFileNotices]:
329350
"""
330351
Import a block (along with its children and any required static assets) from

0 commit comments

Comments
 (0)