- % endif
+ {% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
+
+ {% endif %}
-
- ${status.display_name}
+ {{ status.display_name }}
-
+
- % if msg:
-
${HTML(msg)}
- % endif
-% if status in ['unsubmitted', 'correct', 'incorrect', 'partially-correct', 'incomplete']:
+ {% if msg %}
+
{{ msg|safe }}
+ {% endif %}
+{% if status == 'unsubmitted' or status == 'correct' or status == 'incorrect' or status == 'partially-correct' or status == 'incomplete' %}
-% endif
+{% endif %}
diff --git a/xmodule/capa/tests/helpers.py b/xmodule/capa/tests/helpers.py
index fe9064ee55..3ef3288a9c 100644
--- a/xmodule/capa/tests/helpers.py
+++ b/xmodule/capa/tests/helpers.py
@@ -8,8 +8,7 @@ import xml.sax.saxutils as saxutils
from unittest.mock import MagicMock, Mock
import fs.osfs
-from mako.lookup import TemplateLookup
-from path import Path
+from django.template.loader import get_template as django_get_template
from xmodule.capa.capa_problem import LoncapaProblem, LoncapaSystem
from xmodule.capa.inputtypes import Status
@@ -21,16 +20,14 @@ def get_template(template_name):
"""
Return template for a capa inputtype.
"""
- return TemplateLookup(
- directories=[Path(__file__).dirname().dirname() / "templates"], default_filters=["decode.utf8"]
- ).get_template(template_name)
+ return django_get_template(template_name)
def capa_render_template(template, context):
"""
Render template for a capa inputtype.
"""
- return get_template(template).render_unicode(**context)
+ return get_template(template).render(context)
def tst_render_template(template, context): # pylint: disable=unused-argument
diff --git a/xmodule/capa/tests/test_input_templates.py b/xmodule/capa/tests/test_input_templates.py
index b47f35f254..b3cee9362a 100644
--- a/xmodule/capa/tests/test_input_templates.py
+++ b/xmodule/capa/tests/test_input_templates.py
@@ -1,13 +1,13 @@
"""
-Tests for the logic in input type mako templates.
+~Tests for the logic in input type Django templates.
"""
import json
+import traceback
import unittest
from collections import OrderedDict
from lxml import etree
-from mako import exceptions
from six.moves import range
from openedx.core.djangolib.markup import HTML
@@ -18,7 +18,7 @@ from xmodule.stringify import stringify_children
class TemplateError(Exception):
"""
- Error occurred while rendering a Mako template.
+ Error occurred while rendering a Django template.
"""
pass # lint-amnesty, pylint: disable=unnecessary-pass
@@ -57,10 +57,8 @@ class TemplateTestCase(unittest.TestCase):
context_dict.setdefault("STATIC_URL", "/dummy-static/")
try:
xml_str = capa_render_template(self.TEMPLATE_NAME, context_dict)
- except:
- raise TemplateError( # lint-amnesty, pylint: disable=raise-missing-from
- exceptions.text_error_template().render()
- )
+ except Exception as exc:
+ raise TemplateError(f"
{traceback.format_exc()} ") from exc
# Attempt to construct an XML tree from the template
# This makes it easy to use XPath to make assertions, rather
@@ -232,7 +230,7 @@ class TemplateTestCase(unittest.TestCase):
class ChoiceGroupTemplateTest(TemplateTestCase):
"""
- Test mako template for `
` input.
+ Test django template for `` input.
"""
TEMPLATE_NAME = "choicegroup.html"
@@ -462,7 +460,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
class TextlineTemplateTest(TemplateTestCase):
"""
- Test mako template for `` input.
+ Test django template for `` input.
"""
TEMPLATE_NAME = "textline.html"
@@ -641,7 +639,7 @@ class FormulaEquationInputTemplateTest(TemplateTestCase):
class AnnotationInputTemplateTest(TemplateTestCase):
"""
- Test mako template for `` input.
+ Test django template for `` input.
"""
TEMPLATE_NAME = "annotationinput.html"
@@ -766,7 +764,7 @@ class AnnotationInputTemplateTest(TemplateTestCase):
class MathStringTemplateTest(TemplateTestCase):
"""
- Test mako template for `` input.
+ Test django template for `` input.
"""
TEMPLATE_NAME = "mathstring.html"
@@ -806,7 +804,7 @@ class MathStringTemplateTest(TemplateTestCase):
class OptionInputTemplateTest(TemplateTestCase):
"""
- Test mako template for `` input.
+ Test django template for `` input.
"""
TEMPLATE_NAME = "optioninput.html"
@@ -866,7 +864,7 @@ class OptionInputTemplateTest(TemplateTestCase):
class DragAndDropTemplateTest(TemplateTestCase):
"""
- Test mako template for `` input.
+ Test django template for `` input.
"""
TEMPLATE_NAME = "drag_and_drop_input.html"
@@ -911,7 +909,7 @@ class DragAndDropTemplateTest(TemplateTestCase):
class ChoiceTextGroupTemplateTest(TemplateTestCase):
- """Test mako template for `` input"""
+ """Test django template for `` input"""
TEMPLATE_NAME = "choicetext.html"
VALUE_DICT = {
@@ -1093,7 +1091,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
class ChemicalEquationTemplateTest(TemplateTestCase):
- """Test mako template for `` input"""
+ """Test django template for `` input"""
TEMPLATE_NAME = "chemicalequationinput.html"
@@ -1114,7 +1112,7 @@ class ChemicalEquationTemplateTest(TemplateTestCase):
class SchematicInputTemplateTest(TemplateTestCase):
- """Test mako template for `` input"""
+ """Test django template for `` input"""
TEMPLATE_NAME = "schematicinput.html"
@@ -1145,7 +1143,7 @@ class SchematicInputTemplateTest(TemplateTestCase):
class CodeinputTemplateTest(TemplateTestCase):
"""
- Test mako template for `` input
+ Test django template for `` input
"""
TEMPLATE_NAME = "codeinput.html"
diff --git a/xmodule/capa_block.py b/xmodule/capa_block.py
index 0ae400b434..8ca49eba97 100644
--- a/xmodule/capa_block.py
+++ b/xmodule/capa_block.py
@@ -18,6 +18,7 @@ import traceback
import nh3
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
+from django.template.loader import render_to_string
from django.utils.encoding import smart_str
from django.utils.functional import cached_property
from lxml import etree
@@ -399,6 +400,7 @@ class _BuiltInProblemBlock(
"""
Return the studio view.
"""
+ # Not converting this to django template since this method is deprecated.
fragment = Fragment(
self.runtime.service(self, "mako").render_cms_template(self.mako_template, self.get_context())
)
@@ -896,7 +898,7 @@ class _BuiltInProblemBlock(
get_python_lib_zip=sandbox_service.get_python_lib_zip,
DEBUG=self.debug,
i18n=self.runtime.service(self, "i18n"),
- render_template=self.runtime.service(self, "mako").render_template,
+ render_template=render_to_string,
resources_fs=self.runtime.resources_fs,
seed=seed, # Why do we do this if we have self.seed?
xqueue=None if is_studio else XQueueService(self),
@@ -992,7 +994,7 @@ class _BuiltInProblemBlock(
"""
curr_score, total_possible = self.get_display_progress()
- return self.runtime.service(self, "mako").render_lms_template(
+ return render_to_string(
"problem_ajax.html",
{
"element_id": self.location.html_id(),
@@ -1339,7 +1341,7 @@ class _BuiltInProblemBlock(
"submit_disabled_cta": submit_disabled_ctas[0] if submit_disabled_ctas else None,
}
- html = self.runtime.service(self, "mako").render_lms_template("problem.html", context)
+ html = render_to_string("problem.html", context)
if encapsulate:
html = HTML('{html}
').format(
@@ -1647,7 +1649,7 @@ class _BuiltInProblemBlock(
return {
"answers": new_answers,
- "correct_status_html": self.runtime.service(self, "mako").render_lms_template(
+ "correct_status_html": render_to_string(
"status_span.html", {"status": Status("correct", self.runtime.service(self, "i18n").gettext)}
),
}
diff --git a/xmodule/tests/test_capa_block.py b/xmodule/tests/test_capa_block.py
index 036f05349c..4beb2389f7 100644
--- a/xmodule/tests/test_capa_block.py
+++ b/xmodule/tests/test_capa_block.py
@@ -2277,9 +2277,10 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
assert html is not None
# assert that we got here without exploding
- def test_get_problem_html(self):
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(render_template=render_template)
+ @patch("xmodule.capa_block.render_to_string")
+ def test_get_problem_html(self, render_template):
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create()
# We've tested the show/hide button logic in other tests,
# so here we hard-wire the values
@@ -2337,11 +2338,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
"""
- def test_demand_hint(self):
+ @patch("xmodule.capa_block.render_to_string")
+ def test_demand_hint(self, render_template):
# HTML generation is mocked out to be meaningless here, so instead we check
# the context dict passed into HTML generation.
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(xml=self.demand_xml, render_template=render_template)
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create(xml=self.demand_xml)
block.get_problem_html() # ignoring html result
context = render_template.call_args[0][1]
assert context["demand_hint_possible"]
@@ -2360,7 +2362,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
assert result["hint_index"] == 0
assert result["should_enable_next_hint"]
- def test_single_demand_hint(self):
+ @patch("xmodule.capa_block.render_to_string")
+ def test_single_demand_hint(self, render_template):
"""
Test the hint button enabled state when there is just a single hint.
"""
@@ -2378,8 +2381,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
Only demand hint
"""
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(xml=test_xml, render_template=render_template)
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create(xml=test_xml)
block.get_problem_html() # ignoring html result
context = render_template.call_args[0][1]
assert context["demand_hint_possible"]
@@ -2390,7 +2393,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
assert result["hint_index"] == 0
assert not result["should_enable_next_hint"]
- def test_image_hint(self):
+ @patch("xmodule.capa_block.render_to_string")
+ def test_image_hint(self, render_template):
"""
Test the hint button shows an image without the static url.
"""
@@ -2410,8 +2414,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
You can add an optional hint like this. Problems that have a hint include a hint button, and this text appears the first time learners select the button.
"""
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(xml=test_xml, render_template=render_template)
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create(xml=test_xml)
block.get_problem_html() # ignoring html result
context = render_template.call_args[0][1]
assert context["demand_hint_possible"]
@@ -2449,14 +2453,15 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
intersection = set(block2.input_state.keys()).intersection(set(block1.input_state.keys()))
assert len(intersection) == 0
- def test_get_problem_html_error(self):
+ @patch("xmodule.capa_block.render_to_string")
+ def test_get_problem_html_error(self, render_template):
"""
In production, when an error occurs with the problem HTML
rendering, a "dummy" problem is created with an error
message to display to the user.
"""
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(render_template=render_template)
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create()
# Save the original problem so we can compare it later
original_problem = block.lcp
@@ -2478,12 +2483,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Expect that the block has created a new dummy problem with the error
assert original_problem != block.lcp
- def test_get_problem_html_error_preview(self):
+ @patch("xmodule.capa_block.render_to_string")
+ def test_get_problem_html_error_preview(self, render_template):
"""
Test the html response when an error occurs with DEBUG off in Studio.
"""
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(render_template=render_template)
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create()
# Simulate throwing an exception when the capa problem
# is asked to render itself as HTML
@@ -2503,12 +2509,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
assert error_msg in context["problem"]["html"]
@override_settings(DEBUG=True)
- def test_get_problem_html_error_w_debug(self):
+ @patch("xmodule.capa_block.render_to_string")
+ def test_get_problem_html_error_w_debug(self, render_template):
"""
Test the html response when an error occurs with DEBUG on
"""
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(render_template=render_template)
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create()
# Simulate throwing an exception when the capa problem
# is asked to render itself as HTML
@@ -2823,12 +2830,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
"",
" ",
)
- def test_problem_no_display_name(self, display_name):
+ @patch("xmodule.capa_block.render_to_string")
+ def test_problem_no_display_name(self, display_name, render_template):
"""
Verify that if problem display name is not provided then a default name is used.
"""
- render_template = Mock(return_value="Test Template HTML
")
- block = CapaFactory.create(display_name=display_name, render_template=render_template)
+ render_template.return_value = "Test Template HTML
"
+ block = CapaFactory.create(display_name=display_name)
block.get_problem_html()
render_args, _ = render_template.call_args
context = render_args[1]