forked from openedx/edx-platform
-
Notifications
You must be signed in to change notification settings - Fork 2
/
mako_block.py
75 lines (61 loc) · 2.59 KB
/
mako_block.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"""
Code to handle mako templating for XModules and XBlocks.
"""
from web_fragments.fragment import Fragment
from .x_module import DescriptorSystem, shim_xmodule_js
class MakoDescriptorSystem(DescriptorSystem): # lint-amnesty, pylint: disable=abstract-method
"""
Descriptor system that renders mako templates.
"""
def __init__(self, render_template, **kwargs):
super().__init__(**kwargs)
self.render_template = render_template
# Add the MakoService to the runtime services.
# If it already exists, do not attempt to reinitialize it; otherwise, this could override the `namespace_prefix`
# of the `MakoService`, breaking template rendering in Studio.
#
# This is not needed by most XBlocks, because the MakoService is added to their runtimes.
# However, there are a few cases where the MakoService is not added to the XBlock's
# runtime. Specifically:
# * in the Instructor Dashboard bulk emails tab, when rendering the HtmlBlock for its WYSIWYG editor.
# * during testing, when fetching factory-created blocks.
if 'mako' not in self._services:
from common.djangoapps.edxmako.services import MakoService
self._services['mako'] = MakoService()
class MakoTemplateBlockBase:
"""
XBlock intended as a mixin that uses a mako template
to specify the block html.
Expects the descriptor to have the `mako_template` attribute set
with the name of the template to render, and it will pass
the descriptor as the `module` parameter to that template
"""
# pylint: disable=no-member
js_module_name = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if getattr(self.runtime, 'render_template', None) is None:
raise TypeError(
'{runtime} must have a render_template function'
' in order to use a MakoDescriptor'.format(
runtime=self.runtime,
)
)
def get_context(self):
"""
Return the context to render the mako template with
"""
return {
'module': self,
'editable_metadata_fields': self.editable_metadata_fields
}
def studio_view(self, context): # pylint: disable=unused-argument
"""
View used in Studio.
"""
# pylint: disable=no-member
fragment = Fragment(
self.runtime.render_template(self.mako_template, self.get_context())
)
shim_xmodule_js(fragment, self.js_module_name)
return fragment