def _xblock_type_and_display_name(xblock): """ Returns a string representation of the xblock's type and display name """ return _('{section_or_subsection} "{display_name}"').format( section_or_subsection=xblock_type_display_name(xblock), display_name=xblock.display_name_with_default)
def _create_xblock_child_info(xblock, course_outline, graders, include_children_predicate=NEVER, user=None): """ Returns information about the children of an xblock, as well as about the primary category of xblock expected as children. """ child_info = {} child_category = xblock_primary_child_category(xblock) if child_category: child_info = { "category": child_category, "display_name": xblock_type_display_name(child_category, default_display_name=child_category), } if xblock.has_children and include_children_predicate(xblock): child_info["children"] = [ create_xblock_info( child, include_child_info=True, course_outline=course_outline, include_children_predicate=include_children_predicate, parent_xblock=xblock, graders=graders, user=user, ) for child in xblock.get_children() ] return child_info
def _create_xblock_child_info(xblock, course_outline, graders, include_children_predicate=NEVER): """ Returns information about the children of an xblock, as well as about the primary category of xblock expected as children. """ child_info = {} child_category = xblock_primary_child_category(xblock) if child_category: child_info = { 'category': child_category, 'display_name': xblock_type_display_name(child_category, default_display_name=child_category), } if xblock.has_children and include_children_predicate(xblock): child_info['children'] = [ create_xblock_info( child, include_child_info=True, course_outline=course_outline, include_children_predicate=include_children_predicate, parent_xblock=xblock, graders=graders) for child in xblock.get_children() ] return child_info
def _get_release_date_from(xblock): """ Returns a string representation of the section or subsection that sets the xblock's release date """ source = find_release_date_source(xblock) # Translators: this will be a part of the release date message. # For example, 'Released: Jul 02, 2014 at 4:00 UTC with Section "Week 1"' return _('{section_or_subsection} "{display_name}"').format( section_or_subsection=xblock_type_display_name(source), display_name=source.display_name_with_default)
def get_component_templates(courselike, library=False): """ Returns the applicable component templates that can be used by the specified course or library. """ def create_template_dict(name, cat, boilerplate_name=None, tab="common", hinted=False): """ Creates a component template dict. Parameters display_name: the user-visible name of the component category: the type of component (problem, html, etc.) boilerplate_name: name of boilerplate for filling in default values. May be None. hinted: True if hinted problem else False tab: common(default)/advanced, which tab it goes in """ return { "display_name": name, "category": cat, "boilerplate_name": boilerplate_name, "hinted": hinted, "tab": tab } component_display_names = { 'discussion': _("Discussion"), 'html': _("HTML"), 'problem': _("Problem"), 'video': _("Video") } component_templates = [] categories = set() # The component_templates array is in the order of "advanced" (if present), followed # by the components in the order listed in COMPONENT_TYPES. component_types = COMPONENT_TYPES[:] # Libraries do not support discussions if library: component_types = [ component for component in component_types if component != 'discussion' ] for category in component_types: templates_for_category = [] component_class = _load_mixed_class(category) # add the default template with localized display name # TODO: Once mixins are defined per-application, rather than per-runtime, # this should use a cms mixed-in class. (cpennington) display_name = xblock_type_display_name( category, _('Blank')) # this is the Blank Advanced problem templates_for_category.append( create_template_dict(display_name, category, None, 'advanced')) categories.add(category) # add boilerplates if hasattr(component_class, 'templates'): for template in component_class.templates(): filter_templates = getattr(component_class, 'filter_templates', None) if not filter_templates or filter_templates( template, courselike): # Tab can be 'common' 'advanced' # Default setting is common/advanced depending on the presence of markdown tab = 'common' if template['metadata'].get('markdown') is None: tab = 'advanced' hinted = template.get('hinted', False) templates_for_category.append( create_template_dict( _(template['metadata'].get('display_name')), # pylint: disable=translation-of-non-string category, template.get('template_id'), tab, hinted, )) # Add any advanced problem types if category == 'problem': for advanced_problem_type in ADVANCED_PROBLEM_TYPES: component = advanced_problem_type['component'] boilerplate_name = advanced_problem_type['boilerplate_name'] try: component_display_name = xblock_type_display_name( component) except PluginMissingError: log.warning( 'Unable to load xblock type %s to read display_name', component, exc_info=True) else: templates_for_category.append( create_template_dict(component_display_name, component, boilerplate_name, 'advanced')) categories.add(component) component_templates.append({ "type": category, "templates": templates_for_category, "display_name": component_display_names[category] }) # Libraries do not support advanced components at this time. if library: return component_templates # Check if there are any advanced modules specified in the course policy. # These modules should be specified as a list of strings, where the strings # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be # enabled for the course. course_advanced_keys = courselike.advanced_modules advanced_component_templates = { "type": "advanced", "templates": [], "display_name": _("Advanced") } advanced_component_types = _advanced_component_types() # Set component types according to course policy file if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in advanced_component_types and category not in categories: # boilerplates not supported for advanced components try: component_display_name = xblock_type_display_name( category, default_display_name=category) advanced_component_templates['templates'].append( create_template_dict(component_display_name, category)) categories.add(category) except PluginMissingError: # dhm: I got this once but it can happen any time the # course author configures an advanced component which does # not exist on the server. This code here merely # prevents any authors from trying to instantiate the # non-existent component type by not showing it in the menu log.warning( "Advanced component %s does not exist. It will not be added to the Studio new component menu.", category) else: log.error("Improper format for course advanced keys! %s", course_advanced_keys) if len(advanced_component_templates['templates']) > 0: component_templates.insert(0, advanced_component_templates) return component_templates
def get_component_templates(courselike, library=False): """ Returns the applicable component templates that can be used by the specified course or library. """ def create_template_dict(name, category, support_level, boilerplate_name=None, tab="common", hinted=False): """ Creates a component template dict. Parameters display_name: the user-visible name of the component category: the type of component (problem, html, etc.) support_level: the support level of this component boilerplate_name: name of boilerplate for filling in default values. May be None. hinted: True if hinted problem else False tab: common(default)/advanced, which tab it goes in """ return { "display_name": name, "category": category, "boilerplate_name": boilerplate_name, "hinted": hinted, "tab": tab, "support_level": support_level } def component_support_level(editable_types, name, template=None): """ Returns the support level for the given xblock name/template combination. Args: editable_types: a QuerySet of xblocks with their support levels name: the name of the xblock template: optional template for the xblock Returns: If XBlockStudioConfigurationFlag is enabled, returns the support level (see XBlockStudioConfiguration) or False if this xblock name/template combination has no Studio support at all. If XBlockStudioConfigurationFlag is disabled, simply returns True. """ # If the Studio support feature is disabled, return True for all. if not XBlockStudioConfigurationFlag.is_enabled(): return True if template is None: template = "" extension_index = template.rfind(".yaml") if extension_index >= 0: template = template[0:extension_index] for block in editable_types: if block.name == name and block.template == template: return block.support_level return False def create_support_legend_dict(): """ Returns a dict of settings information for the display of the support level legend. """ return { "show_legend": XBlockStudioConfigurationFlag.is_enabled(), "allow_unsupported_xblocks": allow_unsupported, "documentation_label": _(u"{platform_name} Support Levels:").format( platform_name=settings.PLATFORM_NAME) } component_display_names = { 'discussion': _("Discussion"), 'html': _("HTML"), 'problem': _("Problem"), 'video': _("Video") } component_templates = [] categories = set() # The component_templates array is in the order of "advanced" (if present), followed # by the components in the order listed in COMPONENT_TYPES. component_types = COMPONENT_TYPES[:] # Libraries do not support discussions if library: component_types = [ component for component in component_types if component != 'discussion' ] component_types = _filter_disabled_blocks(component_types) # Content Libraries currently don't allow opting in to unsupported xblocks/problem types. allow_unsupported = getattr(courselike, "allow_unsupported_xblocks", False) for category in component_types: authorable_variations = authorable_xblocks( allow_unsupported=allow_unsupported, name=category) support_level_without_template = component_support_level( authorable_variations, category) templates_for_category = [] component_class = _load_mixed_class(category) if support_level_without_template: # add the default template with localized display name # TODO: Once mixins are defined per-application, rather than per-runtime, # this should use a cms mixed-in class. (cpennington) display_name = xblock_type_display_name( category, _('Blank')) # this is the Blank Advanced problem templates_for_category.append( create_template_dict(display_name, category, support_level_without_template, None, 'advanced')) categories.add(category) # add boilerplates if hasattr(component_class, 'templates'): for template in component_class.templates(): filter_templates = getattr(component_class, 'filter_templates', None) if not filter_templates or filter_templates( template, courselike): template_id = template.get('template_id') support_level_with_template = component_support_level( authorable_variations, category, template_id) if support_level_with_template: # Tab can be 'common' 'advanced' # Default setting is common/advanced depending on the presence of markdown tab = 'common' if template['metadata'].get('markdown') is None: tab = 'advanced' hinted = template.get('hinted', False) templates_for_category.append( create_template_dict( _(template['metadata'].get('display_name')), category, support_level_with_template, template_id, tab, hinted, )) # Add any advanced problem types. Note that these are different xblocks being stored as Advanced Problems, # currently not supported in libraries . if category == 'problem' and not library: disabled_block_names = [block.name for block in disabled_xblocks()] advanced_problem_types = [ advanced_problem_type for advanced_problem_type in ADVANCED_PROBLEM_TYPES if advanced_problem_type['component'] not in disabled_block_names ] for advanced_problem_type in advanced_problem_types: component = advanced_problem_type['component'] boilerplate_name = advanced_problem_type['boilerplate_name'] authorable_advanced_component_variations = authorable_xblocks( allow_unsupported=allow_unsupported, name=component) advanced_component_support_level = component_support_level( authorable_advanced_component_variations, component, boilerplate_name) if advanced_component_support_level: try: component_display_name = xblock_type_display_name( component) except PluginMissingError: log.warning( u'Unable to load xblock type %s to read display_name', component, exc_info=True) else: templates_for_category.append( create_template_dict( component_display_name, component, advanced_component_support_level, boilerplate_name, 'advanced')) categories.add(component) component_templates.append({ "type": category, "templates": templates_for_category, "display_name": component_display_names[category], "support_legend": create_support_legend_dict() }) # Libraries do not support advanced components at this time. if library: return component_templates # Check if there are any advanced modules specified in the course policy. # These modules should be specified as a list of strings, where the strings # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be # enabled for the course. course_advanced_keys = courselike.advanced_modules advanced_component_templates = { "type": "advanced", "templates": [], "display_name": _("Advanced"), "support_legend": create_support_legend_dict() } advanced_component_types = _advanced_component_types(allow_unsupported) # Set component types according to course policy file if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in advanced_component_types.keys( ) and category not in categories: # boilerplates not supported for advanced components try: component_display_name = xblock_type_display_name( category, default_display_name=category) advanced_component_templates['templates'].append( create_template_dict( component_display_name, category, advanced_component_types[category])) categories.add(category) except PluginMissingError: # dhm: I got this once but it can happen any time the # course author configures an advanced component which does # not exist on the server. This code here merely # prevents any authors from trying to instantiate the # non-existent component type by not showing it in the menu log.warning( u"Advanced component %s does not exist. It will not be added to the Studio new component menu.", category) else: log.error(u"Improper format for course advanced keys! %s", course_advanced_keys) if len(advanced_component_templates['templates']) > 0: component_templates.insert(0, advanced_component_templates) return component_templates
def test_xblock_type_display_name(self): # Verify chapter type display name chapter = ItemFactory.create(parent_location=self.course.location, category="chapter") self.assertEqual(xblock_type_display_name(chapter), u"Section") self.assertEqual(xblock_type_display_name("chapter"), u"Section") # Verify sequential type display name sequential = ItemFactory.create(parent_location=chapter.location, category="sequential") self.assertEqual(xblock_type_display_name(sequential), u"Subsection") self.assertEqual(xblock_type_display_name("sequential"), u"Subsection") # Verify unit type display names vertical = ItemFactory.create(parent_location=sequential.location, category="vertical") self.assertEqual(xblock_type_display_name(vertical), u"Unit") self.assertEqual(xblock_type_display_name("vertical"), u"Unit") # Verify child vertical type display name child_vertical = ItemFactory.create( parent_location=vertical.location, category="vertical", display_name="Child Vertical" ) self.assertEqual(xblock_type_display_name(child_vertical), u"Vertical") # Verify video type display names video = ItemFactory.create(parent_location=vertical.location, category="video") self.assertEqual(xblock_type_display_name(video), u"Video") self.assertEqual(xblock_type_display_name("video"), u"Video") # Verify split test type display names split_test = ItemFactory.create(parent_location=vertical.location, category="split_test") self.assertEqual(xblock_type_display_name(split_test), u"Content Experiment") self.assertEqual(xblock_type_display_name("split_test"), u"Content Experiment")
def get_component_templates(course): """ Returns the applicable component templates that can be used by the specified course. """ def create_template_dict(name, cat, boilerplate_name=None, is_common=False): """ Creates a component template dict. Parameters display_name: the user-visible name of the component category: the type of component (problem, html, etc.) boilerplate_name: name of boilerplate for filling in default values. May be None. is_common: True if "common" problem, False if "advanced". May be None, as it is only used for problems. """ return { "display_name": name, "category": cat, "boilerplate_name": boilerplate_name, "is_common": is_common } component_display_names = { 'discussion': _("Discussion"), 'html': _("HTML"), 'problem': _("Problem"), 'video': _("Video") } component_templates = [] categories = set() # The component_templates array is in the order of "advanced" (if present), followed # by the components in the order listed in COMPONENT_TYPES. for category in COMPONENT_TYPES: templates_for_category = [] component_class = _load_mixed_class(category) # add the default template with localized display name # TODO: Once mixins are defined per-application, rather than per-runtime, # this should use a cms mixed-in class. (cpennington) display_name = xblock_type_display_name(category, _('Blank')) templates_for_category.append(create_template_dict(display_name, category)) categories.add(category) # add boilerplates if hasattr(component_class, 'templates'): for template in component_class.templates(): filter_templates = getattr(component_class, 'filter_templates', None) if not filter_templates or filter_templates(template, course): templates_for_category.append( create_template_dict( _(template['metadata'].get('display_name')), category, template.get('template_id'), template['metadata'].get('markdown') is not None ) ) # Add any advanced problem types if category == 'problem': for advanced_problem_type in ADVANCED_PROBLEM_TYPES: component = advanced_problem_type['component'] boilerplate_name = advanced_problem_type['boilerplate_name'] component_display_name = xblock_type_display_name(component) templates_for_category.append(create_template_dict(component_display_name, component, boilerplate_name)) categories.add(component) component_templates.append({ "type": category, "templates": templates_for_category, "display_name": component_display_names[category] }) # Check if there are any advanced modules specified in the course policy. # These modules should be specified as a list of strings, where the strings # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be # enabled for the course. course_advanced_keys = course.advanced_modules advanced_component_templates = {"type": "advanced", "templates": [], "display_name": _("Advanced")} # Set component types according to course policy file if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in ADVANCED_COMPONENT_TYPES and not category in categories: # boilerplates not supported for advanced components try: component_display_name = xblock_type_display_name(category, default_display_name=category) advanced_component_templates['templates'].append( create_template_dict( component_display_name, category ) ) categories.add(category) except PluginMissingError: # dhm: I got this once but it can happen any time the # course author configures an advanced component which does # not exist on the server. This code here merely # prevents any authors from trying to instantiate the # non-existent component type by not showing it in the menu log.warning( "Advanced component %s does not exist. It will not be added to the Studio new component menu.", category ) pass else: log.error( "Improper format for course advanced keys! %s", course_advanced_keys ) if len(advanced_component_templates['templates']) > 0: component_templates.insert(0, advanced_component_templates) return component_templates
def get_component_templates(courselike, library=False): """ Returns the applicable component templates that can be used by the specified course or library. """ def create_template_dict(name, cat, boilerplate_name=None, tab="common"): """ Creates a component template dict. Parameters display_name: the user-visible name of the component category: the type of component (problem, html, etc.) boilerplate_name: name of boilerplate for filling in default values. May be None. tab: common(default)/advanced/hint, which tab it goes in """ return { "display_name": name, "category": cat, "boilerplate_name": boilerplate_name, "tab": tab } component_display_names = { 'discussion': _("Discussion"), 'html': _("HTML"), 'problem': _("Problem"), 'video': _("Video") } component_templates = [] categories = set() # The component_templates array is in the order of "advanced" (if present), followed # by the components in the order listed in COMPONENT_TYPES. component_types = COMPONENT_TYPES[:] # Libraries do not support discussions if library: component_types = [component for component in component_types if component != 'discussion'] for category in component_types: templates_for_category = [] component_class = _load_mixed_class(category) # add the default template with localized display name # TODO: Once mixins are defined per-application, rather than per-runtime, # this should use a cms mixed-in class. (cpennington) display_name = xblock_type_display_name(category, _('Blank')) # this is the Blank Advanced problem templates_for_category.append(create_template_dict(display_name, category, None, 'advanced')) categories.add(category) # add boilerplates if hasattr(component_class, 'templates'): for template in component_class.templates(): filter_templates = getattr(component_class, 'filter_templates', None) if not filter_templates or filter_templates(template, courselike): # Tab can be 'common' 'advanced' 'hint' # Default setting is common/advanced depending on the presence of markdown tab = 'common' if template['metadata'].get('markdown') is None: tab = 'advanced' # Then the problem can override that with a tab: attribute (note: not nested in metadata) tab = template.get('tab', tab) templates_for_category.append( create_template_dict( _(template['metadata'].get('display_name')), # pylint: disable=translation-of-non-string category, template.get('template_id'), tab ) ) # Add any advanced problem types if category == 'problem': for advanced_problem_type in ADVANCED_PROBLEM_TYPES: component = advanced_problem_type['component'] boilerplate_name = advanced_problem_type['boilerplate_name'] try: component_display_name = xblock_type_display_name(component) except PluginMissingError: log.warning('Unable to load xblock type %s to read display_name', component, exc_info=True) else: templates_for_category.append( create_template_dict(component_display_name, component, boilerplate_name, 'advanced') ) categories.add(component) component_templates.append({ "type": category, "templates": templates_for_category, "display_name": component_display_names[category] }) # Libraries do not support advanced components at this time. if library: return component_templates # Check if there are any advanced modules specified in the course policy. # These modules should be specified as a list of strings, where the strings # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be # enabled for the course. course_advanced_keys = courselike.advanced_modules advanced_component_templates = {"type": "advanced", "templates": [], "display_name": _("Advanced")} advanced_component_types = _advanced_component_types() # Set component types according to course policy file course_advanced_keys = course_advanced_keys or [] course_advanced_keys = list(set(course_advanced_keys + XBLOCKS_ALWAYS_IN_STUDIO)) if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in advanced_component_types and category not in categories: # boilerplates not supported for advanced components try: component_display_name = xblock_type_display_name(category, default_display_name=category) advanced_component_templates['templates'].append( create_template_dict( component_display_name, category ) ) categories.add(category) except PluginMissingError: # dhm: I got this once but it can happen any time the # course author configures an advanced component which does # not exist on the server. This code here merely # prevents any authors from trying to instantiate the # non-existent component type by not showing it in the menu log.warning( "Advanced component %s does not exist. It will not be added to the Studio new component menu.", category ) else: log.error( "Improper format for course advanced keys! %s", course_advanced_keys ) if len(advanced_component_templates['templates']) > 0: component_templates.insert(0, advanced_component_templates) return component_templates
def get_component_templates(courselike, library=False): """ Returns the applicable component templates that can be used by the specified course or library. """ def create_template_dict(name, category, support_level, boilerplate_name=None, tab="common", hinted=False): """ Creates a component template dict. Parameters display_name: the user-visible name of the component category: the type of component (problem, html, etc.) support_level: the support level of this component boilerplate_name: name of boilerplate for filling in default values. May be None. hinted: True if hinted problem else False tab: common(default)/advanced, which tab it goes in """ return { "display_name": name, "category": category, "boilerplate_name": boilerplate_name, "hinted": hinted, "tab": tab, "support_level": support_level } def component_support_level(editable_types, name, template=None): """ Returns the support level for the given xblock name/template combination. Args: editable_types: a QuerySet of xblocks with their support levels name: the name of the xblock template: optional template for the xblock Returns: If XBlockStudioConfigurationFlag is enabled, returns the support level (see XBlockStudioConfiguration) or False if this xblock name/template combination has no Studio support at all. If XBlockStudioConfigurationFlag is disabled, simply returns True. """ # If the Studio support feature is disabled, return True for all. if not XBlockStudioConfigurationFlag.is_enabled(): return True if template is None: template = "" extension_index = template.rfind(".yaml") if extension_index >= 0: template = template[0:extension_index] for block in editable_types: if block.name == name and block.template == template: return block.support_level return False def create_support_legend_dict(): """ Returns a dict of settings information for the display of the support level legend. """ return { "show_legend": XBlockStudioConfigurationFlag.is_enabled(), "allow_unsupported_xblocks": allow_unsupported, "documentation_label": _("{platform_name} Support Levels:").format(platform_name=settings.PLATFORM_NAME) } component_display_names = { 'discussion': _("Discussion"), 'html': _("HTML"), 'problem': _("Problem"), 'video': _("Video") } component_templates = [] categories = set() # The component_templates array is in the order of "advanced" (if present), followed # by the components in the order listed in COMPONENT_TYPES. component_types = COMPONENT_TYPES[:] # Libraries do not support discussions if library: component_types = [component for component in component_types if component != 'discussion'] component_types = _filter_disabled_blocks(component_types) # Content Libraries currently don't allow opting in to unsupported xblocks/problem types. allow_unsupported = getattr(courselike, "allow_unsupported_xblocks", False) for category in component_types: authorable_variations = authorable_xblocks(allow_unsupported=allow_unsupported, name=category) support_level_without_template = component_support_level(authorable_variations, category) templates_for_category = [] component_class = _load_mixed_class(category) if support_level_without_template: # add the default template with localized display name # TODO: Once mixins are defined per-application, rather than per-runtime, # this should use a cms mixed-in class. (cpennington) display_name = xblock_type_display_name(category, _('Blank')) # this is the Blank Advanced problem templates_for_category.append( create_template_dict(display_name, category, support_level_without_template, None, 'advanced') ) categories.add(category) # add boilerplates if hasattr(component_class, 'templates'): for template in component_class.templates(): filter_templates = getattr(component_class, 'filter_templates', None) if not filter_templates or filter_templates(template, courselike): template_id = template.get('template_id') support_level_with_template = component_support_level( authorable_variations, category, template_id ) if support_level_with_template: # Tab can be 'common' 'advanced' # Default setting is common/advanced depending on the presence of markdown tab = 'common' if template['metadata'].get('markdown') is None: tab = 'advanced' hinted = template.get('hinted', False) templates_for_category.append( create_template_dict( _(template['metadata'].get('display_name')), # pylint: disable=translation-of-non-string category, support_level_with_template, template_id, tab, hinted, ) ) # Add any advanced problem types. Note that these are different xblocks being stored as Advanced Problems, # currently not supported in libraries . if category == 'problem' and not library: disabled_block_names = [block.name for block in disabled_xblocks()] advanced_problem_types = [advanced_problem_type for advanced_problem_type in ADVANCED_PROBLEM_TYPES if advanced_problem_type['component'] not in disabled_block_names] for advanced_problem_type in advanced_problem_types: component = advanced_problem_type['component'] boilerplate_name = advanced_problem_type['boilerplate_name'] authorable_advanced_component_variations = authorable_xblocks( allow_unsupported=allow_unsupported, name=component ) advanced_component_support_level = component_support_level( authorable_advanced_component_variations, component, boilerplate_name ) if advanced_component_support_level: try: component_display_name = xblock_type_display_name(component) except PluginMissingError: log.warning('Unable to load xblock type %s to read display_name', component, exc_info=True) else: templates_for_category.append( create_template_dict( component_display_name, component, advanced_component_support_level, boilerplate_name, 'advanced' ) ) categories.add(component) component_templates.append({ "type": category, "templates": templates_for_category, "display_name": component_display_names[category], "support_legend": create_support_legend_dict() }) # Libraries do not support advanced components at this time. if library: return component_templates # Check if there are any advanced modules specified in the course policy. # These modules should be specified as a list of strings, where the strings # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be # enabled for the course. course_advanced_keys = courselike.advanced_modules advanced_component_templates = { "type": "advanced", "templates": [], "display_name": _("Advanced"), "support_legend": create_support_legend_dict() } advanced_component_types = _advanced_component_types(allow_unsupported) # Set component types according to course policy file if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in advanced_component_types.keys() and category not in categories: # boilerplates not supported for advanced components try: component_display_name = xblock_type_display_name(category, default_display_name=category) advanced_component_templates['templates'].append( create_template_dict( component_display_name, category, advanced_component_types[category] ) ) categories.add(category) except PluginMissingError: # dhm: I got this once but it can happen any time the # course author configures an advanced component which does # not exist on the server. This code here merely # prevents any authors from trying to instantiate the # non-existent component type by not showing it in the menu log.warning( "Advanced component %s does not exist. It will not be added to the Studio new component menu.", category ) else: log.error( "Improper format for course advanced keys! %s", course_advanced_keys ) if len(advanced_component_templates['templates']) > 0: component_templates.insert(0, advanced_component_templates) return component_templates
def test_xblock_type_display_name(self): # Verify chapter type display name chapter = ItemFactory.create(parent_location=self.course.location, category='chapter') self.assertEqual(xblock_type_display_name(chapter), u'Section') self.assertEqual(xblock_type_display_name('chapter'), u'Section') # Verify sequential type display name sequential = ItemFactory.create(parent_location=chapter.location, category='sequential') self.assertEqual(xblock_type_display_name(sequential), u'Subsection') self.assertEqual(xblock_type_display_name('sequential'), u'Subsection') # Verify unit type display names vertical = ItemFactory.create(parent_location=sequential.location, category='vertical') self.assertEqual(xblock_type_display_name(vertical), u'Unit') self.assertEqual(xblock_type_display_name('vertical'), u'Unit') # Verify child vertical type display name child_vertical = ItemFactory.create(parent_location=vertical.location, category='vertical', display_name='Child Vertical') self.assertEqual(xblock_type_display_name(child_vertical), u'Vertical') # Verify video type display names video = ItemFactory.create(parent_location=vertical.location, category="video") self.assertEqual(xblock_type_display_name(video), u'Video') self.assertEqual(xblock_type_display_name('video'), u'Video') # Verify split test type display names split_test = ItemFactory.create(parent_location=vertical.location, category="split_test") self.assertEqual(xblock_type_display_name(split_test), u'Content Experiment') self.assertEqual(xblock_type_display_name('split_test'), u'Content Experiment')