Commit edf6f7c7 by cahrens

WIP

parent c85d8ad8
......@@ -27,7 +27,7 @@ from opaque_keys.edx.keys import UsageKey
from student.auth import has_course_author_access
from django.utils.translation import ugettext as _
from xblock_django.models import XBlockDisableConfig
from xblock_django.api import disabled_xblocks, authorable_xblocks
__all__ = [
'container_handler',
......@@ -52,12 +52,24 @@ CONTAINER_TEMPLATES = [
]
def _advanced_component_types():
def _advanced_component_types(show_unsupported):
"""
Return advanced component types which can be created.
"""
disabled_create_block_types = XBlockDisableConfig.disabled_create_block_types()
return [c_type for c_type in ADVANCED_COMPONENT_TYPES if c_type not in disabled_create_block_types]
disabled_create_block_types = disabled_xblocks()
enabled_components = [c_type for c_type in ADVANCED_COMPONENT_TYPES if c_type not in disabled_create_block_types]
authorable_blocks = authorable_xblocks(allow_unsupported=show_unsupported)
if authorable_blocks is not None:
filtered_blocks = {}
for block in authorable_blocks:
if block.name in enabled_components:
filtered_blocks[block.name] = block.support_level
return filtered_blocks
else:
all_blocks = {}
for c_type in authorable_blocks:
all_blocks[c_type] = True
return all_blocks
def _load_mixed_class(category):
......@@ -152,7 +164,7 @@ 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):
def create_template_dict(name, cat, boilerplate_name=None, tab="common", hinted=False, support_level="full"):
"""
Creates a component template dict.
......@@ -169,9 +181,24 @@ def get_component_templates(courselike, library=False):
"category": cat,
"boilerplate_name": boilerplate_name,
"hinted": hinted,
"tab": tab
"tab": tab,
"support_level": support_level
}
def component_editable(enabled_types, template=None):
if enabled_types is None:
return True
if template is None:
template = ""
extension_index = template.rfind(".yaml")
if extension_index:
template = template[0:extension_index]
for block in enabled_types:
if block.template == template:
return block.support_level
return False
component_display_names = {
'discussion': _("Discussion"),
'html': _("HTML"),
......@@ -189,14 +216,22 @@ def get_component_templates(courselike, library=False):
if library:
component_types = [component for component in component_types if component != 'discussion']
component_types = [component for component in component_types if component not in disabled_xblocks()]
allow_unsupported = not courselike.enforce_supported_xblocks
for category in component_types:
enabled_types = authorable_xblocks(allow_unsupported=allow_unsupported, name=category)
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)
supported = component_editable(enabled_types)
if supported:
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'))
templates_for_category.append(
create_template_dict(display_name, category, None, 'advanced', support_level=supported)
)
categories.add(category)
# add boilerplates
......@@ -204,6 +239,8 @@ def get_component_templates(courselike, library=False):
for template in component_class.templates():
filter_templates = getattr(component_class, 'filter_templates', None)
if not filter_templates or filter_templates(template, courselike):
supported = component_editable(enabled_types, template.get('template_id'))
if supported:
# Tab can be 'common' 'advanced'
# Default setting is common/advanced depending on the presence of markdown
tab = 'common'
......@@ -213,26 +250,32 @@ def get_component_templates(courselike, library=False):
templates_for_category.append(
create_template_dict(
_(template['metadata'].get('display_name')), # pylint: disable=translation-of-non-string
_(template['metadata'].get('display_name')),
# pylint: disable=translation-of-non-string
category,
template.get('template_id'),
tab,
hinted,
supported
)
)
# Add any advanced problem types
# Add any advanced problem types. Note that these are different xblocks being stored as Advanced Problems.
if category == 'problem':
for advanced_problem_type in ADVANCED_PROBLEM_TYPES:
component = advanced_problem_type['component']
advanced_enabled_types = authorable_xblocks(allow_unsupported=allow_unsupported, name=component)
boilerplate_name = advanced_problem_type['boilerplate_name']
supported = component_editable(advanced_enabled_types, boilerplate_name)
if supported:
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')
create_template_dict(component_display_name, component, boilerplate_name, 'advanced',
support_level=supported)
)
categories.add(component)
......@@ -252,18 +295,19 @@ def get_component_templates(courselike, library=False):
# 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()
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 and category not in categories:
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
category,
support_level=advanced_component_types[category]
)
)
categories.add(category)
......
......@@ -99,7 +99,7 @@ from xmodule.modulestore import EdxJSONEncoder
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError
from xmodule.tabs import CourseTab, CourseTabList, InvalidTabsException
from xblock_django.api import deprecated_xblocks
log = logging.getLogger(__name__)
......@@ -599,7 +599,8 @@ def course_index(request, course_key):
except (ItemNotFoundError, CourseActionStateItemNotFoundError):
current_action = None
deprecated_blocks_info = _deprecated_blocks_info(course_module, settings.DEPRECATED_BLOCK_TYPES)
deprecated_block_names = [block.name for block in deprecated_xblocks()]
deprecated_blocks_info = _deprecated_blocks_info(course_module, deprecated_block_names)
return render_to_response('course_outline.html', {
'context_course': course_module,
......
......@@ -21,6 +21,9 @@
<li class="editor-md empty">
<button type="button" class="button-component" data-category="<%= templates[i].category %>">
<span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%-templates[i].support_level %>)</span>
<% } %>
</button>
</li>
<% } else { %>
......@@ -28,6 +31,9 @@
<button type="button" class="button-component" data-category="<%= templates[i].category %>"
data-boilerplate="<%= templates[i].boilerplate_name %>">
<span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%- templates[i].support_level %>)</span>
<% } %>
</button>
</li>
<% } %>
......@@ -43,6 +49,9 @@
<button type="button" class="button-component" data-category="<%= templates[i].category %>"
data-boilerplate="<%= templates[i].boilerplate_name %>">
<span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%- templates[i].support_level %>)</span>
<% } %>
</button>
</li>
<% } %>
......
......@@ -12,6 +12,9 @@
<li class="editor-md empty">
<button type="button" class="button-component" data-category="<%= templates[i].category %>">
<span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%-templates[i].support_level%>)</span>
<% } %>
</button>
</li>
<% } else { %>
......@@ -19,6 +22,9 @@
<button type="button" class="button-component" data-category="<%= templates[i].category %>"
data-boilerplate="<%= templates[i].boilerplate_name %>">
<span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%- templates[i].support_level %>)</span>
<% } %>
</button>
</li>
<% } %>
......@@ -27,3 +33,4 @@
<button class="cancel-button" data-type="<%= type %>"><%= gettext("Cancel") %></button>
</div>
<% } %>
......@@ -413,6 +413,13 @@ class CourseFields(object):
help=_("Enter the names of the advanced components to use in your course."),
scope=Scope.settings
)
enforce_supported_xblocks = Boolean(
display_name = _("Only allow the creation of fully supported components"),
help = _(
"Only allow the creation of fully supported and accessible components in Studio. Scary legal text..."
),
scope = Scope.settings, default = True
)
has_children = True
info_sidebar_name = String(
display_name=_("Course Home Sidebar Name"),
......
......@@ -49,9 +49,9 @@ except ImportError:
HAS_USER_SERVICE = False
try:
from xblock_django.models import XBlockDisableConfig
from xblock_django.api import disabled_xblocks
except ImportError:
XBlockDisableConfig = None
disabled_xblocks = None
log = logging.getLogger(__name__)
ASSET_IGNORE_REGEX = getattr(settings, "ASSET_IGNORE_REGEX", r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)")
......@@ -188,8 +188,8 @@ def create_modulestore_instance(
if 'read_preference' in doc_store_config:
doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference'])
if XBlockDisableConfig and settings.FEATURES.get('ENABLE_DISABLING_XBLOCK_TYPES', False):
disabled_xblock_types = XBlockDisableConfig.disabled_block_types()
if disabled_xblocks:
disabled_xblock_types = disabled_xblocks()
else:
disabled_xblock_types = ()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment