示例#1
0
def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
    """
    Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons.
    """
    # Only add the Studio wrapper when on the container page. The "Pages" page will remain as is for now.
    if not context.get('is_pages_view', None) and view in PREVIEW_VIEWS:
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and xblock.location == root_xblock.location
        is_reorderable = _is_xblock_reorderable(xblock, context)
        selected_groups_label = get_visibility_partition_info(
            xblock)['selected_groups_label']
        if selected_groups_label:
            selected_groups_label = _(
                'Access restricted to: {list_of_groups}').format(
                    list_of_groups=selected_groups_label)
        template_context = {
            'xblock_context': context,
            'xblock': xblock,
            'show_preview': context.get('show_preview', True),
            'content': frag.content,
            'is_root': is_root,
            'is_reorderable': is_reorderable,
            'can_edit': context.get('can_edit', True),
            'can_edit_visibility': context.get('can_edit_visibility', True),
            'selected_groups_label': selected_groups_label,
            'can_add': context.get('can_add', True),
            'can_move': context.get('can_move', True)
        }
        html = render_to_string('studio_xblock_wrapper.html', template_context)
        frag = wrap_fragment(frag, html)
    return frag
示例#2
0
def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
    """
    Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons.
    """
    # Only add the Studio wrapper when on the container page. The "Pages" page will remain as is for now.
    if not context.get('is_pages_view', None) and view in PREVIEW_VIEWS:
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and xblock.location == root_xblock.location
        is_reorderable = _is_xblock_reorderable(xblock, context)
        selected_groups_label = get_visibility_partition_info(xblock)['selected_groups_label']
        if selected_groups_label:
            selected_groups_label = _('Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label)
        course = modulestore().get_course(xblock.location.course_key)
        template_context = {
            'xblock_context': context,
            'xblock': xblock,
            'show_preview': context.get('show_preview', True),
            'content': frag.content,
            'is_root': is_root,
            'is_reorderable': is_reorderable,
            'can_edit': context.get('can_edit', True),
            'can_edit_visibility': context.get('can_edit_visibility', True),
            'selected_groups_label': selected_groups_label,
            'can_add': context.get('can_add', True),
            'can_move': context.get('can_move', True),
            'language': getattr(course, 'language', None)
        }

        html = render_to_string('studio_xblock_wrapper.html', template_context)
        frag = wrap_fragment(frag, html)
    return frag
示例#3
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(XBlockRuntime, self).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, self.transform_static_paths_to_urls(block, fragment.content))

        return fragment
 def test_wrap_fragment(self):
     """
     Verify that wrap_fragment adds new content.
     """
     new_content = '<p>New Content<p>'
     fragment = self.create_fragment()
     wrapped_fragment = wrap_fragment(fragment, new_content)
     self.assertEqual('<p>New Content<p>', wrapped_fragment.content)
     self.assertEqual('body {background-color:red;}', wrapped_fragment.resources[0].data)
     self.assertEqual('alert("Hi!");', wrapped_fragment.resources[1].data)
 def test_wrap_fragment(self):
     """
     Verify that wrap_fragment adds new content.
     """
     new_content = '<p>New Content<p>'
     fragment = self.create_fragment()
     wrapped_fragment = wrap_fragment(fragment, new_content)
     self.assertEqual('<p>New Content<p>', wrapped_fragment.content)
     self.assertEqual('body {background-color:red;}', wrapped_fragment.resources[0].data)
     self.assertEqual('alert("Hi!");', wrapped_fragment.resources[1].data)
示例#6
0
def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
    """
    Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons.
    """
    # Only add the Studio wrapper when on the container page. The "Pages" page will remain as is for now.
    if not context.get('is_pages_view', None) and view in PREVIEW_VIEWS:
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and xblock.location == root_xblock.location
        is_reorderable = _is_xblock_reorderable(xblock, context)
        selected_groups_label = get_visibility_partition_info(
            xblock)['selected_groups_label']
        if selected_groups_label:
            selected_groups_label = _('Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label)  # lint-amnesty, pylint: disable=line-too-long
        course = modulestore().get_course(xblock.location.course_key)
        template_context = {
            'xblock_context':
            context,
            'xblock':
            xblock,
            'show_preview':
            context.get('show_preview', True),
            'content':
            frag.content,
            'is_root':
            is_root,
            'is_reorderable':
            is_reorderable,
            'can_edit':
            context.get('can_edit', True),
            'can_edit_visibility':
            context.get('can_edit_visibility',
                        xblock.scope_ids.usage_id.context_key.is_course),
            'selected_groups_label':
            selected_groups_label,
            'can_add':
            context.get('can_add', True),
            'can_move':
            context.get('can_move',
                        xblock.scope_ids.usage_id.context_key.is_course),
            'language':
            getattr(course, 'language', None)
        }

        if isinstance(xblock, (XModule, XModuleDescriptor)):
            # Add the webpackified asset tags
            class_name = getattr(xblock.__class__, 'unmixed_class',
                                 xblock.__class__).__name__
            add_webpack_to_fragment(frag, class_name)

        add_webpack_to_fragment(frag, "js/factories/xblock_validation")

        html = render_to_string('studio_xblock_wrapper.html', template_context)
        frag = wrap_fragment(frag, html)
    return frag
示例#7
0
def replace_urls_wrapper(block,
                         view,
                         frag,
                         context,
                         replace_url_service,
                         static_replace_only=False):  # pylint: disable=unused-argument
    """
    Replace any static/course/jump-to-id URLs in XBlock to absolute URLs
    """
    return wrap_fragment(
        frag,
        replace_url_service.replace_urls(frag.content, static_replace_only))
示例#8
0
def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
    """
    Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons.
    """
    # Only add the Studio wrapper when on the container page. The "Pages" page will remain as is for now.
    if not context.get('is_pages_view', None) and view in PREVIEW_VIEWS:
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and xblock.location == root_xblock.location
        is_reorderable = _is_xblock_reorderable(xblock, context)
        selected_groups_label = get_visibility_partition_info(xblock)['selected_groups_label']
        if selected_groups_label:
            selected_groups_label = _('Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label)
        course = modulestore().get_course(xblock.location.course_key)
        template_context = {
            'xblock_context': context,
            'xblock': xblock,
            'show_preview': context.get('show_preview', True),
            'content': frag.content,
            'is_root': is_root,
            'is_reorderable': is_reorderable,
            'can_edit': context.get('can_edit', True),
            'can_edit_visibility': context.get('can_edit_visibility', True),
            'selected_groups_label': selected_groups_label,
            'can_add': context.get('can_add', True),
            'can_move': context.get('can_move', True),
            'language': getattr(course, 'language', None)
        }

        if isinstance(xblock, (XModule, XModuleDescriptor)):
            # Add the webpackified asset tags
            class_name = getattr(xblock.__class__, 'unmixed_class', xblock.__class__).__name__
            for tag in webpack_loader.utils.get_as_tags(class_name):
                frag.add_resource(tag, mimetype='text/html', placement='head')

        for tag in webpack_loader.utils.get_as_tags("js/factories/xblock_validation"):
            frag.add_resource(tag, mimetype='text/html', placement='head')

        html = render_to_string('studio_xblock_wrapper.html', template_context)
        frag = wrap_fragment(frag, html)
    return frag
示例#9
0
def add_inline_analytics(_user, block, _view, frag, _context):  # pylint: disable=unused-argument
    """
    Adds a fragment for in-line analytics.
    Fragment consists of a button and some placeholder divs.

    Returns the wrapped fragment if the problem has a valid question (response).
    See get_responses_data function for valid responses.

    Otherwise, returns the fragment unchanged.
    """
    responses_data = get_responses_data(block)
    if responses_data:
        analytics_context = {
            'block_content': frag.content,
            'location': unicode(block.location),
            'element_id': block.location.html_id().replace('-', '_'),
            'answer_dist_url': reverse('get_analytics_answer_dist'),
            'responses_data': responses_data,
            'course_id': unicode(block.course_id),
        }
        return wrap_fragment(frag, render_to_string('inline_analytics.html', analytics_context))
    return frag
示例#10
0
def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
    """
    Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons.
    """
    # Only add the Studio wrapper when on the container page. The "Pages" page will remain as is for now.
    if not context.get('is_pages_view', None) and view in PREVIEW_VIEWS:
        root_xblock = context.get('root_xblock')
        is_root = root_xblock and xblock.location == root_xblock.location
        is_reorderable = _is_xblock_reorderable(xblock, context)
        template_context = {
            'xblock_context': context,
            'xblock': xblock,
            'show_preview': context.get('show_preview', True),
            'content': frag.content,
            'is_root': is_root,
            'is_reorderable': is_reorderable,
            'can_edit': context.get('can_edit', True),
            'can_edit_visibility': context.get('can_edit_visibility', True),
            'can_add': context.get('can_add', True),
        }
        html = render_to_string('studio_xblock_wrapper.html', template_context)
        frag = wrap_fragment(frag, html)
    return frag
示例#11
0
def add_inline_analytics(_user, block, _view, frag, _context):  # pylint: disable=unused-argument
    """
    Adds a fragment for in-line analytics.
    Fragment consists of a button and some placeholder divs.

    Returns the wrapped fragment if the problem has a valid question (response).
    See get_responses_data function for valid responses.

    Otherwise, returns the fragment unchanged.
    """
    responses_data = get_responses_data(block)
    if responses_data:
        analytics_context = {
            'block_content': frag.content,
            'location': unicode(block.location),
            'element_id': block.location.html_id().replace('-', '_'),
            'answer_dist_url': reverse('get_analytics_answer_dist'),
            'responses_data': responses_data,
            'course_id': unicode(block.course_id),
        }
        return wrap_fragment(
            frag, render_to_string('inline_analytics.html', analytics_context))
    return frag
示例#12
0
def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
    """
    Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons.
    """
    # Only add the Studio wrapper when on the container page. The "Pages" page will remain as is for now.
    if not context.get("is_pages_view", None) and view in PREVIEW_VIEWS:
        root_xblock = context.get("root_xblock")
        is_root = root_xblock and xblock.location == root_xblock.location
        is_reorderable = _is_xblock_reorderable(xblock, context)
        template_context = {
            "xblock_context": context,
            "xblock": xblock,
            "show_preview": context.get("show_preview", True),
            "content": frag.content,
            "is_root": is_root,
            "is_reorderable": is_reorderable,
            "can_edit": context.get("can_edit", True),
            "can_edit_visibility": context.get("can_edit_visibility", True),
            "can_add": context.get("can_add", True),
        }
        html = render_to_string("studio_xblock_wrapper.html", template_context)
        frag = wrap_fragment(frag, html)
    return frag