Ejemplo n.º 1
0
    def student_view_aside(self, block, context):  # pylint: disable=unused-argument
        """
        Display the tag selector with specific categories and allowed values,
        depending on the context.
        """
        if isinstance(block, CapaModule):
            tags = []
            for tag in self.get_available_tags():
                tag_available_values = tag.get_values()
                tag_current_values = self.saved_tags.get(tag.name, [])

                if isinstance(tag_current_values, basestring):
                    tag_current_values = [tag_current_values]

                tag_values_not_exists = [cur_val for cur_val in tag_current_values
                                         if cur_val not in tag_available_values]

                tag_values_available_to_choose = tag_available_values + tag_values_not_exists
                tag_values_available_to_choose.sort()

                tags.append({
                    'key': tag.name,
                    'title': tag.title,
                    'values': tag_values_available_to_choose,
                    'current_values': tag_current_values,
                })
            fragment = Fragment(render_to_string('structured_tags_block.html', {'tags': tags,
                                                                                'tags_count': len(tags),
                                                                                'block_location': block.location}))
            fragment.add_javascript_url(self._get_studio_resource_url('/js/xblock_asides/structured_tags.js'))
            fragment.initialize_js('StructuredTagsInit')
            return fragment
        else:
            return Fragment(u'')
Ejemplo n.º 2
0
    def _student_view(self, context, prereq_met, prereq_meta_info, banner_text=None):
        """
        Returns the rendered student view of the content of this
        sequential.  If banner_text is given, it is added to the
        content.
        """
        display_items = self.get_display_items()
        self._update_position(context, len(display_items))

        if prereq_met and not self._is_gate_fulfilled():
            banner_text = _('This section is a prerequisite. You must complete this section in order to unlock additional content.')

        fragment = Fragment()
        params = {
            'items': self._render_student_view_for_items(context, display_items, fragment) if prereq_met else [],
            'element_id': self.location.html_id(),
            'item_id': text_type(self.location),
            'position': self.position,
            'tag': self.location.block_type,
            'ajax_url': self.system.ajax_url,
            'next_url': context.get('next_url'),
            'prev_url': context.get('prev_url'),
            'banner_text': banner_text,
            'save_position': self.is_user_authenticated(context),
            'show_completion': self.is_user_authenticated(context),
            'gated_content': self._get_gated_content_info(prereq_met, prereq_meta_info)
        }
        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)

        return fragment
Ejemplo n.º 3
0
    def student_view(self, context):
        """ Renders parameters to template. """
        context = {
            'course_key': self.runtime.course_id,
            'display_name': self.display_name_with_default_escaped,
            'tag': self.instructor_tags,
            'source': self.source,
            'instructions_html': self.instructions,
            'content_html': self.content,
            'token': retrieve_token(self.user_email, self.annotation_token_secret),
            'diacritic_marks': self.diacritics,
            'annotation_storage': self.annotation_storage_url,
            'default_tab': self.default_tab,
            'instructor_email': self.instructor_email,
            'annotation_mode': self.annotation_mode,
            'is_course_staff': self.is_course_staff,
        }
        fragment = Fragment(self.system.render_template('textannotation.html', context))

        # TinyMCE already exists in Studio so we should not load the files again
        # get_real_user always returns "None" in Studio since its runtimes contains no anonymous ids
        if self.runtime.get_real_user is not None:
            fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
            fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js")
        return fragment
Ejemplo n.º 4
0
 def create_fragment(self, content=None):
     """
     Create a fragment.
     """
     fragment = Fragment(content)
     fragment.add_css('body {background-color:red;}')
     fragment.add_javascript('alert("Hi!");')
     return fragment
Ejemplo n.º 5
0
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_fragment_resources(fragment)
    return wrapper_frag
Ejemplo n.º 6
0
 def author_view(self, context=None):  # pylint: disable=unused-argument
     """
     Renders author view for Studio.
     """
     fragment = Fragment()
     fragment.add_content(self.runtime.render_template(
         'discussion/_discussion_inline_studio.html',
         {'discussion_id': self.discussion_id}
     ))
     return fragment
Ejemplo n.º 7
0
    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)
            complete_on_view_delay = completion_service.get_complete_on_view_delay_ms()

        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': complete_on_view_delay
                }
            rendered_child = child.render(STUDENT_VIEW, child_block_context)
            fragment.add_fragment_resources(rendered_child)

            contents.append({
                'id': six.text_type(child.location),
                '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)),  # pylint: disable=no-member
        }))

        for tag in webpack_loader.utils.get_as_tags('VerticalStudentView'):
            fragment.add_resource(tag, mimetype='text/html', placement='head')
        fragment.initialize_js('VerticalStudentView')

        return fragment
Ejemplo n.º 8
0
    def render_to_fragment(self, request, course_id=None, discussion_id=None, thread_id=None, **kwargs):
        """
        Render the discussion board to a fragment.

        Args:
            request: The Django request.
            course_id: The id of the course in question.
            discussion_id: An optional discussion ID to be focused upon.
            thread_id: An optional ID of the thread to be shown.

        Returns:
            Fragment: The fragment representing the discussion board
        """
        course_key = CourseKey.from_string(course_id)
        try:
            base_context = _create_base_discussion_view_context(request, course_key)
            # Note:
            #   After the thread is rendered in this fragment, an AJAX
            #   request is made and the thread is completely loaded again
            #   (yes, this is something to fix). Because of this, we pass in
            #   raise_event=False to _load_thread_for_viewing avoid duplicate
            #   tracking events.
            thread = (
                _load_thread_for_viewing(
                    request,
                    base_context['course'],
                    discussion_id=discussion_id,
                    thread_id=thread_id,
                    raise_event=False,
                )
                if thread_id
                else None
            )
            context = _create_discussion_board_context(request, base_context, thread=thread)
            html = render_to_string('discussion/discussion_board_fragment.html', context)
            inline_js = render_to_string('discussion/discussion_board_js.template', context)

            fragment = Fragment(html)
            self.add_fragment_resource_urls(fragment)
            fragment.add_javascript(inline_js)
            if not settings.REQUIRE_DEBUG:
                fragment.add_javascript_url(staticfiles_storage.url('discussion/js/discussion_board_factory.js'))
            return fragment
        except cc.utils.CommentClientMaintenanceError:
            log.warning('Forum is in maintenance mode')
            html = render_to_response('discussion/maintenance_fragment.html', {
                'disable_courseware_js': True,
                'uses_pattern_library': True,
            })
            return Fragment(html)
Ejemplo n.º 9
0
    def student_view(self, context):
        """
        Renders the output that a student will see.
        """
        fragment = Fragment()

        fragment.add_content(self.system.render_template('word_cloud.html', {
            'ajax_url': self.system.ajax_url,
            'display_name': self.display_name,
            'instructions': self.instructions,
            'element_class': self.location.block_type,
            'element_id': self.location.html_id(),
            'num_inputs': self.num_inputs,
            'submitted': self.submitted,
        }))

        return fragment
Ejemplo n.º 10
0
    def author_view(self, context):
        """
        Renders the Studio preview by rendering each child so that they can all be seen and edited.
        """
        fragment = Fragment()
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and root_xblock.location == self.location
        active_groups_preview = None
        inactive_groups_preview = None

        if is_root:
            [active_children, inactive_children] = self.descriptor.active_and_inactive_children()
            active_groups_preview = self.studio_render_children(
                fragment, active_children, context
            )
            inactive_groups_preview = self.studio_render_children(
                fragment, inactive_children, context
            )

        fragment.add_content(self.system.render_template('split_test_author_view.html', {
            'split_test': self,
            'is_root': is_root,
            'is_configured': self.is_configured,
            'active_groups_preview': active_groups_preview,
            'inactive_groups_preview': inactive_groups_preview,
            'group_configuration_url': self.descriptor.group_configuration_url,
        }))
        fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/split_test_author_view.js'))
        fragment.initialize_js('SplitTestAuthorView')

        return fragment
    def author_view(self, context):
        """
        Renders the Studio views.
        Normal studio view: If block is properly configured, displays library status summary
        Studio container view: displays a preview of all possible children.
        """
        fragment = Fragment()
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and root_xblock.location == self.location

        if is_root:
            # User has clicked the "View" link. Show a preview of all possible children:
            if self.children:  # pylint: disable=no-member
                fragment.add_content(self.system.render_template("library-block-author-preview-header.html", {
                    'max_count': self.max_count,
                    'display_name': self.display_name or self.url_name,
                }))
                context['can_edit_visibility'] = False
                context['can_move'] = False
                self.render_children(context, fragment, can_reorder=False, can_add=False)
        # else: When shown on a unit page, don't show any sort of preview -
        # just the status of this block in the validation area.

        # The following JS is used to make the "Update now" button work on the unit page and the container view:
        fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/library_content_edit.js'))
        fragment.initialize_js('LibraryContentAuthorView')
        return fragment
Ejemplo n.º 12
0
    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']

        completion_service = self.runtime.service(self, 'completion')

        child_context['child_of_vertical'] = True
        is_child_of_vertical = context.get('child_of_vertical', False)

        # pylint: disable=no-member
        for child in self.get_display_items():
            rendered_child = child.render(STUDENT_VIEW, child_context)
            fragment.add_fragment_resources(rendered_child)

            contents.append({
                'id': six.text_type(child.location),
                '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)),  # pylint: disable=no-member
            'watched_completable_blocks': self.get_completable_by_viewing(completion_service),
            'completion_delay_ms': self.get_completion_delay_ms(completion_service),
        }))

        fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vertical_student_view.js'))
        fragment.initialize_js('VerticalStudentView')

        return fragment
Ejemplo n.º 13
0
    def render_to_fragment(self, request, course_id=None, **kwargs):
        """
        Renders the user's course bookmarks as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)

        context = {
            'csrf': csrf(request)['csrf_token'],
            'course': course,
            'bookmarks_api_url': reverse('bookmarks'),
            'language_preference': 'en',  # TODO:
        }
        html = render_to_string('course_bookmarks/course-bookmarks-fragment.html', context)
        inline_js = render_to_string('course_bookmarks/course_bookmarks_js.template', context)
        fragment = Fragment(html)
        self.add_fragment_resource_urls(fragment)
        fragment.add_javascript(inline_js)
        return fragment
Ejemplo n.º 14
0
    def _wrap_ele(self, block, view, 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 = (
                '<script type="json/xblock-args" class="xblock_json_init_args">'
                '{data}</script>'
            ).format(data=json.dumps(frag.json_init_args))

        block_css_entrypoint = block.entry_point.replace('.', '-')
        css_classes = [
            block_css_entrypoint,
            '{}-{}'.format(block_css_entrypoint, view),
        ]

        html = "<div class='{}'{properties}>{body}{js}</div>".format(
            markupsafe.escape(' '.join(css_classes)),
            properties="".join(" data-%s='%s'" % item for item in list(data.items())),
            body=frag.body_html(),
            js=json_init)

        wrapped.add_content(html)
        wrapped.add_fragment_resources(frag)
        return wrapped
    def student_view(self, context):
        fragment = Fragment()
        contents = []
        child_context = {} if not context else copy(context)

        for child in self._get_selected_child_blocks():
            for displayable in child.displayable_items():
                rendered_child = displayable.render(STUDENT_VIEW, child_context)
                fragment.add_fragment_resources(rendered_child)
                contents.append({
                    'id': text_type(displayable.location),
                    'content': rendered_child.content,
                })

        fragment.add_content(self.system.render_template('vert_module.html', {
            'items': contents,
            'xblock_context': context,
            'show_bookmark_button': False,
            'watched_completable_blocks': set(),
        }))
        return fragment
Ejemplo n.º 16
0
    def _student_view(self, context, banner_text=None):
        """
        Returns the rendered student view of the content of this
        sequential.  If banner_text is given, it is added to the
        content.
        """
        display_items = self.get_display_items()
        self._update_position(context, len(display_items))
        prereq_met = True
        prereq_meta_info = {}

        if self._required_prereq():
            if self.runtime.user_is_staff:
                banner_text = _('This subsection is unlocked for learners when they meet the prerequisite requirements.')
            else:
                # check if prerequisite has been met
                prereq_met, prereq_meta_info = self._compute_is_prereq_met(True)
        if prereq_met and not self._is_gate_fulfilled():
            banner_text = _('This section is a prerequisite. You must complete this section in order to unlock additional content.')

        fragment = Fragment()
        params = {
            'items': self._render_student_view_for_items(context, display_items, fragment) if prereq_met else [],
            'element_id': self.location.html_id(),
            'item_id': text_type(self.location),
            'position': self.position,
            'tag': self.location.block_type,
            'ajax_url': self.system.ajax_url,
            'next_url': context.get('next_url'),
            'prev_url': context.get('prev_url'),
            'banner_text': banner_text,
            'disable_navigation': not self.is_user_authenticated(context),
            'gated_content': self._get_gated_content_info(prereq_met, prereq_meta_info)
        }
        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)

        return fragment
Ejemplo n.º 17
0
    def render_to_fragment(self, request, course_id=None, discussion_id=None, thread_id=None, **kwargs):
        """
        Render the discussion board to a fragment.

        Args:
            request: The Django request.
            course_id: The id of the course in question.
            discussion_id: An optional discussion ID to be focused upon.
            thread_id: An optional ID of the thread to be shown.

        Returns:
            Fragment: The fragment representing the discussion board
        """
        course_key = CourseKey.from_string(course_id)
        try:
            context = _create_discussion_board_context(
                request,
                course_key,
                discussion_id=discussion_id,
                thread_id=thread_id,
            )
            html = render_to_string('discussion/discussion_board_fragment.html', context)
            inline_js = render_to_string('discussion/discussion_board_js.template', context)

            fragment = Fragment(html)
            self.add_fragment_resource_urls(fragment)
            fragment.add_javascript(inline_js)
            if not settings.REQUIRE_DEBUG:
                fragment.add_javascript_url(staticfiles_storage.url('discussion/js/discussion_board_factory.js'))
            return fragment
        except cc.utils.CommentClientMaintenanceError:
            log.warning('Forum is in maintenance mode')
            html = render_to_response('discussion/maintenance_fragment.html', {
                'disable_courseware_js': True,
                'uses_pattern_library': True,
            })
            return Fragment(html)
Ejemplo n.º 18
0
    def layout_asides(self, block, context, frag, view_name, aside_frag_fns):
        position_for_asides = '<!-- footer for xblock_aside -->'
        result = Fragment()
        result.add_fragment_resources(frag)

        for aside, aside_fn in aside_frag_fns:
            aside_frag = aside_fn(block, context)
            if aside_frag.content != u'':
                aside_frag_wrapped = self.wrap_aside(block, aside, view_name, aside_frag, context)
                aside.save()
                result.add_fragment_resources(aside_frag_wrapped)
                replacement = position_for_asides + aside_frag_wrapped.content
                frag.content = frag.content.replace(position_for_asides, replacement)

        result.add_content(frag.content)
        return result
Ejemplo n.º 19
0
 def visibility_view(self, _context=None):
     """
     Render the view to manage an xblock's visibility settings in Studio.
     Args:
         _context: Not actively used for this view.
     Returns:
         (Fragment): An HTML fragment for editing the visibility of this XBlock.
     """
     fragment = Fragment()
     from contentstore.utils import reverse_course_url
     fragment.add_content(self.system.render_template('visibility_editor.html', {
         'xblock': self,
         'manage_groups_url': reverse_course_url('group_configurations_list_handler', self.location.course_key),
     }))
     fragment.add_javascript_url(self._get_studio_resource_url('/js/xblock/authoring.js'))
     fragment.initialize_js('VisibilityEditorInit')
     return fragment
Ejemplo n.º 20
0
    def render_to_fragment(self,
                           request,
                           course_id=None,
                           page_context=None,
                           **kwargs):
        """
        Renders the course outline as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)
        _, course_position = get_last_accessed_courseware(
            course, request, request.user)
        course_usage_key = modulestore().make_course_usage_key(course_key)
        all_blocks = get_blocks(
            request,
            course_usage_key,
            user=request.user,
            nav_depth=3,
            requested_fields=['children', 'display_name', 'type'],
            block_types_filter=['course', 'chapter', 'sequential'])

        course_block_tree = all_blocks['blocks'][
            all_blocks['root']]  # Get the root of the block tree

        context = {
            'csrf':
            csrf(request)['csrf_token'],
            'course':
            course,
            # Recurse through the block tree, fleshing out each child object
            'blocks':
            self.populate_children(course_block_tree, all_blocks['blocks'],
                                   course_position)
        }
        html = render_to_string(
            'course_experience/course-outline-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 21
0
    def student_view(self, context=None):  # pylint: disable=unused-argument
        """
        The primary view of the DoneXBlock, shown to students
        when viewing courses.
        """
        html_resource = resource_string("static/html/done.html")
        html = html_resource.format(done=self.done, id=uuid.uuid1(0))
        (unchecked_png,
         checked_png) = (self.runtime.local_resource_url(self, x)
                         for x in ('public/check-empty.png',
                                   'public/check-full.png'))

        frag = Fragment(html)
        frag.add_css(resource_string("static/css/done.css"))
        frag.add_javascript(resource_string("static/js/src/done.js"))
        frag.initialize_js(
            "DoneXBlock", {
                'state': self.done,
                'unchecked': unchecked_png,
                'checked': checked_png,
                'align': self.align.lower()
            })
        return frag
Ejemplo n.º 22
0
    def render_to_fragment(self,
                           request,
                           course_id=None,
                           page_context=None,
                           **kwargs):
        """
        Renders the course outline as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course_overview = get_course_overview_with_access(
            request.user, 'load', course_key, check_if_enrolled=True)
        course = modulestore().get_course(course_key)

        course_block_tree = get_course_outline_block_tree(request, course_id)
        if not course_block_tree:
            return None

        context = {
            'csrf': csrf(request)['csrf_token'],
            'course': course_overview,
            'due_date_display_format': course.due_date_display_format,
            'blocks': course_block_tree,
            'user': request.user,
            'course_id': course_id
        }
        print(course_block_tree)
        resume_block = get_resume_block(course_block_tree)
        if not resume_block:
            self.mark_first_unit_to_resume(course_block_tree)

        xblock_display_names = self.create_xblock_id_and_name_dict(
            course_block_tree)
        gated_content = self.get_content_milestones(request, course_key)

        context['gated_content'] = gated_content
        context['xblock_display_names'] = xblock_display_names
        #badge can be issued here on complete status. An error occured here
        html = render_to_string(
            'course_experience/course-outline-fragment.html', context)
        return Fragment(html)
    def dashboard_view(self, context):
        fragment = Fragment()

        children_context = context.copy()

        stage_fragments = self._render_children('dashboard_view',
                                                children_context, self.stages)
        stage_contents = [frag.content for frag in stage_fragments]
        for stage_fragment in stage_fragments:
            fragment.add_fragment_resources(stage_fragment)

        render_context = {'activity': self, 'stage_contents': stage_contents}
        fragment.add_content(
            self.render_template('dashboard_view', render_context))

        return fragment
Ejemplo n.º 24
0
 def visibility_view(self, _context=None):
     """
     Render the view to manage an xblock's visibility settings in Studio.
     Args:
         _context: Not actively used for this view.
     Returns:
         (Fragment): An HTML fragment for editing the visibility of this XBlock.
     """
     fragment = Fragment()
     from contentstore.utils import reverse_course_url
     fragment.add_content(
         self.system.render_template(
             'visibility_editor.html', {
                 'xblock':
                 self,
                 'manage_groups_url':
                 reverse_course_url('group_configurations_list_handler',
                                    self.location.course_key),
             }))
     fragment.add_javascript_url(
         self._get_studio_resource_url('/js/xblock/authoring.js'))
     fragment.initialize_js('VisibilityEditorInit')
     return fragment
Ejemplo n.º 25
0
    def layout_asides(self, block, context, frag, view_name, aside_frag_fns):
        """
        Execute and layout the aside_frags wrt the block's frag. Runtimes should feel free to override this
        method to control execution, place, and style the asides appropriately for their application

        This default method appends the aside_frags after frag. If you override this, you must
        call wrap_aside around each aside as per this function.

        Args:
            block (XBlock): the block being rendered
            frag (html): The result from rendering the block
            aside_frag_fns list((aside, aside_fn)): The asides and closures for rendering to call
        """
        result = Fragment(frag.content)
        result.add_fragment_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_content(aside_frag.content)
            result.add_fragment_resources(aside_frag)

        return result
Ejemplo n.º 26
0
    def student_view_aside(self, block, context):  # pylint: disable=unused-argument
        """
        Display the tag selector with specific categories and allowed values,
        depending on the context.
        """
        if isinstance(block, CapaModule):
            tags = []
            for tag in self.get_available_tags():
                tag_available_values = tag.get_values()
                tag_current_values = self.saved_tags.get(tag.name, [])

                if isinstance(tag_current_values, basestring):
                    tag_current_values = [tag_current_values]

                tag_values_not_exists = [
                    cur_val for cur_val in tag_current_values
                    if cur_val not in tag_available_values
                ]

                tag_values_available_to_choose = tag_available_values + tag_values_not_exists
                tag_values_available_to_choose.sort()

                tags.append({
                    'key': tag.name,
                    'title': tag.title,
                    'values': tag_values_available_to_choose,
                    'current_values': tag_current_values,
                })
            fragment = Fragment(
                render_to_string(
                    'structured_tags_block.html', {
                        'tags': tags,
                        'tags_count': len(tags),
                        'block_location': block.location
                    }))
            fragment.add_javascript_url(
                self._get_studio_resource_url(
                    '/js/xblock_asides/structured_tags.js'))
            fragment.initialize_js('StructuredTagsInit')
            return fragment
        else:
            return Fragment(u'')
Ejemplo n.º 27
0
 def build_fragment(
     self,
     template='',
     context=None,
     css=None,
     js=None,
     js_init=None,
 ):
     """
     Creates a fragment for display.
     """
     context = context or {}
     css = css or []
     js = js or []
     rendered_template = ''
     if template:  # pragma: no cover
         template = 'templates/' + template
         rendered_template = self.loader.render_django_template(
             template,
             context=Context(context),
             i18n_service=self.runtime.service(self, 'i18n'),
         )
     fragment = Fragment(rendered_template)
     for item in css:
         if item.startswith('/'):
             url = item
         else:
             item = 'public/' + item
             url = self.runtime.local_resource_url(self, item)
         fragment.add_css_url(url)
     for item in js:
         item = 'public/' + item
         url = self.runtime.local_resource_url(self, item)
         fragment.add_javascript_url(url)
     if js_init:  # pragma: no cover
         fragment.initialize_js(js_init)
     return fragment
Ejemplo n.º 28
0
def get_first_purchase_offer_banner_fragment(user, course):
    """
    Return an HTML Fragment with First Purcahse Discount message,
    which has the discount_expiration_date, price,
    discount percentage and a link to upgrade.
    """
    if user and not user.is_anonymous and course:
        now = datetime.now(tz=pytz.UTC).strftime(u"%Y-%m-%d %H:%M:%S%z")
        saw_banner = ExperimentData.objects.filter(
            user=user, experiment_id=REV1008_EXPERIMENT_ID, key=str(course)
        )
        if not saw_banner:
            ExperimentData.objects.create(
                user=user, experiment_id=REV1008_EXPERIMENT_ID, key=str(course), value=now
            )
        discount_expiration_date = get_discount_expiration_date(user, course)
        if (discount_expiration_date and
                can_receive_discount(user=user, course=course, discount_expiration_date=discount_expiration_date)):
            # Translator: xgettext:no-python-format
            offer_message = _(u'{banner_open} Upgrade by {discount_expiration_date} and save {percentage}% '
                              u'[{strikeout_price}]{span_close}{br}Discount will be automatically applied at checkout. '
                              u'{a_open}Upgrade Now{a_close}{div_close}')
            return Fragment(HTML(offer_message).format(
                a_open=HTML(u'<a href="{upgrade_link}">').format(
                    upgrade_link=verified_upgrade_deadline_link(user=user, course=course)
                ),
                a_close=HTML('</a>'),
                br=HTML('<br>'),
                banner_open=HTML(
                    '<div class="first-purchase-offer-banner" role="note">'
                    '<span class="first-purchase-offer-banner-bold">'
                ),
                discount_expiration_date=discount_expiration_date.strftime(u'%B %d'),
                percentage=discount_percentage(course),
                span_close=HTML('</span>'),
                div_close=HTML('</div>'),
                strikeout_price=HTML(format_strikeout_price(user, course, check_for_discount=False)[0])
            ))
    return None
Ejemplo n.º 29
0
    def render_to_fragment(self,
                           request,
                           course_id=None,
                           page_context=None,
                           **kwargs):
        """
        Renders the course outline as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course_overview = get_course_overview_with_access(
            request.user, 'load', course_key, check_if_enrolled=True)

        course_block_tree = get_course_outline_block_tree(request, course_id)

        context = {
            'csrf': csrf(request)['csrf_token'],
            'course': course_overview,
            'blocks': course_block_tree
        }
        html = render_to_string(
            'course_experience/course-outline-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 30
0
    def test_that_timed_sequence_gating_respects_access_configurations(self):
        """
        Verify that if a time limited sequence contains content type gated problems, we gate the sequence
        """
        # the one problem in this sequence needs to have graded set to true in order to test content type gating
        self.sequence_5_1.get_children()[0].get_children()[0].graded = True
        gated_fragment = Fragment('i_am_gated')

        # When a time limited sequence contains content type gated problems, the sequence itself is gated
        self.sequence_5_1.runtime._services['content_type_gating'] = Mock(return_value=Mock(  # pylint: disable=protected-access
            check_children_for_content_type_gating_paywall=Mock(return_value=gated_fragment.content),
        ))
        view = self._get_rendered_view(
            self.sequence_5_1,
            extra_context=dict(next_url='NextSequential', prev_url='PrevSequential'),
            view=STUDENT_VIEW
        )
        assert 'i_am_gated' in view
        # check a few elements to ensure the correct page was loaded
        assert 'seq_module.html' in view
        assert 'NextSequential' in view
        assert 'PrevSequential' in view
Ejemplo n.º 31
0
    def render(self, block, view_name, context=None):
        """
        Render a specific view of an XBlock.
        """
        # Users who aren't logged in are not allowed to view any views other
        # than public_view. They may call any handlers though.
        if (self.user is None or self.user.is_anonymous) and view_name != 'public_view':
            raise PermissionDenied

        # We also need to override this method because some XBlocks in the
        # edx-platform codebase use methods like add_webpack_to_fragment()
        # which create relative URLs (/static/studio/bundles/webpack-foo.js).
        # We want all resource URLs to be absolute, such as is done when
        # local_resource_url() is used.
        fragment = super().render(block, view_name, context)
        needs_fix = False
        for resource in fragment.resources:
            if resource.kind == 'url' and resource.data.startswith('/'):
                needs_fix = True
                break
        if needs_fix:
            log.warning("XBlock %s returned relative resource URLs, which are deprecated", block.scope_ids.usage_id)
            # The Fragment API is mostly immutable, so changing a resource requires this:
            frag_data = fragment.to_dict()
            for resource in frag_data['resources']:
                if resource['kind'] == 'url' and resource['data'].startswith('/'):
                    log.debug("-> Relative resource URL: %s", resource['data'])
                    resource['data'] = get_xblock_app_config().get_site_root_url() + resource['data']
            fragment = Fragment.from_dict(frag_data)

        # Apply any required transforms to the fragment.
        # We could move to doing this in wrap_xblock() and/or use an array of
        # wrapper methods like the ConfigurableFragmentWrapper mixin does.
        fragment = wrap_fragment(
            fragment,
            ReplaceURLService(xblock=block, lookup_asset_url=self._lookup_asset_url).replace_urls(fragment.content)
        )

        return fragment
Ejemplo n.º 32
0
    def render_to_fragment(self, request, course_id=None, **kwargs):
        """
        Render the course dates fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)
        course_date_blocks = get_course_date_blocks(course, request.user)

        context = {
            'course_date_blocks': [
                block for block in course_date_blocks
                if block.title != 'current_datetime'
            ]
        }
        html = render_to_string(self.template_name, context)
        dates_fragment = Fragment(html)
        self.add_fragment_resource_urls(dates_fragment)

        return dates_fragment
Ejemplo n.º 33
0
    def render_to_fragment(self, request, course_id=None, **kwargs):
        """
        Renders the welcome message fragment for the specified course.

        Returns: A fragment, or None if there is no welcome message.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)
        welcome_message_html = self.welcome_message_html(request, course)
        if not welcome_message_html:
            return None

        context = {
            'welcome_message_html': welcome_message_html,
        }

        html = render_to_string(
            'course_experience/welcome-message-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 34
0
    def render_to_fragment(self, request, course_id=None, **kwargs):  # lint-amnesty, pylint: disable=arguments-differ
        """
        Renders the latest update message fragment for the specified course.

        Returns: A fragment, or None if there is no latest update message.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)

        update_html = self.latest_update_html(request, course)
        if not update_html:
            return None

        context = {
            'update_html': update_html,
        }
        html = render_to_string(
            'course_experience/latest-update-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 35
0
 def student_view(self, context=None):  # pylint: disable=W0613
     """Provide default student view."""
     # Get the attempts for all problems in my parent.
     if self.parent:
         # these two lines are equivalent, and both work:
         attempts = list(
             self.runtime.query(self).parent().descendants().attr(
                 "problem_attempted"))
         attempts = list(
             self.runtime.querypath(self, "..//@problem_attempted"))
         num_problems = len(attempts)
         attempted = sum(attempts)
         if num_problems == 0:
             content = "There are no problems here..."
         elif attempted == num_problems:
             content = "Great! You attempted all %d problems!" % num_problems
         else:
             content = "Hmm, you've only tried %d out of %d problems..." % (
                 attempted, num_problems)
     else:
         content = "I have nothing to live for! :("
     return Fragment(content)
Ejemplo n.º 36
0
    def student_view(self, context):
        _ = self.runtime.service(self, "i18n").ugettext
        context = context or {}
        self._capture_basic_metrics()
        banner_text = None
        prereq_met = True
        prereq_meta_info = {}

        if self._required_prereq():
            if self.runtime.user_is_staff:
                banner_text = _('This subsection is unlocked for learners when they meet the prerequisite requirements.')
            else:
                # check if prerequisite has been met
                prereq_met, prereq_meta_info = self._compute_is_prereq_met(True)
        if prereq_met:
            special_html_view = self._hidden_content_student_view(context) or self._special_exam_student_view()
            if special_html_view:
                masquerading_as_specific_student = context.get('specific_masquerade', False)
                banner_text, special_html = special_html_view
                if special_html and not masquerading_as_specific_student:
                    return Fragment(special_html)
        return self._student_or_public_view(context, prereq_met, prereq_meta_info, banner_text)
    def student_view(self, context):
        """
        Player view, displayed to the student
        """
        fragment = Fragment()

        current_stage_id = context.get(
            Constants.CURRENT_STAGE_ID_PARAMETER_NAME, None)
        target_stage = self.get_stage_to_display(current_stage_id)

        if not target_stage:
            fragment.add_content(self._(messages.NO_STAGES))
        else:
            stage_fragment = target_stage.render('student_view', context)
            fragment.add_fragment_resources(stage_fragment)
            render_context = {
                'activity': self,
                'stage_content': stage_fragment.content,
            }
            render_context.update(context)
            fragment.add_content(
                self.render_template('student_view', render_context))

        return fragment
Ejemplo n.º 38
0
    def author_view(self, context):
        """
        Renders the Studio preview view.
        """
        fragment = Fragment()
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and root_xblock.location == self.location  # pylint: disable=no-member
        # If block ID is not defined, ask user for the component ID in the author_view itself.
        # We don't display the editor if is_root as that page should represent the student_view without any ambiguity
        if not self.source_block_id and not is_root:
            fragment.add_content(
                loader.render_django_template('templates/library-sourced-block-author-view.html', {
                    'save_url': handler_url(self, 'submit_studio_edits')
                })
            )
            fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/library_source_block.js'))
            fragment.initialize_js('LibrarySourceBlockAuthorView')
            return fragment

        context = {} if not context else copy(context)  # Isolate context - without this there are weird bugs in Studio
        # EditableChildrenMixin.render_children will render HTML that allows instructors to make edits to the children
        context['can_move'] = False
        self.render_children(context, fragment, can_reorder=False, can_add=False)
        return fragment
Ejemplo n.º 39
0
    def student_view(self, context):
        """
        Renders the contents of the chosen condition for students, and all the
        conditions for staff.
        """
        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_fragment_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
Ejemplo n.º 40
0
    def render_to_fragment(self, request, **kwargs):
        """
        Render the program listing fragment.
        """
        user = request.user
        programs_config = kwargs.get(
            'programs_config') or ProgramsApiConfig.current()
        if not programs_config.enabled or not user.is_authenticated():
            raise Http404

        meter = ProgramProgressMeter(request.site, user)

        context = {
            'marketing_url': get_program_marketing_url(programs_config),
            'programs': meter.engaged_programs,
            'progress': meter.progress()
        }
        html = render_to_string('learner_dashboard/programs_fragment.html',
                                context)
        programs_fragment = Fragment(html)
        self.add_fragment_resource_urls(programs_fragment)

        return programs_fragment
Ejemplo n.º 41
0
    def render_to_fragment(self, request, course_id=None, **kwargs):  # lint-amnesty, pylint: disable=arguments-differ
        """
        Renders the welcome message fragment for the specified course.

        Returns: A fragment, or None if there is no welcome message.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
        welcome_message_html = self.welcome_message_html(request, course)
        if not welcome_message_html:
            return None

        dismiss_url = reverse(
            'openedx.course_experience.dismiss_welcome_message', kwargs={'course_id': str(course_key)}
        )

        context = {
            'dismiss_url': dismiss_url,
            'welcome_message_html': welcome_message_html,
        }

        html = render_to_string('course_experience/welcome-message-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 42
0
 def student_view(self, context=None):  # pylint: disable=W0613
     """Returned content has handler urls."""
     all_args = [
         # Arguments for handler_url
         (
             "send_it_back", ),
         ("send_it_back", "with_some_suffix"),
         ("send_it_back", "", "a=123"),
         ("send_it_back", "", "a=123&b=456&c=789"),
         ("send_it_back", "another_suffix", "a=123&b=456&c=789"),
         ("send_it_back_public", ),
         ("send_it_back_public", "with_some_suffix"),
         ("send_it_back_public", "", "a=123"),
         ("send_it_back_public", "", "a=123&b=456&c=789"),
         ("send_it_back_public", "another_suffix", "a=123&b=456&c=789"),
     ]
     urls = []
     for args in all_args:
         thirdparty = (args[0] == "send_it_back_public")
         urls.append(
             self.runtime.handler_url(self, *args, thirdparty=thirdparty))
     encoded = json.dumps(urls)
     return Fragment(u":::" + encoded + u":::")
Ejemplo n.º 43
0
    def render_iframe(self) -> str:
        """
        Returns the program LTI iframe if program Lti configuration exists for a program uuid
        """
        if not self.is_configured:
            return ''

        lti_embed_html = self._get_lti_embed_code()
        fragment = Fragment(
            HTML(
                """
                <iframe
                    id='lti-tab-embed'
                    style='width: 100%; min-height: 800px; border: none'
                    srcdoc='{srcdoc}'
                 >
                </iframe>
                """
            ).format(
                srcdoc=lti_embed_html
            )
        )
        return fragment.content
    def render_to_fragment(self, request, course_id=None, **kwargs):
        """
        Renders the latest update message fragment for the specified course.

        Returns: A fragment, or None if there is no latest update message.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)

        ordered_updates = get_ordered_updates(request, course)

        if not ordered_updates:
            return None

        context = {
            'ordered_updates': ordered_updates,
        }
        html = render_to_string(
            'course_experience/course-home-updates-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 45
0
    def test_handle_ajax_metadata_content_type_gated_content(self):
        """
        The contains_content_type_gated_content field should reflect
        whether the given item contains content type gated content
        """
        self.sequence_5_1.xmodule_runtime._services['bookmarks'] = None  # pylint: disable=protected-access
        ContentTypeGatingConfig.objects.create(enabled=True,
                                               enabled_as_of=datetime(
                                                   2018, 1, 1))
        metadata = json.loads(self.sequence_5_1.handle_ajax('metadata', {}))
        self.assertEqual(
            metadata['items'][0]['contains_content_type_gated_content'], False)

        # When a block contains content type gated problems, set the contains_content_type_gated_content field
        self.sequence_5_1.get_children()[0].get_children()[0].graded = True
        self.sequence_5_1.runtime._services['content_type_gating'] = Mock(
            return_value=Mock(  # pylint: disable=protected-access
                enabled_for_enrollment=Mock(return_value=True),
                content_type_gate_for_block=Mock(
                    return_value=Fragment('i_am_gated'))))
        metadata = json.loads(self.sequence_5_1.handle_ajax('metadata', {}))
        self.assertEqual(
            metadata['items'][0]['contains_content_type_gated_content'], True)
Ejemplo n.º 46
0
    def student_view(self, context=None):
        """
        Renders student view for LMS.
        """
        fragment = Fragment()

        self.add_resource_urls(fragment)

        login_msg = ''

        if not self.django_user.is_authenticated():
            qs = urllib.urlencode({
                'course_id': self.course_key,
                'enrollment_action': 'enroll',
                'email_opt_in': False,
            })
            login_msg = Text(_("You are not signed in. To view the discussion content, {sign_in_link} or "
                               "{register_link}, and enroll in this course.")).format(
                sign_in_link=HTML('<a href="{url}">{sign_in_label}</a>').format(
                    sign_in_label=_('sign in'),
                    url='{}?{}'.format(reverse('signin_user'), qs),
                ),
                register_link=HTML('<a href="/{url}">{register_label}</a>').format(
                    register_label=_('register'),
                    url='{}?{}'.format(reverse('register_user'), qs),
                ),
            )

        context = {
            'discussion_id': self.discussion_id,
            'display_name': self.display_name if self.display_name else _("Discussion"),
            'user': self.django_user,
            'course_id': self.course_key,
            'discussion_category': self.discussion_category,
            'discussion_target': self.discussion_target,
            'can_create_thread': self.has_permission("create_thread"),
            'can_create_comment': self.has_permission("create_comment"),
            'can_create_subcomment': self.has_permission("create_sub_comment"),
            'login_msg': login_msg,
        }

        fragment.add_content(self.runtime.render_template('discussion/_discussion_inline.html', context))
        fragment.initialize_js('DiscussionInlineBlock')

        return fragment
Ejemplo n.º 47
0
    def render_to_fragment(self, request, course_id, user_access, **kwargs):
        """
        Renders a course message fragment for the specified course.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user, 'load', course_key)

        # Get time until the start date, if already started, or no start date, value will be zero or negative
        now = datetime.now(UTC())
        already_started = course.start and now > course.start
        days_until_start_string = "started" if already_started else format_timedelta(course.start - now, locale=to_locale(get_language()))
        course_start_data = {
            'course_start_date': format_date(course.start, locale=to_locale(get_language())),
            'already_started': already_started,
            'days_until_start_string': days_until_start_string
        }

        # Register the course home messages to be loaded on the page
        self.register_course_home_messages(request, course, user_access, course_start_data)

        # Grab the relevant messages
        course_home_messages = list(CourseHomeMessages.user_messages(request))

        # Return None if user is enrolled and course has begun
        if user_access['is_enrolled'] and already_started:
            return None

        # Grab the logo
        image_src = "course_experience/images/home_message_author.png"

        context = {
            'course_home_messages': course_home_messages,
            'image_src': image_src,
        }

        html = render_to_string('course_experience/course-messages-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 48
0
    def dashboard_view(self, context):
        fragment = Fragment()

        children_context = self._sanitize_context(context)
        self._add_students_and_workgroups_to_context(children_context)

        activity_fragments = self._render_children('dashboard_view', children_context, self.activities)
        activity_contents = [frag.content for frag in activity_fragments]
        for activity_fragment in activity_fragments:
            fragment.add_fragment_resources(activity_fragment)

        render_context = {'project': self, 'activity_contents': activity_contents}
        fragment.add_content(self.render_template('dashboard_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)

        return fragment
Ejemplo n.º 49
0
def get_first_purchase_offer_banner_fragment(user, course):
    """
    Return an HTML Fragment with First Purcahse Discount message,
    which has the discount_expiration_date, price,
    discount percentage and a link to upgrade.
    """
    if user and course:
        discount_expiration_date = get_discount_expiration_date(user, course)
        if (discount_expiration_date and can_receive_discount(
                user=user,
                course=course,
                discount_expiration_date=discount_expiration_date)):
            # Translator: xgettext:no-python-format
            offer_message = _(
                u'{banner_open} Upgrade by {discount_expiration_date} and save {percentage}% '
                u'[{strikeout_price}]{span_close}{br}Discount will be automatically applied at checkout. '
                u'{a_open}Upgrade Now{a_close}{div_close}')
            return Fragment(
                HTML(offer_message).format(
                    a_open=HTML(u'<a href="{upgrade_link}">').format(
                        upgrade_link=verified_upgrade_deadline_link(
                            user=user, course=course)),
                    a_close=HTML('</a>'),
                    br=HTML('<br>'),
                    banner_open=HTML(
                        '<div class="first-purchase-offer-banner"><span class="first-purchase-offer-banner-bold">'
                    ),
                    discount_expiration_date=discount_expiration_date.strftime(
                        u'%B %d'),
                    percentage=discount_percentage(),
                    span_close=HTML('</span>'),
                    div_close=HTML('</div>'),
                    strikeout_price=HTML(
                        format_strikeout_price(user,
                                               course,
                                               check_for_discount=False)[0])))
    return None
Ejemplo n.º 50
0
    def render_to_fragment(self, request, course_id, user_is_enrolled=True, **kwargs):  # pylint: disable=arguments-differ
        """
        Renders the course outline as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course_overview = get_course_overview_with_access(
            request.user, 'load', course_key, check_if_enrolled=user_is_enrolled
        )
        course = modulestore().get_course(course_key)

        course_block_tree = get_course_outline_block_tree(
            request, course_id, request.user if user_is_enrolled else None
        )
        if not course_block_tree:
            return None

        context = {
            'csrf': csrf(request)['csrf_token'],
            'course': course_overview,
            'due_date_display_format': course.due_date_display_format,
            'blocks': course_block_tree,
            'enable_links': user_is_enrolled or course.course_visibility == COURSE_VISIBILITY_PUBLIC,
        }

        resume_block = get_resume_block(course_block_tree) if user_is_enrolled else None

        if not resume_block:
            self.mark_first_unit_to_resume(course_block_tree)

        xblock_display_names = self.create_xblock_id_and_name_dict(course_block_tree)
        gated_content = self.get_content_milestones(request, course_key)

        context['gated_content'] = gated_content
        context['xblock_display_names'] = xblock_display_names

        html = render_to_string('course_experience/course-outline-fragment.html', context)
        return Fragment(html)
Ejemplo n.º 51
0
    def layout_asides(self, block, context, frag, view_name, aside_frag_fns):
        """
        Execute and layout the aside_frags wrt the block's frag. Runtimes should feel free to override this
        method to control execution, place, and style the asides appropriately for their application

        This default method appends the aside_frags after frag. If you override this, you must
        call wrap_aside around each aside as per this function.

        Args:
            block (XBlock): the block being rendered
            frag (html): The result from rendering the block
            aside_frag_fns list((aside, aside_fn)): The asides and closures for rendering to call
        """
        result = Fragment(frag.content)
        result.add_fragment_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_content(aside_frag.content)
            result.add_fragment_resources(aside_frag)

        return result
Ejemplo n.º 52
0
    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_fragment_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': text_type(child.location),
                    'content': rendered_child.content,
                    'group_id': updated_group_id,
                })
                continue

            active_contents.append({
                'group_name': group_name,
                'id': text_type(child.location),
                '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