Merge pull request #1221 from cpennington/lms-xblock-css-js
Put XBlock css and javascript onto the LMS courseware page
This commit is contained in:
@@ -7,6 +7,7 @@ from xmodule.seq_module import SequenceDescriptor
|
||||
from lxml import etree
|
||||
|
||||
from xblock.fields import Scope, Integer
|
||||
from xblock.fragment import Fragment
|
||||
|
||||
log = logging.getLogger('mitx.' + __name__)
|
||||
|
||||
@@ -77,12 +78,12 @@ class RandomizeModule(RandomizeFields, XModule):
|
||||
return [self.child_descriptor]
|
||||
|
||||
|
||||
def get_html(self):
|
||||
def student_view(self, context):
|
||||
if self.child is None:
|
||||
# raise error instead? In fact, could complain on descriptor load...
|
||||
return u"<div>Nothing to randomize between</div>"
|
||||
return Fragment(content=u"<div>Nothing to randomize between</div>")
|
||||
|
||||
return self.child.render('student_view').content
|
||||
return self.child.render('student_view', context)
|
||||
|
||||
def get_icon_class(self):
|
||||
return self.child.get_icon_class() if self.child else 'other'
|
||||
|
||||
@@ -9,6 +9,7 @@ from xmodule.x_module import XModule
|
||||
from xmodule.progress import Progress
|
||||
from xmodule.exceptions import NotFoundError
|
||||
from xblock.fields import Integer, Scope
|
||||
from xblock.fragment import Fragment
|
||||
from pkg_resources import resource_string
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -43,12 +44,6 @@ class SequenceModule(SequenceFields, XModule):
|
||||
if getattr(self.system, 'position', None) is not None:
|
||||
self.position = int(self.system.position)
|
||||
|
||||
self.rendered = False
|
||||
|
||||
def get_html(self):
|
||||
self.render()
|
||||
return self.content
|
||||
|
||||
def get_progress(self):
|
||||
''' Return the total progress, adding total done and total available.
|
||||
(assumes that each submodule uses the same "units" for progress.)
|
||||
@@ -66,20 +61,24 @@ class SequenceModule(SequenceFields, XModule):
|
||||
return json.dumps({'success': True})
|
||||
raise NotFoundError('Unexpected dispatch type')
|
||||
|
||||
def render(self):
|
||||
def student_view(self, context):
|
||||
# If we're rendering this sequence, but no position is set yet,
|
||||
# default the position to the first element
|
||||
if self.position is None:
|
||||
self.position = 1
|
||||
|
||||
if self.rendered:
|
||||
return
|
||||
## Returns a set of all types of all sub-children
|
||||
contents = []
|
||||
|
||||
fragment = Fragment()
|
||||
|
||||
for child in self.get_display_items():
|
||||
progress = child.get_progress()
|
||||
rendered_child = child.render('student_view', context)
|
||||
fragment.add_frag_resources(rendered_child)
|
||||
|
||||
childinfo = {
|
||||
'content': child.render('student_view').content,
|
||||
'content': rendered_child.content,
|
||||
'title': "\n".join(
|
||||
grand_child.display_name
|
||||
for grand_child in child.get_children()
|
||||
@@ -98,11 +97,12 @@ class SequenceModule(SequenceFields, XModule):
|
||||
'element_id': self.location.html_id(),
|
||||
'item_id': self.id,
|
||||
'position': self.position,
|
||||
'tag': self.location.category
|
||||
'tag': self.location.category,
|
||||
}
|
||||
|
||||
self.content = self.system.render_template('seq_module.html', params)
|
||||
self.rendered = True
|
||||
fragment.add_content(self.system.render_template('seq_module.html', params))
|
||||
|
||||
return fragment
|
||||
|
||||
def get_icon_class(self):
|
||||
child_classes = set(child.get_icon_class()
|
||||
|
||||
@@ -12,7 +12,7 @@ from mock import Mock
|
||||
from xblock.field_data import DictFieldData
|
||||
from xblock.fields import ScopeIds
|
||||
|
||||
from xmodule.x_module import ModuleSystem
|
||||
from xmodule.x_module import ModuleSystem, XModule, XModuleDescriptor
|
||||
from xmodule.mako_module import MakoDescriptorSystem
|
||||
from xmodule.annotatable_module import AnnotatableDescriptor
|
||||
from xmodule.capa_module import CapaDescriptor
|
||||
@@ -143,6 +143,10 @@ class TestStudentView(TestXBlockWrapper):
|
||||
# Check that when an xmodule is instantiated from descriptor_cls
|
||||
# it generates the same thing from student_view that it does from get_html
|
||||
def check_student_view_leaf_node(self, descriptor_cls):
|
||||
|
||||
if descriptor_cls.module_class.student_view != XModule.student_view:
|
||||
raise SkipTest(descriptor_cls.__name__ + " implements student_view")
|
||||
|
||||
descriptor = self.leaf_module(descriptor_cls)
|
||||
assert_equal(
|
||||
descriptor._xmodule.get_html(),
|
||||
@@ -165,6 +169,10 @@ class TestStudentView(TestXBlockWrapper):
|
||||
# with only xmodule children, it generates the same html from student_view
|
||||
# as it does using get_html
|
||||
def check_student_view_container_node_xmodules_only(self, descriptor_cls):
|
||||
|
||||
if descriptor_cls.module_class.student_view != XModule.student_view:
|
||||
raise SkipTest(descriptor_cls.__name__ + " implements student_view")
|
||||
|
||||
descriptor = self.container_module(descriptor_cls, 2)
|
||||
assert_equal(
|
||||
descriptor._xmodule.get_html(),
|
||||
@@ -197,7 +205,10 @@ class TestStudioView(TestXBlockWrapper):
|
||||
# it generates the same thing from studio_view that it does from get_html
|
||||
def check_studio_view_leaf_node(self, descriptor_cls):
|
||||
if descriptor_cls in NOT_STUDIO_EDITABLE:
|
||||
raise SkipTest(descriptor_cls.__name__ + "is not editable in studio")
|
||||
raise SkipTest(descriptor_cls.__name__ + " is not editable in studio")
|
||||
|
||||
if descriptor_cls.studio_view != XModuleDescriptor.studio_view:
|
||||
raise SkipTest(descriptor_cls.__name__ + " implements studio_view")
|
||||
|
||||
descriptor = self.leaf_descriptor(descriptor_cls)
|
||||
assert_equal(descriptor.get_html(), descriptor.render('studio_view').content)
|
||||
@@ -222,6 +233,9 @@ class TestStudioView(TestXBlockWrapper):
|
||||
if descriptor_cls in NOT_STUDIO_EDITABLE:
|
||||
raise SkipTest(descriptor_cls.__name__ + "is not editable in studio")
|
||||
|
||||
if descriptor_cls.studio_view != XModuleDescriptor.studio_view:
|
||||
raise SkipTest(descriptor_cls.__name__ + " implements studio_view")
|
||||
|
||||
descriptor = self.container_descriptor(descriptor_cls, 2)
|
||||
assert_equal(descriptor.get_html(), descriptor.render('studio_view').content)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from xmodule.x_module import XModule
|
||||
from xmodule.progress import Progress
|
||||
from xmodule.exceptions import NotFoundError
|
||||
from xblock.fields import Float, String, Boolean, Scope
|
||||
from xblock.fragment import Fragment
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -84,14 +85,14 @@ class TimeLimitModule(TimeLimitFields, XModule):
|
||||
def get_remaining_time_in_ms(self):
|
||||
return int((self.ending_at - time()) * 1000)
|
||||
|
||||
def get_html(self):
|
||||
def student_view(self, context):
|
||||
# assumes there is one and only one child, so it only renders the first child
|
||||
children = self.get_display_items()
|
||||
if children:
|
||||
child = children[0]
|
||||
return child.render('student_view').content
|
||||
return child.render('student_view', context)
|
||||
else:
|
||||
return u""
|
||||
return Fragment()
|
||||
|
||||
def get_progress(self):
|
||||
''' Return the total progress, adding total done and total available.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from xblock.fragment import Fragment
|
||||
from xmodule.x_module import XModule
|
||||
from xmodule.seq_module import SequenceDescriptor
|
||||
from xmodule.progress import Progress
|
||||
@@ -17,18 +18,24 @@ class VerticalModule(VerticalFields, XModule):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
XModule.__init__(self, *args, **kwargs)
|
||||
self.contents = None
|
||||
|
||||
def get_html(self):
|
||||
if self.contents is None:
|
||||
self.contents = [{
|
||||
def student_view(self, context):
|
||||
fragment = Fragment()
|
||||
contents = []
|
||||
|
||||
for child in self.get_display_items():
|
||||
rendered_child = child.render('student_view', context)
|
||||
fragment.add_frag_resources(rendered_child)
|
||||
|
||||
contents.append({
|
||||
'id': child.id,
|
||||
'content': child.render('student_view').content
|
||||
} for child in self.get_display_items()]
|
||||
'content': rendered_child.content
|
||||
})
|
||||
|
||||
return self.system.render_template('vert_module.html', {
|
||||
'items': self.contents
|
||||
})
|
||||
fragment.add_content(self.system.render_template('vert_module.html', {
|
||||
'items': contents
|
||||
}))
|
||||
return fragment
|
||||
|
||||
def get_progress(self):
|
||||
# TODO: Cache progress or children array?
|
||||
|
||||
@@ -31,6 +31,7 @@ from django_comment_client.utils import get_discussion_title
|
||||
|
||||
from student.models import UserTestGroup, CourseEnrollment
|
||||
from util.cache import cache, cache_if_anonymous
|
||||
from xblock.fragment import Fragment
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError, NoPathToItem
|
||||
@@ -327,7 +328,7 @@ def index(request, course_id, chapter=None, section=None,
|
||||
'COURSE_TITLE': course.display_name_with_default,
|
||||
'course': course,
|
||||
'init': '',
|
||||
'content': '',
|
||||
'fragment': Fragment(),
|
||||
'staff_access': staff_access,
|
||||
'masquerade': masq,
|
||||
'xqa_server': settings.MITX_FEATURES.get('USE_XQA_SERVER', 'http://xqa:server@content-qa.mitx.mit.edu/xqa')
|
||||
@@ -395,7 +396,7 @@ def index(request, course_id, chapter=None, section=None,
|
||||
|
||||
# check here if this section *is* a timed module.
|
||||
if section_module.category == 'timelimit':
|
||||
timer_context = update_timelimit_module(user, course_id, student_module_cache,
|
||||
timer_context = update_timelimit_module(user, course_id, section_field_data_cache,
|
||||
section_descriptor, section_module)
|
||||
if 'timer_expiration_duration' in timer_context:
|
||||
context.update(timer_context)
|
||||
@@ -407,7 +408,7 @@ def index(request, course_id, chapter=None, section=None,
|
||||
# add in the appropriate timer information to the rendering context:
|
||||
context.update(check_for_active_timelimit_module(request, course_id, course))
|
||||
|
||||
context['content'] = section_module.render('student_view').content
|
||||
context['fragment'] = section_module.render('student_view')
|
||||
else:
|
||||
# section is none, so display a message
|
||||
prev_section = get_current_child(chapter_module)
|
||||
@@ -417,11 +418,15 @@ def index(request, course_id, chapter=None, section=None,
|
||||
prev_section_url = reverse('courseware_section', kwargs={'course_id': course_id,
|
||||
'chapter': chapter_descriptor.url_name,
|
||||
'section': prev_section.url_name})
|
||||
context['content'] = render_to_string('courseware/welcome-back.html',
|
||||
{'course': course,
|
||||
'chapter_module': chapter_module,
|
||||
'prev_section': prev_section,
|
||||
'prev_section_url': prev_section_url})
|
||||
context['fragment'] = Fragment(content=render_to_string(
|
||||
'courseware/welcome-back.html',
|
||||
{
|
||||
'course': course,
|
||||
'chapter_module': chapter_module,
|
||||
'prev_section': prev_section,
|
||||
'prev_section_url': prev_section_url
|
||||
}
|
||||
))
|
||||
|
||||
result = render_to_response('courseware/courseware.html', context)
|
||||
except Exception as e:
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
## all needs to stay together for the Candy.js plugin to work.
|
||||
<link rel="stylesheet" href="${static.url('candy_res/candy_full.css')}" />
|
||||
% endif
|
||||
${fragment.head_html()}
|
||||
</%block>
|
||||
|
||||
<%block name="js_extra">
|
||||
@@ -150,6 +151,8 @@
|
||||
</script>
|
||||
% endif
|
||||
|
||||
${fragment.foot_html()}
|
||||
|
||||
</%block>
|
||||
|
||||
% if timer_expiration_duration:
|
||||
@@ -185,7 +188,7 @@
|
||||
% endif
|
||||
|
||||
<section class="course-content">
|
||||
${content}
|
||||
${fragment.body_html()}
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user