def student_view(self, context): fragment = Fragment() contents = [] child_context = {} if not context else copy(context) child_context['child_of_vertical'] = True for child in self.get_display_items(): print print print "Type(child): ", type(child) print print rendered_child = child.render(STUDENT_VIEW, child_context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': child.location.to_deprecated_string(), 'content': rendered_child.content }) fragment.add_content(self.system.render_template('vert_module.html', { 'items': contents, 'xblock_context': context, })) return fragment
def dashboard_detail_view(self, context): ctx = self._sanitize_context(context) self._add_students_and_workgroups_to_context(ctx) fragment = Fragment() render_context = { 'project': self, 'course_id': self.course_id, 'group_id': self.workgroup.id } render_context.update(ctx) target_block_id = self.get_block_id_from_string(ctx.get(Constants.ACTIVATE_BLOCK_ID_PARAMETER_NAME, None)) target_activity = self._get_target_block(target_block_id) if target_activity is None and self.activities: target_activity = self.activities[0] activity_fragment = self._render_child_fragment_with_fallback( target_activity, ctx, messages.NO_ACTIVITIES, view='dashboard_detail_view' ) render_context['activity_content'] = activity_fragment.content fragment.add_frag_resources(activity_fragment) fragment.add_content(self.render_template('dashboard_detail_view', render_context)) add_resource(self, 'css', 'public/css/group_project_common.css', fragment) add_resource(self, 'css', 'public/css/group_project_dashboard.css', fragment) add_resource(self, 'css', 'public/css/vendor/font-awesome/font-awesome.css', fragment, via_url=True) add_resource(self, 'javascript', 'public/js/group_project_dashboard_detail.js', fragment) fragment.initialize_js('GroupProjectBlockDashboardDetailsView') return fragment
def student_view(self, context): fragment = Fragment() children_contents = [] context = context or {} context['hide_prev_answer'] = True # For Step Builder, we don't show the users' old answers when they try again context['score_summary'] = self.get_score_summary() for child_id in self.children: child = self.runtime.get_block(child_id) if child is None: # child should not be None but it can happen due to bugs or permission issues child_content = u"<p>[{}]</p>".format(self._(u"Error: Unable to load child component.")) else: child_fragment = self._render_child_fragment(child, context, view='mentoring_view') fragment.add_frag_resources(child_fragment) child_content = child_fragment.content children_contents.append(child_content) fragment.add_content(loader.render_django_template('templates/html/mentoring_with_steps.html', { 'self': self, 'title': self.display_name, 'show_title': self.show_title, 'children_contents': children_contents, }, i18n_service=self.i18n_service)) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/problem-builder.css')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/underscore-min.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/step_util.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/mentoring_with_steps.js')) fragment.add_resource(loader.load_unicode('templates/html/mentoring_attempts.underscore'), "text/html") fragment.initialize_js('MentoringWithStepsBlock', { 'show_extended_feedback': self.show_extended_feedback(), }) return fragment
def student_view(self, context): """ Renders the student view of the block in the LMS. """ fragment = Fragment() contents = [] child_context = {} if not context else copy(context) child_context['child_of_vertical'] = True # pylint: disable=no-member for child in self.get_display_items(): rendered_child = child.render(STUDENT_VIEW, child_context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': child.location.to_deprecated_string(), 'content': rendered_child.content }) fragment.add_content(self.system.render_template('vert_module.html', { 'items': contents, 'xblock_context': context, 'show_bookmark_button': True, 'bookmarked': child_context['bookmarked'], 'bookmark_id': "{},{}".format(child_context['username'], unicode(self.location)) })) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vertical_student_view.js')) fragment.initialize_js('VerticalStudentView') return fragment
def student_view(self, context): fragment = Fragment() children_contents = [] for child_id in self.children: child = self.runtime.get_block(child_id) if child is None: # child should not be None but it can happen due to bugs or permission issues child_content = u"<p>[{}]</p>".format(self._(u"Error: Unable to load child component.")) elif not isinstance(child, MentoringMessageBlock): child_fragment = self._render_child_fragment(child, context, view='mentoring_view') fragment.add_frag_resources(child_fragment) child_content = child_fragment.content children_contents.append(child_content) fragment.add_content(loader.render_template('templates/html/mentoring_with_steps.html', { 'self': self, 'title': self.display_name, 'show_title': self.show_title, 'children_contents': children_contents, })) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/problem-builder.css')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/underscore-min.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/mentoring_with_steps.js')) fragment.add_resource(loader.load_unicode('templates/html/mentoring_attempts.html'), "text/html") fragment.add_resource(loader.load_unicode('templates/html/mentoring_review_templates.html'), "text/html") self.include_theme_files(fragment) fragment.initialize_js('MentoringWithStepsBlock') return fragment
def student_view(self, context): """ Renders the student view of the block in the LMS. """ fragment = Fragment() contents = [] child_context = {} if not context else copy(context) child_context['child_of_vertical'] = True # pylint: disable=no-member for child in self.get_display_items(): rendered_child = child.render(STUDENT_VIEW, child_context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': child.location.to_deprecated_string(), 'content': rendered_child.content }) fragment.add_content(self.system.render_template('vert_module.html', { 'items': contents, 'xblock_context': context, })) return fragment
def author_view(self, context): """ Renders the Studio preview view, which supports drag and drop. """ fragment = Fragment() contents = [] for child_key in self.children: # pylint: disable=E1101 context['reorderable_items'].add(child_key) child = self.runtime.get_block(child_key) rendered_child = self.runtime.render_child(child, StudioEditableModule.get_preview_view_name(child), context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': unicode(child_key), 'content': rendered_child.content, }) fragment.add_content(self.runtime.render_template("studio_render_children_view.html", { 'items': contents, 'xblock_context': context, 'can_add': True, 'can_reorder': True, })) return fragment
def student_view(self, context=None): """ Normal view of the review step. The parent Step Builder block should pass in appropriate context information: - score_summary """ context = context.copy() if context else {} fragment = Fragment() if "score_summary" not in context: fragment.add_content(u"Error: This block only works inside a Step Builder block.") elif not context["score_summary"]: # Note: The following text should never be seen (in theory) so does not need to be translated. fragment.add_content(u"Your score and review messages will appear here.") else: for child_id in self.children: child = self.runtime.get_block(child_id) if child is None: # child should not be None but it can happen due to bugs or permission issues fragment.add_content(u"<p>[{}]</p>".format(u"Error: Unable to load child component.")) else: if hasattr(child, 'is_applicable'): if not child.is_applicable(context): continue # Hide conditional messages that don't meet their criteria # Render children as "embedded_student_view" rather than "student_view" so # that Studio doesn't wrap with with unwanted controls and the XBlock SDK # workbench doesn't add the acid-aside to the fragment. child_fragment = self._render_child_fragment(child, context, view="embedded_student_view") fragment.add_frag_resources(child_fragment) fragment.add_content(child_fragment.content) return fragment
def _wrap_ele(self, block, frag, extra_data=None): """ Does the guts of the wrapping the same way for both xblocks and asides. Their wrappers provide other info in extra_data which gets put into the dom data- attrs. """ wrapped = Fragment() data = { 'usage': block.scope_ids.usage_id, 'block-type': block.scope_ids.block_type, } data.update(extra_data) if frag.js_init_fn: data['init'] = frag.js_init_fn data['runtime-version'] = frag.js_init_version json_init = "" # TODO/Note: We eventually want to remove: hasattr(frag, 'json_init_args') # However, I'd like to maintain backwards-compatibility with older XBlock # for at least a little while so as not to adversely effect developers. # pmitros/Jun 28, 2014. if hasattr(frag, 'json_init_args') and frag.json_init_args is not None: json_init = u'<script type="json/xblock-args" class="xblock_json_init_args">' + \ u'{data}</script>'.format(data=json.dumps(frag.json_init_args)) html = u"<div class='{}'{properties}>{body}{js}</div>".format( block.entry_point.replace('.', '-'), properties="".join(" data-%s='%s'" % item for item in data.items()), body=frag.body_html(), js=json_init) wrapped.add_content(html) wrapped.add_frag_resources(frag) return wrapped
def _staff_view(self, context): """ Render the staff view for a split test module. """ fragment = Fragment() contents = [] for group_id in self.group_id_to_child: child_location = self.group_id_to_child[group_id] child_descriptor = self.get_child_descriptor_by_location(child_location) child = self.system.get_module(child_descriptor) rendered_child = child.render(STUDENT_VIEW, context) fragment.add_frag_resources(rendered_child) contents.append({ 'group_id': group_id, 'id': child.location.to_deprecated_string(), 'content': rendered_child.content }) # Use the new template fragment.add_content(self.system.render_template('split_test_staff_view.html', { 'items': contents, })) fragment.add_css('.split-test-child { display: none; }') fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/split_test_staff.js')) fragment.initialize_js('ABTestSelector') return fragment
def _render_view(self, context, view): """ Actually renders a view """ fragment = Fragment() child_contents = [] for child_id in self.children: child = self.runtime.get_block(child_id) if child is None: # child should not be None but it can happen due to bugs or permission issues child_contents.append(u"<p>[{}]</p>".format(self._(u"Error: Unable to load child component."))) else: child_fragment = self._render_child_fragment(child, context, view) fragment.add_frag_resources(child_fragment) child_contents.append(child_fragment.content) fragment.add_content(loader.render_template('templates/html/step.html', { 'self': self, 'title': self.display_name, 'show_title': self.show_title, 'child_contents': child_contents, })) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/step.js')) fragment.initialize_js('MentoringStepBlock') return fragment
def student_view(self, context): """ Render the contents of the chosen condition for students, and all the conditions for staff. """ # When rendering a Studio preview, render all of the block's children if context and context.get('runtime_type', None) == 'studio': return self.studio_preview_view(context) if self.child is None: # raise error instead? In fact, could complain on descriptor load... return Fragment(content=u"<div>Nothing here. Move along.</div>") if self.system.user_is_staff: return self._staff_view(context) else: child_fragment = self.child.render('student_view', context) fragment = Fragment(self.system.render_template('split_test_student_view.html', { 'child_content': child_fragment.content, 'child_id': self.child.scope_ids.usage_id, })) fragment.add_frag_resources(child_fragment) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/split_test_student.js')) fragment.initialize_js('SplitTestStudentView') return fragment
def wrap_child(self, block, view, frag, context): # pylint: disable=W0613 wrapped = Fragment() wrapped.add_javascript_url(self.resource_url("js/vendor/jquery.min.js")) wrapped.add_javascript_url(self.resource_url("js/vendor/jquery.cookie.js")) data = {} if frag.js_init_fn: wrapped.add_javascript_url(self.resource_url("js/runtime/%s.js" % frag.js_init_version)) data['init'] = frag.js_init_fn data['runtime-version'] = frag.js_init_version data['usage'] = block.scope_ids.usage_id data['block-type'] = block.scope_ids.block_type if block.name: data['name'] = block.name json_init = "" # TODO/Note: We eventually want to remove: hasattr(frag, 'json_init_args') # However, I'd like to maintain backwards-compatibility with older XBlock # for at least a little while so as not to adversely effect developers. # pmitros/Jun 28, 2014. if hasattr(frag, 'json_init_args') and frag.json_init_args is not None: json_init = u'<script type="json/xblock-args" class="xblock_json_init_args">' + \ u'{data}</script>'.format(data=json.dumps(frag.json_init_args)) html = u"<div class='xblock'{properties}>{body}{js}</div>".format( properties="".join(" data-%s='%s'" % item for item in data.items()), body=frag.body_html(), js=json_init) wrapped.add_content(html) wrapped.add_frag_resources(frag) return wrapped
def wrap_fragment(fragment, new_content): """ Returns a new Fragment that has `new_content` and all as its content, and all of the resources from fragment """ wrapper_frag = Fragment(content=new_content) wrapper_frag.add_frag_resources(fragment) return wrapper_frag
def student_view(self, context): """ Renders the student view of the block in the LMS. """ fragment = Fragment() contents = [] if context: child_context = copy(context) else: child_context = {} if 'bookmarked' not in child_context: bookmarks_service = self.runtime.service(self, 'bookmarks') child_context['bookmarked'] = bookmarks_service.is_bookmarked(usage_key=self.location), # pylint: disable=no-member if 'username' not in child_context: user_service = self.runtime.service(self, 'user') child_context['username'] = user_service.get_current_user().opt_attrs['edx-platform.username'] child_blocks = self.get_display_items() child_blocks_to_complete_on_view = set() completion_service = self.runtime.service(self, 'completion') if completion_service and completion_service.completion_tracking_enabled(): child_blocks_to_complete_on_view = completion_service.blocks_to_mark_complete_on_view(child_blocks) child_context['child_of_vertical'] = True is_child_of_vertical = context.get('child_of_vertical', False) # pylint: disable=no-member for child in child_blocks: child_block_context = copy(child_context) if child in child_blocks_to_complete_on_view: child_block_context['wrap_xblock_data'] = { 'mark-completed-on-view-after-delay': completion_service.get_complete_on_view_delay_ms() } rendered_child = child.render(STUDENT_VIEW, child_block_context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': child.location.to_deprecated_string(), 'content': rendered_child.content }) fragment.add_content(self.system.render_template('vert_module.html', { 'items': contents, 'xblock_context': context, 'unit_title': self.display_name_with_default if not is_child_of_vertical else None, 'show_bookmark_button': child_context.get('show_bookmark_button', not is_child_of_vertical), 'bookmarked': child_context['bookmarked'], 'bookmark_id': u"{},{}".format(child_context['username'], unicode(self.location)) })) fragment.add_javascript_url(self.runtime.STATIC_URL + 'bundles/commons.js') fragment.add_javascript_url(self.runtime.STATIC_URL + 'bundles/CompletionOnViewService.js') fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vertical_student_view.js')) fragment.initialize_js('VerticalStudentView') return fragment
def queue_view(self, context): result = Fragment() queue = super(QueueWidget, self).student_view(context) result.add_frag_resources(queue) html = self.runtime.render_template("static/html/queue.html", queue=queue) result.add_content(html) result.add_css_url('static/css/stuview.css') return result
def page_view(self): result = Fragment() toolbar_frag = self.toolbar_view() result.add_frag_resources(toolbar_frag) html = self.runtime.render_template('static/html/textblock.html', toolbar=toolbar_frag) result.add_content(html) return result
def author_view(self, _context): """ Studio Preview view """ fragment = Fragment(self.display_name_with_default) url_name_fragment = self.get_url_name_fragment(self.url_name_caption) fragment.add_content(url_name_fragment.content) fragment.add_frag_resources(url_name_fragment) return fragment
def student_view(self, context): context = context.copy() if context else {} fragment = Fragment() for child_id in self.children: child = self.runtime.get_block(child_id) # Child should be an instance of MentoringTableColumn child_frag = child.render('mentoring_view', context) fragment.add_frag_resources(child_frag) context['allow_sharing'] = self.allow_sharing context['allow_download'] = self.allow_download user_service = self.runtime.service(self, 'user') if user_service: context['view_options'] = Share.objects.filter( shared_with__username=self.current_user_key, block_id=self.block_id, ).values_list('shared_by__username', flat=True) context['username'] = self.current_user_key share_notifications = Share.objects.filter( shared_with__username=self.current_user_key, notified=False, block_id=self.block_id, ).values_list('shared_by__username', flat=True) context['share_notifications'] = share_notifications and json.dumps(list(share_notifications)) if self.type: # Load an optional background image: context['bg_image_url'] = self.runtime.local_resource_url(self, 'public/img/{}-bg.png'.format(self.type)) # Load an optional description for the background image, for accessibility try: context['bg_image_description'] = loader.load_unicode('static/text/table-{}.txt'.format(self.type)) except IOError as e: if e.errno == errno.ENOENT: pass else: raise report_template = loader.render_template('templates/html/mentoring-table-report.html', { 'title': self.display_name, 'css': loader.load_unicode(AnswerRecapBlock.css_path) + loader.load_unicode(self.css_path), 'student_name': self._get_user_full_name(), 'course_name': self._get_course_name(), }) fragment.add_content(loader.render_template('templates/html/mentoring-table-container.html', context)) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/mentoring-table.css')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/jquery-shorten.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, self.js_path)) fragment.initialize_js( 'MentoringTableBlock', { 'reportContentSelector': '.mentoring-table-container', 'reportTemplate': report_template, } ) return fragment
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 ## Returns a set of all types of all sub-children contents = [] fragment = Fragment() # Is this sequential part of a timed or proctored exam? if self.is_time_limited: view_html = self._time_limited_student_view(context) # Do we have an alternate rendering # from the edx_proctoring subsystem? if view_html: fragment.add_content(view_html) return 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) # `titles` is a list of titles to inject into the sequential tooltip display. # We omit any blank titles to avoid blank lines in the tooltip display. titles = [title.strip() for title in child.get_content_titles() if title.strip()] childinfo = { 'content': rendered_child.content, 'title': "\n".join(titles), 'page_title': titles[0] if titles else '', # Mihara: Also pass on block title. 'block_title': child.display_name_with_default, 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), 'id': child.scope_ids.usage_id.to_deprecated_string(), } if childinfo['title'] == '': childinfo['title'] = child.display_name_with_default contents.append(childinfo) params = { 'items': contents, 'element_id': self.location.html_id(), 'item_id': self.location.to_deprecated_string(), 'position': self.position, 'tag': self.location.category, 'ajax_url': self.system.ajax_url, } fragment.add_content(self.system.render_template("seq_module.html", params)) return fragment
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": rendered_child.content}) fragment.add_content(self.system.render_template("vert_module.html", {"items": contents})) return fragment
def get_children_fragment(self, context, view_name='student_view', instance_of=None, not_instance_of=None): fragment = Fragment() named_child_frags = [] for child in self.get_children_objects(): if instance_of is not None and not isinstance(child, instance_of): continue if not_instance_of is not None and isinstance(child, not_instance_of): continue frag = self.render_child(child, view_name, context) fragment.add_frag_resources(frag) named_child_frags.append((child.name, frag)) return fragment, named_child_frags
def _render_view(self, child_view, template, context): fragment = Fragment() submission_contents = [] for submission in self.submissions: submission_fragment = submission.render(child_view, context) fragment.add_frag_resources(submission_fragment) submission_contents.append(submission_fragment.content) context = {'stage': self, 'submission_contents': submission_contents} fragment.add_content(loader.render_template(template, context)) return fragment
def page_view(self): result = Fragment() toolbar_frag = self.toolbar_view() result.add_frag_resources(toolbar_frag) content_html = self.runtime.render_template(self.content, input=simplejson.loads(self.input)) content_frag = Fragment(content_html) html = self.runtime.render_template('static/html/problemblock.html', toolbar=toolbar_frag, content=content_frag) result.add_content(html) return result
def layout_asides(self, block, context, frag, view_name, aside_frag_fns): position_for_asides = '<!-- footer for xblock_aside -->' result = Fragment() result.add_frag_resources(frag) for aside, aside_fn in aside_frag_fns: aside_frag = self.wrap_aside(block, aside, view_name, aside_fn(block, context), context) aside.save() result.add_frag_resources(aside_frag) frag.content = frag.content.replace(position_for_asides, position_for_asides + aside_frag.content) result.add_content(frag.content) return result
def _staff_view(self, context): """ Render the staff view for a split test module. """ fragment = Fragment() active_contents = [] inactive_contents = [] for child_location in self.children: # pylint: disable=no-member child_descriptor = self.get_child_descriptor_by_location(child_location) child = self.system.get_module(child_descriptor) rendered_child = child.render(STUDENT_VIEW, context) fragment.add_frag_resources(rendered_child) group_name, updated_group_id = self.get_data_for_vertical(child) if updated_group_id is None: # inactive group group_name = child.display_name updated_group_id = [g_id for g_id, loc in self.group_id_to_child.items() if loc == child_location][0] inactive_contents.append( { "group_name": _(u"{group_name} (inactive)").format(group_name=group_name), "id": child.location.to_deprecated_string(), "content": rendered_child.content, "group_id": updated_group_id, } ) continue active_contents.append( { "group_name": group_name, "id": child.location.to_deprecated_string(), "content": rendered_child.content, "group_id": updated_group_id, } ) # Sort active and inactive contents by group name. sorted_active_contents = sorted(active_contents, key=itemgetter("group_name")) sorted_inactive_contents = sorted(inactive_contents, key=itemgetter("group_name")) # Use the new template fragment.add_content( self.system.render_template( "split_test_staff_view.html", {"items": sorted_active_contents + sorted_inactive_contents} ) ) fragment.add_css(".split-test-child { display: none; }") fragment.add_javascript_url(self.runtime.local_resource_url(self, "public/js/split_test_staff.js")) fragment.initialize_js("ABTestSelector") return fragment
def _view_render(self, context, view='student_view'): stage_fragment = self.get_stage_content_fragment(context, view) fragment = Fragment() fragment.add_frag_resources(stage_fragment) render_context = { 'stage': self, 'stage_content': stage_fragment.content, "ta_graded": self.activity.group_reviews_required_count } fragment.add_content(loader.render_template(self.STAGE_WRAPPER_TEMPLATE, render_context)) if stage_fragment.js_init_fn: fragment.initialize_js(stage_fragment.js_init_fn) return fragment
def author_preview_view(self, context): fragment = Fragment() children_contents = [] for child in self._children: child_fragment = child.render('preview_view', context) fragment.add_frag_resources(child_fragment) children_contents.append(child_fragment.content) fragment.add_content(loader.render_template( "templates/html/project_navigator/project_navigator_author_view.html", {'navigator': self, 'children_contents': children_contents} )) add_resource(self, 'css', 'public/css/project_navigator/project_navigator.css', fragment) return fragment
def author_preview_view(self, context): context['self'] = self fragment = Fragment() fragment.add_content(loader.render_template('templates/html/plot_preview.html', context)) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/plot-preview.css')) if self.overlay_ids: fragment.add_content( u"<p>{}</p>".format( _(u"In addition to the default and average overlays the plot includes the following overlays:") )) for overlay in self.overlays: overlay_fragment = self._render_child_fragment(overlay, context, view='mentoring_view') fragment.add_frag_resources(overlay_fragment) fragment.add_content(overlay_fragment.content) return fragment
def mentoring_view(self, context=None): """ Render this XBlock within a mentoring block. """ context = context.copy() if context else {} fragment = Fragment() for child_id in self.children: child = self.runtime.get_block(child_id) if child.scope_ids.block_type == "html": # HTML block current doesn't support "mentoring_view" and if "student_view" is used, it gets wrapped # with HTML we don't want. So just grab its HTML directly. child_frag = Fragment(child.data) else: child_frag = child.render('mentoring_view', context) fragment.add_content(child_frag.content) fragment.add_frag_resources(child_frag) return fragment
def student_view(self, context): display_items = self.get_display_items() # If we're rendering this sequence, but no position is set yet, # or exceeds the length of the displayable items, # default the position to the first element if context.get('requested_child') == 'first': self.position = 1 elif context.get('requested_child') == 'last': self.position = len(display_items) or None elif self.position is None or self.position > len(display_items): self.position = 1 ## Returns a set of all types of all sub-children contents = [] fragment = Fragment() context = context or {} bookmarks_service = self.runtime.service(self, "bookmarks") context["username"] = self.runtime.service( self, "user").get_current_user().opt_attrs['edx-platform.username'] parent_module = self.get_parent() display_names = [ parent_module.display_name_with_default, self.display_name_with_default ] # We do this up here because proctored exam functionality could bypass # rendering after this section. self._capture_basic_metrics() # Is this sequential part of a timed or proctored exam? if self.is_time_limited: view_html = self._time_limited_student_view(context) # Do we have an alternate rendering # from the edx_proctoring subsystem? if view_html: fragment.add_content(view_html) return fragment for child in display_items: is_bookmarked = bookmarks_service.is_bookmarked( usage_key=child.scope_ids.usage_id) context["bookmarked"] = is_bookmarked progress = child.get_progress() rendered_child = child.render(STUDENT_VIEW, context) fragment.add_frag_resources(rendered_child) # `titles` is a list of titles to inject into the sequential tooltip display. # We omit any blank titles to avoid blank lines in the tooltip display. titles = [ title.strip() for title in child.get_content_titles() if title.strip() ] childinfo = { 'content': rendered_child.content, 'title': "\n".join(titles), 'page_title': titles[0] if titles else '', 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), 'id': child.scope_ids.usage_id.to_deprecated_string(), 'bookmarked': is_bookmarked, 'path': " > ".join(display_names + [child.display_name_with_default]), } if childinfo['title'] == '': childinfo['title'] = child.display_name_with_default_escaped contents.append(childinfo) params = { 'items': contents, 'element_id': self.location.html_id(), 'item_id': self.location.to_deprecated_string(), 'position': self.position, 'tag': self.location.category, 'ajax_url': self.system.ajax_url, 'next_url': _compute_next_url( self.location, parent_module, context.get('redirect_url_func'), ), 'prev_url': _compute_previous_url( self.location, parent_module, context.get('redirect_url_func'), ), } fragment.add_content( self.system.render_template("seq_module.html", params)) self._capture_full_seq_item_metrics(display_items) self._capture_current_unit_metrics(display_items) # Get all descendant XBlock types and counts return fragment
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 ## Returns a set of all types of all sub-children contents = [] fragment = Fragment() context = context or {} bookmarks_service = self.runtime.service(self, "bookmarks") context["username"] = self.runtime.service( self, "user").get_current_user().opt_attrs['edx-platform.username'] display_names = [ self.get_parent().display_name or '', self.display_name or '' ] # Is this sequential part of a timed or proctored exam? if self.is_time_limited: view_html = self._time_limited_student_view(context) # Do we have an alternate rendering # from the edx_proctoring subsystem? if view_html: fragment.add_content(view_html) return fragment for child in self.get_display_items(): is_bookmarked = bookmarks_service.is_bookmarked( usage_key=child.scope_ids.usage_id) context["bookmarked"] = is_bookmarked progress = child.get_progress() rendered_child = child.render(STUDENT_VIEW, context) fragment.add_frag_resources(rendered_child) # `titles` is a list of titles to inject into the sequential tooltip display. # We omit any blank titles to avoid blank lines in the tooltip display. titles = [ title.strip() for title in child.get_content_titles() if title.strip() ] childinfo = { 'content': rendered_child.content, 'title': "\n".join(titles), 'page_title': titles[0] if titles else '', 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), 'id': child.scope_ids.usage_id.to_deprecated_string(), 'bookmarked': is_bookmarked, 'path': " > ".join(display_names + [child.display_name or '']), } if childinfo['title'] == '': childinfo['title'] = child.display_name_with_default_escaped contents.append(childinfo) params = { 'items': contents, 'element_id': self.location.html_id(), 'item_id': self.location.to_deprecated_string(), 'position': self.position, 'tag': self.location.category, 'ajax_url': self.system.ajax_url, } fragment.add_content( self.system.render_template("seq_module.html", params)) return fragment