diff --git a/cms/djangoapps/contentstore/views/tests/test_preview.py b/cms/djangoapps/contentstore/views/tests/test_preview.py
index 0f6786ca62..b97a1a4110 100644
--- a/cms/djangoapps/contentstore/views/tests/test_preview.py
+++ b/cms/djangoapps/contentstore/views/tests/test_preview.py
@@ -186,7 +186,7 @@ class PureXBlock(XBlock):
Renders the output that a student will see.
"""
fragment = Fragment()
- fragment.add_content(self.runtime.service(self, 'mako').render_template('edxmako.html', context))
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template('edxmako.html', context))
return fragment
diff --git a/cms/lib/xblock/authoring_mixin.py b/cms/lib/xblock/authoring_mixin.py
index bb6b742f44..a3d3b3298c 100644
--- a/cms/lib/xblock/authoring_mixin.py
+++ b/cms/lib/xblock/authoring_mixin.py
@@ -37,7 +37,7 @@ class AuthoringMixin(XBlockMixin):
"""
fragment = Fragment()
from cms.djangoapps.contentstore.utils import reverse_course_url
- fragment.add_content(self.runtime.service(self, 'mako').render_template('visibility_editor.html', {
+ fragment.add_content(self.runtime.service(self, 'mako').render_cms_template('visibility_editor.html', {
'xblock': self,
'manage_groups_url': reverse_course_url('group_configurations_list_handler', self.location.course_key),
}))
diff --git a/lms/templates/library-block-author-preview-header.html b/cms/templates/library-block-author-preview-header.html
similarity index 100%
rename from lms/templates/library-block-author-preview-header.html
rename to cms/templates/library-block-author-preview-header.html
diff --git a/common/djangoapps/edxmako/services.py b/common/djangoapps/edxmako/services.py
index 6ee2b096d6..d300e32cf7 100644
--- a/common/djangoapps/edxmako/services.py
+++ b/common/djangoapps/edxmako/services.py
@@ -1,10 +1,23 @@
"""
Supports rendering an XBlock to HTML using mako templates.
"""
-
+from django.template import engines
+from django.template.utils import InvalidTemplateEngineError
from xblock.reference.plugins import Service
from common.djangoapps.edxmako.shortcuts import render_to_string
+from common.djangoapps.edxmako import Engines
+
+try:
+ engines[Engines.PREVIEW]
+except InvalidTemplateEngineError:
+ # We are running in the CMS:
+ lms_mako_namespace = "main"
+ cms_mako_namespace = None
+else:
+ # We are running in the LMS:
+ lms_mako_namespace = "lms.main"
+ cms_mako_namespace = "main"
class MakoService(Service):
@@ -21,10 +34,41 @@ class MakoService(Service):
**kwargs
):
super().__init__(**kwargs)
+ # Set the "default" namespace prefix, in case it's not specified when render_template() is called.
self.namespace_prefix = namespace_prefix
def render_template(self, template_file, dictionary, namespace='main'):
"""
- Takes (template_file, dictionary) and returns rendered HTML.
+ DEPRECATED. Takes (template_file, dictionary) and returns rendered HTML.
+
+ Use render_lms_template or render_cms_template instead. Or better yet,
+ don't use mako templates at all. React or django templates are much
+ safer.
"""
return render_to_string(template_file, dictionary, namespace=self.namespace_prefix + namespace)
+
+ def render_lms_template(self, template_file, dictionary):
+ """
+ Render a template which is found in one of the LMS edx-platform template
+ dirs. (lms.envs.common.MAKO_TEMPLATE_DIRS_BASE)
+
+ Templates which are in these dirs will only work with this function:
+ edx-platform/lms/templates/
+ edx-platform/xmodule/capa/templates/
+ openedx/features/course_experience/templates
+ """
+ return render_to_string(template_file, dictionary, namespace=lms_mako_namespace)
+
+ def render_cms_template(self, template_file, dictionary):
+ """
+ Render a template which is found in one of the CMS edx-platform template
+ dirs. (cms.envs.common.MAKO_TEMPLATE_DIRS_BASE)
+
+ Templates which are in these dirs will only work with this function:
+ edx-platform/cms/templates/
+ common/static/
+ openedx/features/course_experience/templates
+ """
+ if cms_mako_namespace is None:
+ raise RuntimeError("Cannot access CMS templates from the LMS")
+ return render_to_string(template_file, dictionary, namespace=cms_mako_namespace)
diff --git a/lms/djangoapps/courseware/tests/test_video_mongo.py b/lms/djangoapps/courseware/tests/test_video_mongo.py
index a1a01dcfd7..452962c06f 100644
--- a/lms/djangoapps/courseware/tests/test_video_mongo.py
+++ b/lms/djangoapps/courseware/tests/test_video_mongo.py
@@ -148,7 +148,7 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests
@@ -233,7 +233,7 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests
mako_service = self.block.runtime.service(self.block, 'mako')
expected_result = get_context_dict_from_string(
- mako_service.render_template('video.html', expected_context)
+ mako_service.render_lms_template('video.html', expected_context)
)
assert get_context_dict_from_string(context) == expected_result
assert expected_result['download_video_link'] == 'example.mp4'
@@ -506,7 +506,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
def test_get_html_source(self):
# lint-amnesty, pylint: disable=invalid-name, redefined-outer-name
@@ -620,7 +620,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
def test_get_html_with_non_existent_edx_video_id(self):
"""
@@ -766,7 +766,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
def test_get_html_with_existing_edx_video_id(self):
"""
@@ -794,7 +794,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
context, expected_context = self.helper_get_html_with_edx_video_id(data)
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
def test_get_html_with_existing_unstripped_edx_video_id(self):
"""
@@ -825,7 +825,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
def encode_and_create_video(self, edx_video_id):
"""
@@ -1050,7 +1050,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
# pylint: disable=invalid-name
def test_get_html_cdn_source_external_video(self):
@@ -1156,7 +1156,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
mako_service = self.block.runtime.service(self.block, 'mako')
assert get_context_dict_from_string(context) ==\
- get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
+ get_context_dict_from_string(mako_service.render_lms_template('video.html', expected_context))
@ddt.data(
(True, ['youtube', 'desktop_webm', 'desktop_mp4', 'hls']),
@@ -2409,7 +2409,7 @@ class TestVideoWithBumper(TestVideo): # pylint: disable=test-inherits-tests
}
mako_service = self.block.runtime.service(self.block, 'mako')
- expected_content = mako_service.render_template('video.html', expected_context)
+ expected_content = mako_service.render_lms_template('video.html', expected_context)
assert get_context_dict_from_string(content) == get_context_dict_from_string(expected_content)
@@ -2506,7 +2506,7 @@ class TestAutoAdvanceVideo(TestVideo): # lint-amnesty, pylint: disable=test-inh
mako_service = self.block.runtime.service(self.block, 'mako')
with override_settings(FEATURES=self.FEATURES):
- expected_content = mako_service.render_template('video.html', expected_context)
+ expected_content = mako_service.render_lms_template('video.html', expected_context)
assert get_context_dict_from_string(content) == get_context_dict_from_string(expected_content)
diff --git a/xmodule/annotatable_block.py b/xmodule/annotatable_block.py
index 95f68d4370..e41e2b17a5 100644
--- a/xmodule/annotatable_block.py
+++ b/xmodule/annotatable_block.py
@@ -172,7 +172,7 @@ class AnnotatableBlock(
'content_html': self._render_content()
}
- return self.runtime.service(self, 'mako').render_template('annotatable.html', context)
+ return self.runtime.service(self, 'mako').render_lms_template('annotatable.html', context)
def student_view(self, context): # lint-amnesty, pylint: disable=unused-argument
"""
@@ -191,7 +191,7 @@ class AnnotatableBlock(
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_sass_to_fragment(fragment, 'AnnotatableBlockEditor.scss')
add_webpack_js_to_fragment(fragment, 'AnnotatableBlockEditor')
diff --git a/xmodule/capa_block.py b/xmodule/capa_block.py
index c991696888..94d4b2a61f 100644
--- a/xmodule/capa_block.py
+++ b/xmodule/capa_block.py
@@ -356,7 +356,7 @@ class ProblemBlock(
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_sass_to_fragment(fragment, 'ProblemBlockEditor.scss')
add_webpack_js_to_fragment(fragment, 'ProblemBlockEditor')
@@ -898,7 +898,7 @@ class ProblemBlock(
"""
curr_score, total_possible = self.get_display_progress()
- return self.runtime.service(self, 'mako').render_template('problem_ajax.html', {
+ return self.runtime.service(self, 'mako').render_lms_template('problem_ajax.html', {
'element_id': self.location.html_id(),
'id': str(self.location),
'ajax_url': self.ajax_url,
@@ -1247,7 +1247,7 @@ class ProblemBlock(
'submit_disabled_cta': submit_disabled_ctas[0] if submit_disabled_ctas else None,
}
- html = self.runtime.service(self, 'mako').render_template('problem.html', context)
+ html = self.runtime.service(self, 'mako').render_lms_template('problem.html', context)
if encapsulate:
html = HTML('
{html}
').format(
@@ -1548,7 +1548,7 @@ class ProblemBlock(
return {
'answers': new_answers,
- 'correct_status_html': self.runtime.service(self, 'mako').render_template(
+ 'correct_status_html': self.runtime.service(self, 'mako').render_lms_template(
'status_span.html',
{'status': Status('correct', self.runtime.service(self, "i18n").gettext)}
)
diff --git a/xmodule/conditional_block.py b/xmodule/conditional_block.py
index 03662deb01..78a5b8c1c1 100644
--- a/xmodule/conditional_block.py
+++ b/xmodule/conditional_block.py
@@ -223,7 +223,7 @@ class ConditionalBlock(
def get_html(self):
required_html_ids = [block.location.html_id() for block in self.get_required_blocks]
- return self.runtime.service(self, 'mako').render_template('conditional_ajax.html', {
+ return self.runtime.service(self, 'mako').render_lms_template('conditional_ajax.html', {
'element_id': self.location.html_id(),
'ajax_url': self.ajax_url,
'depends': ';'.join(required_html_ids)
@@ -249,7 +249,7 @@ class ConditionalBlock(
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_webpack_js_to_fragment(fragment, 'ConditionalBlockEditor')
shim_xmodule_js(fragment, self.studio_js_module_name)
@@ -262,7 +262,7 @@ class ConditionalBlock(
if not self.is_condition_satisfied():
context = {'module': self,
'message': self.conditional_message}
- html = self.runtime.service(self, 'mako').render_template('conditional_block.html', context)
+ html = self.runtime.service(self, 'mako').render_lms_template('conditional_block.html', context)
return json.dumps({'fragments': [{'content': html}], 'message': bool(self.conditional_message)})
fragments = [child.render(STUDENT_VIEW).to_dict() for child in self.get_children()]
diff --git a/xmodule/discussion_block.py b/xmodule/discussion_block.py
index 7433b51c9f..b5c5c01907 100644
--- a/xmodule/discussion_block.py
+++ b/xmodule/discussion_block.py
@@ -204,7 +204,7 @@ class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, XmlMixin): # lint-amn
'login_msg': login_msg,
}
fragment.add_content(
- self.runtime.service(self, 'mako').render_template('discussion/_discussion_inline.html', context)
+ self.runtime.service(self, 'mako').render_lms_template('discussion/_discussion_inline.html', context)
)
fragment.initialize_js('DiscussionInlineBlock')
@@ -216,7 +216,8 @@ class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, XmlMixin): # lint-amn
Renders author view for Studio.
"""
fragment = Fragment()
- fragment.add_content(self.runtime.service(self, 'mako').render_template(
+ # For historic reasons, this template is in the LMS templates folder:
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template(
'discussion/_discussion_inline_studio.html',
{
'discussion_id': self.discussion_id,
diff --git a/xmodule/error_block.py b/xmodule/error_block.py
index a3379007e1..9ee1d47f67 100644
--- a/xmodule/error_block.py
+++ b/xmodule/error_block.py
@@ -60,7 +60,7 @@ class ErrorBlock(
"""
Return a fragment that contains the html for the student view.
"""
- fragment = Fragment(self.runtime.service(self, 'mako').render_template('module-error.html', {
+ fragment = Fragment(self.runtime.service(self, 'mako').render_lms_template('module-error.html', {
'staff_access': True,
'data': self.contents,
'error': self.error_msg,
diff --git a/xmodule/html_block.py b/xmodule/html_block.py
index 688e515c80..6c883e1322 100644
--- a/xmodule/html_block.py
+++ b/xmodule/html_block.py
@@ -134,7 +134,7 @@ class HtmlBlockMixin( # lint-amnesty, pylint: disable=abstract-method
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_sass_to_fragment(fragment, 'HtmlBlockEditor.scss')
add_webpack_js_to_fragment(fragment, 'HtmlBlockEditor')
@@ -463,7 +463,7 @@ class CourseInfoBlock(CourseInfoFields, HtmlBlockMixin): # lint-amnesty, pylint
'visible_updates': course_updates[:3],
'hidden_updates': course_updates[3:],
}
- return self.runtime.service(self, 'mako').render_template(
+ return self.runtime.service(self, 'mako').render_lms_template(
f"{self.TEMPLATE_DIR}/course_updates.html",
context,
)
diff --git a/xmodule/library_content_block.py b/xmodule/library_content_block.py
index 047d36abca..dd8b731127 100644
--- a/xmodule/library_content_block.py
+++ b/xmodule/library_content_block.py
@@ -391,7 +391,7 @@ class LibraryContentBlock(
'content': rendered_child.content,
})
- fragment.add_content(self.runtime.service(self, 'mako').render_template('vert_module.html', {
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template('vert_module.html', {
'items': contents,
'xblock_context': context,
'show_bookmark_button': False,
@@ -421,7 +421,7 @@ class LibraryContentBlock(
if max_count < 0:
max_count = len(self.children)
- fragment.add_content(self.runtime.service(self, 'mako').render_template(
+ fragment.add_content(self.runtime.service(self, 'mako').render_cms_template(
"library-block-author-preview-header.html", {
'max_count': max_count,
'display_name': self.display_name or self.url_name,
@@ -442,7 +442,7 @@ class LibraryContentBlock(
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_webpack_js_to_fragment(fragment, 'LibraryContentBlockEditor')
shim_xmodule_js(fragment, self.studio_js_module_name)
diff --git a/xmodule/library_root_xblock.py b/xmodule/library_root_xblock.py
index 70fb993ba9..cfe2ba6276 100644
--- a/xmodule/library_root_xblock.py
+++ b/xmodule/library_root_xblock.py
@@ -104,7 +104,8 @@ class LibraryRoot(XBlock):
})
fragment.add_content(
- self.runtime.service(self, 'mako').render_template("studio_render_paged_children_view.html", {
+ # For historic reasons, this template is in the LMS folder, and some external code may depend on that.
+ self.runtime.service(self, 'mako').render_lms_template("studio_render_paged_children_view.html", {
'items': contents,
'xblock_context': context,
'can_add': can_add,
diff --git a/xmodule/lti_block.py b/xmodule/lti_block.py
index 4228aec743..7705a7321b 100644
--- a/xmodule/lti_block.py
+++ b/xmodule/lti_block.py
@@ -381,7 +381,7 @@ class LTIBlock(
# Add our specific template information (the raw data body)
context.update({'data': self.data})
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, context)
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, context)
)
add_sass_to_fragment(fragment, 'LTIBlockEditor.scss')
add_webpack_js_to_fragment(fragment, 'LTIBlockEditor')
@@ -498,7 +498,7 @@ class LTIBlock(
Return the student view.
"""
fragment = Fragment()
- fragment.add_content(self.runtime.service(self, 'mako').render_template('lti.html', self.get_context()))
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template('lti.html', self.get_context()))
add_webpack_js_to_fragment(fragment, 'LTIBlockDisplay')
shim_xmodule_js(fragment, 'LTI')
return fragment
@@ -508,7 +508,7 @@ class LTIBlock(
"""
This is called to get context with new oauth params to iframe.
"""
- template = self.runtime.service(self, 'mako').render_template('lti_form.html', self.get_context())
+ template = self.runtime.service(self, 'mako').render_lms_template('lti_form.html', self.get_context())
return Response(template, content_type='text/html')
def get_user_id(self):
diff --git a/xmodule/poll_block.py b/xmodule/poll_block.py
index c4d9372883..f09889f506 100644
--- a/xmodule/poll_block.py
+++ b/xmodule/poll_block.py
@@ -135,7 +135,7 @@ class PollBlock(
'ajax_url': self.ajax_url,
'configuration_json': self.dump_poll(),
}
- fragment.add_content(self.runtime.service(self, 'mako').render_template('poll.html', params))
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template('poll.html', params))
add_sass_to_fragment(fragment, 'PollBlockDisplay.scss')
add_webpack_js_to_fragment(fragment, 'PollBlockDisplay')
shim_xmodule_js(fragment, 'Poll')
diff --git a/xmodule/seq_block.py b/xmodule/seq_block.py
index 5561d034da..1faa487808 100644
--- a/xmodule/seq_block.py
+++ b/xmodule/seq_block.py
@@ -516,7 +516,7 @@ class SequenceBlock(
if not self._can_user_view_content(course):
banner_text = self._hidden_content_banner_text(course)
- hidden_content_html = self.runtime.service(self, 'mako').render_template(
+ hidden_content_html = self.runtime.service(self, 'mako').render_lms_template(
'hidden_content.html',
{
'self_paced': course.self_paced,
@@ -589,7 +589,7 @@ class SequenceBlock(
parent_block_id = self.get_parent().scope_ids.usage_id.block_id
params['chapter_completion_aggregator_url'] = '/'.join(
[settings.COMPLETION_AGGREGATOR_URL, str(self.scope_ids.usage_id.context_key), parent_block_id]) + '/'
- fragment.add_content(self.runtime.service(self, 'mako').render_template("seq_block.html", params))
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template("seq_block.html", params))
self._capture_full_seq_item_metrics(children)
self._capture_current_unit_metrics(children)
diff --git a/xmodule/split_test_block.py b/xmodule/split_test_block.py
index 8984dc62db..88b51db19b 100644
--- a/xmodule/split_test_block.py
+++ b/xmodule/split_test_block.py
@@ -282,7 +282,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
sorted_inactive_contents = sorted(inactive_contents, key=itemgetter('group_name'))
# Use the new template
- fragment.add_content(self.runtime.service(self, 'mako').render_template('split_test_staff_view.html', {
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template('split_test_staff_view.html', {
'items': sorted_active_contents + sorted_inactive_contents,
}))
fragment.add_css('.split-test-child { display: none; }')
@@ -309,7 +309,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
fragment, inactive_children, context
)
- fragment.add_content(self.runtime.service(self, 'mako').render_template('split_test_author_view.html', {
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template('split_test_author_view.html', {
'split_test': self,
'is_root': is_root,
'is_configured': self.is_configured,
@@ -348,7 +348,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_webpack_js_to_fragment(fragment, 'SplitTestBlockEditor')
shim_xmodule_js(fragment, self.studio_js_module_name)
@@ -367,7 +367,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
return self._staff_view(context)
else:
child_fragment = self.child.render(STUDENT_VIEW, context)
- fragment = Fragment(self.runtime.service(self, 'mako').render_template('split_test_student_view.html', {
+ fragment = Fragment(self.runtime.service(self, 'mako').render_lms_template('split_test_student_view.html', {
'child_content': child_fragment.content,
'child_id': self.child.scope_ids.usage_id,
}))
diff --git a/xmodule/studio_editable.py b/xmodule/studio_editable.py
index 844f0f446c..4bb7a130b1 100644
--- a/xmodule/studio_editable.py
+++ b/xmodule/studio_editable.py
@@ -33,10 +33,9 @@ class StudioEditableBlock(XBlockMixin):
'content': rendered_child.content
})
- # 'lms.' namespace_prefix is required for rendering in studio
mako_service = self.runtime.service(self, 'mako')
- mako_service.namespace_prefix = 'lms.'
- fragment.add_content(mako_service.render_template("studio_render_children_view.html", { # pylint: disable=no-member
+ # For historic reasons, this template is in the LMS folder, and some code like xblock-utils expects that.
+ fragment.add_content(mako_service.render_lms_template("studio_render_children_view.html", { # pylint: disable=no-member
'items': contents,
'xblock_context': context,
'can_add': can_add,
diff --git a/xmodule/template_block.py b/xmodule/template_block.py
index fd53733860..c481371253 100644
--- a/xmodule/template_block.py
+++ b/xmodule/template_block.py
@@ -67,7 +67,7 @@ class CustomTagBlock(CustomTagTemplateBlock): # pylint: disable=abstract-method
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_sass_to_fragment(fragment, 'CustomTagBlockEditor.scss')
add_webpack_js_to_fragment(fragment, 'CustomTagBlockEditor')
diff --git a/xmodule/tests/helpers.py b/xmodule/tests/helpers.py
index bfe5297c2a..480771b417 100644
--- a/xmodule/tests/helpers.py
+++ b/xmodule/tests/helpers.py
@@ -56,6 +56,18 @@ class StubMakoService:
"""
return self._render_template(*args, **kwargs)
+ def render_lms_template(self, *args, **kwargs):
+ """
+ Invokes the configured render_template method.
+ """
+ return self._render_template(*args, **kwargs)
+
+ def render_cms_template(self, *args, **kwargs):
+ """
+ Invokes the configured render_template method.
+ """
+ return self._render_template(*args, **kwargs)
+
class StubUserService(UserService):
"""
diff --git a/xmodule/tests/test_conditional.py b/xmodule/tests/test_conditional.py
index 81eecd0938..d1fcde0c75 100644
--- a/xmodule/tests/test_conditional.py
+++ b/xmodule/tests/test_conditional.py
@@ -162,7 +162,7 @@ class ConditionalBlockBasicTest(unittest.TestCase):
# we reverse it here
html = blocks['cond_block'].render(STUDENT_VIEW).content
mako_service = blocks['cond_block'].runtime.service(blocks['cond_block'], 'mako')
- expected = mako_service.render_template('conditional_ajax.html', {
+ expected = mako_service.render_lms_template('conditional_ajax.html', {
'ajax_url': blocks['cond_block'].ajax_url,
'element_id': 'i4x-edX-conditional_test-conditional-SampleConditional',
'depends': 'i4x-edX-conditional_test-problem-SampleProblem',
@@ -243,7 +243,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
block = self.get_block_for_location(location)
html = block.render(STUDENT_VIEW).content
mako_service = block.runtime.service(block, 'mako')
- html_expect = mako_service.render_template(
+ html_expect = mako_service.render_lms_template(
'conditional_ajax.html',
{
# Test ajax url is just usage-id / handler_name
diff --git a/xmodule/tests/test_html_block.py b/xmodule/tests/test_html_block.py
index 9b769b252a..8cca7acc04 100644
--- a/xmodule/tests/test_html_block.py
+++ b/xmodule/tests/test_html_block.py
@@ -316,7 +316,7 @@ class CourseInfoBlockTestCase(unittest.TestCase):
template_name = f"{info_block.TEMPLATE_DIR}/course_updates.html"
info_block.get_html()
# Assertion to validate that render function is called with the expected context
- info_block.runtime.service(info_block, 'mako').render_template.assert_called_once_with(
+ info_block.runtime.service(info_block, 'mako').render_lms_template.assert_called_once_with(
template_name,
expected_context
)
diff --git a/xmodule/vertical_block.py b/xmodule/vertical_block.py
index 11904cfdb3..d6a19353b2 100644
--- a/xmodule/vertical_block.py
+++ b/xmodule/vertical_block.py
@@ -161,7 +161,8 @@ class VerticalBlock(
child_context['username'], str(self.location)), # pylint: disable=no-member
})
- fragment.add_content(self.runtime.service(self, 'mako').render_template('vert_module.html', fragment_context))
+ mako_service = self.runtime.service(self, 'mako')
+ fragment.add_content(mako_service.render_lms_template('vert_module.html', fragment_context))
add_webpack_js_to_fragment(fragment, 'VerticalStudentView')
fragment.initialize_js('VerticalStudentView')
diff --git a/xmodule/video_block/video_block.py b/xmodule/video_block/video_block.py
index 5bf2b3c28c..ef290349b4 100644
--- a/xmodule/video_block/video_block.py
+++ b/xmodule/video_block/video_block.py
@@ -258,7 +258,7 @@ class VideoBlock(
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_sass_to_fragment(fragment, 'VideoBlockEditor.scss')
add_webpack_js_to_fragment(fragment, 'VideoBlockEditor')
@@ -498,7 +498,7 @@ class VideoBlock(
organization=organization
)
- return self.runtime.service(self, 'mako').render_template('video.html', template_context)
+ return self.runtime.service(self, 'mako').render_lms_template('video.html', template_context)
def get_course_video_sharing_override(self):
"""
diff --git a/xmodule/word_cloud_block.py b/xmodule/word_cloud_block.py
index 6a31da5ef8..26a2c38c5c 100644
--- a/xmodule/word_cloud_block.py
+++ b/xmodule/word_cloud_block.py
@@ -253,7 +253,7 @@ class WordCloudBlock( # pylint: disable=abstract-method
Renders the output that a student will see.
"""
fragment = Fragment()
- fragment.add_content(self.runtime.service(self, 'mako').render_template('word_cloud.html', {
+ fragment.add_content(self.runtime.service(self, 'mako').render_lms_template('word_cloud.html', {
'ajax_url': self.ajax_url,
'display_name': self.display_name,
'instructions': self.instructions,
@@ -279,7 +279,7 @@ class WordCloudBlock( # pylint: disable=abstract-method
Return the studio view.
"""
fragment = Fragment(
- self.runtime.service(self, 'mako').render_template(self.mako_template, self.get_context())
+ self.runtime.service(self, 'mako').render_cms_template(self.mako_template, self.get_context())
)
add_webpack_js_to_fragment(fragment, 'WordCloudBlockEditor')
shim_xmodule_js(fragment, self.studio_js_module_name)