Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions common/lib/xmodule/xmodule/randomize_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from lxml import etree

from xblock.fields import Scope, Integer
from xblock.fragment import Fragment

log = logging.getLogger('mitx.' + __name__)

Expand Down Expand Up @@ -77,12 +78,12 @@ def get_child_descriptors(self):
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'
Expand Down
26 changes: 13 additions & 13 deletions common/lib/xmodule/xmodule/seq_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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__)
Expand Down Expand Up @@ -43,12 +44,6 @@ def __init__(self, *args, **kwargs):
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.)
Expand All @@ -66,20 +61,24 @@ def handle_ajax(self, dispatch, data): # TODO: bounds checking
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()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this used to cache its rendering? Seems silly: it will only be accessed once.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it was silly (at least in my mind).

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()
Expand All @@ -98,11 +97,12 @@ def render(self):
'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()
Expand Down
18 changes: 16 additions & 2 deletions common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
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
Expand Down Expand Up @@ -143,6 +143,10 @@ def test_student_view_leaf_node(self):
# 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(),
Expand All @@ -165,6 +169,10 @@ def test_student_view_container_node(self):
# 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(),
Expand Down Expand Up @@ -197,7 +205,10 @@ def test_studio_view_leaf_node(self):
# 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)
Expand All @@ -222,6 +233,9 @@ def check_studio_view_container_node_xmodules_only(self, descriptor_cls):
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)

Expand Down
7 changes: 4 additions & 3 deletions common/lib/xmodule/xmodule/timelimit_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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__)
Expand Down Expand Up @@ -84,14 +85,14 @@ def begin(self, duration):
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.
Expand Down
25 changes: 16 additions & 9 deletions common/lib/xmodule/xmodule/vertical_module.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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?
Expand Down
21 changes: 13 additions & 8 deletions lms/djangoapps/courseware/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

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
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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:
Expand Down
5 changes: 4 additions & 1 deletion lms/templates/courseware/courseware.html
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -150,6 +151,8 @@
</script>
% endif

${fragment.foot_html()}

</%block>

% if timer_expiration_duration:
Expand Down Expand Up @@ -185,7 +188,7 @@
% endif

<section class="course-content">
${content}
${fragment.body_html()}
</section>
</div>
</section>
Expand Down