Commit edf6f7c7 by cahrens

WIP

parent c85d8ad8
...@@ -27,7 +27,7 @@ from opaque_keys.edx.keys import UsageKey ...@@ -27,7 +27,7 @@ from opaque_keys.edx.keys import UsageKey
from student.auth import has_course_author_access from student.auth import has_course_author_access
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from xblock_django.models import XBlockDisableConfig from xblock_django.api import disabled_xblocks, authorable_xblocks
__all__ = [ __all__ = [
'container_handler', 'container_handler',
...@@ -52,12 +52,24 @@ CONTAINER_TEMPLATES = [ ...@@ -52,12 +52,24 @@ CONTAINER_TEMPLATES = [
] ]
def _advanced_component_types(): def _advanced_component_types(show_unsupported):
""" """
Return advanced component types which can be created. Return advanced component types which can be created.
""" """
disabled_create_block_types = XBlockDisableConfig.disabled_create_block_types() disabled_create_block_types = disabled_xblocks()
return [c_type for c_type in ADVANCED_COMPONENT_TYPES if c_type not in disabled_create_block_types] 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): def _load_mixed_class(category):
...@@ -152,7 +164,7 @@ def get_component_templates(courselike, library=False): ...@@ -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. 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. Creates a component template dict.
...@@ -169,9 +181,24 @@ def get_component_templates(courselike, library=False): ...@@ -169,9 +181,24 @@ def get_component_templates(courselike, library=False):
"category": cat, "category": cat,
"boilerplate_name": boilerplate_name, "boilerplate_name": boilerplate_name,
"hinted": hinted, "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 = { component_display_names = {
'discussion': _("Discussion"), 'discussion': _("Discussion"),
'html': _("HTML"), 'html': _("HTML"),
...@@ -189,52 +216,68 @@ def get_component_templates(courselike, library=False): ...@@ -189,52 +216,68 @@ def get_component_templates(courselike, library=False):
if library: if library:
component_types = [component for component in component_types if component != 'discussion'] 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: for category in component_types:
enabled_types = authorable_xblocks(allow_unsupported=allow_unsupported, name=category)
templates_for_category = [] templates_for_category = []
component_class = _load_mixed_class(category) component_class = _load_mixed_class(category)
# add the default template with localized display name # add the default template with localized display name
# TODO: Once mixins are defined per-application, rather than per-runtime, # TODO: Once mixins are defined per-application, rather than per-runtime,
# this should use a cms mixed-in class. (cpennington) # this should use a cms mixed-in class. (cpennington)
display_name = xblock_type_display_name(category, _('Blank')) # this is the Blank Advanced problem supported = component_editable(enabled_types)
templates_for_category.append(create_template_dict(display_name, category, None, 'advanced')) if supported:
categories.add(category) 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', support_level=supported)
)
categories.add(category)
# add boilerplates # add boilerplates
if hasattr(component_class, 'templates'): if hasattr(component_class, 'templates'):
for template in component_class.templates(): for template in component_class.templates():
filter_templates = getattr(component_class, 'filter_templates', None) filter_templates = getattr(component_class, 'filter_templates', None)
if not filter_templates or filter_templates(template, courselike): if not filter_templates or filter_templates(template, courselike):
# Tab can be 'common' 'advanced' supported = component_editable(enabled_types, template.get('template_id'))
# Default setting is common/advanced depending on the presence of markdown if supported:
tab = 'common' # Tab can be 'common' 'advanced'
if template['metadata'].get('markdown') is None: # Default setting is common/advanced depending on the presence of markdown
tab = 'advanced' tab = 'common'
hinted = template.get('hinted', False) if template['metadata'].get('markdown') is None:
tab = 'advanced'
templates_for_category.append( hinted = template.get('hinted', False)
create_template_dict(
_(template['metadata'].get('display_name')), # pylint: disable=translation-of-non-string templates_for_category.append(
category, create_template_dict(
template.get('template_id'), _(template['metadata'].get('display_name')),
tab, # pylint: disable=translation-of-non-string
hinted, 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': if category == 'problem':
for advanced_problem_type in ADVANCED_PROBLEM_TYPES: for advanced_problem_type in ADVANCED_PROBLEM_TYPES:
component = advanced_problem_type['component'] component = advanced_problem_type['component']
advanced_enabled_types = authorable_xblocks(allow_unsupported=allow_unsupported, name=component)
boilerplate_name = advanced_problem_type['boilerplate_name'] boilerplate_name = advanced_problem_type['boilerplate_name']
try: supported = component_editable(advanced_enabled_types, boilerplate_name)
component_display_name = xblock_type_display_name(component) if supported:
except PluginMissingError: try:
log.warning('Unable to load xblock type %s to read display_name', component, exc_info=True) component_display_name = xblock_type_display_name(component)
else: except PluginMissingError:
templates_for_category.append( log.warning('Unable to load xblock type %s to read display_name', component, exc_info=True)
create_template_dict(component_display_name, component, boilerplate_name, 'advanced') else:
) templates_for_category.append(
categories.add(component) create_template_dict(component_display_name, component, boilerplate_name, 'advanced',
support_level=supported)
)
categories.add(component)
component_templates.append({ component_templates.append({
"type": category, "type": category,
...@@ -252,18 +295,19 @@ def get_component_templates(courselike, library=False): ...@@ -252,18 +295,19 @@ def get_component_templates(courselike, library=False):
# enabled for the course. # enabled for the course.
course_advanced_keys = courselike.advanced_modules course_advanced_keys = courselike.advanced_modules
advanced_component_templates = {"type": "advanced", "templates": [], "display_name": _("Advanced")} 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 # Set component types according to course policy file
if isinstance(course_advanced_keys, list): if isinstance(course_advanced_keys, list):
for category in course_advanced_keys: 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 # boilerplates not supported for advanced components
try: try:
component_display_name = xblock_type_display_name(category, default_display_name=category) component_display_name = xblock_type_display_name(category, default_display_name=category)
advanced_component_templates['templates'].append( advanced_component_templates['templates'].append(
create_template_dict( create_template_dict(
component_display_name, component_display_name,
category category,
support_level=advanced_component_types[category]
) )
) )
categories.add(category) categories.add(category)
......
...@@ -99,7 +99,7 @@ from xmodule.modulestore import EdxJSONEncoder ...@@ -99,7 +99,7 @@ from xmodule.modulestore import EdxJSONEncoder
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError
from xmodule.tabs import CourseTab, CourseTabList, InvalidTabsException from xmodule.tabs import CourseTab, CourseTabList, InvalidTabsException
from xblock_django.api import deprecated_xblocks
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -599,7 +599,8 @@ def course_index(request, course_key): ...@@ -599,7 +599,8 @@ def course_index(request, course_key):
except (ItemNotFoundError, CourseActionStateItemNotFoundError): except (ItemNotFoundError, CourseActionStateItemNotFoundError):
current_action = None 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', { return render_to_response('course_outline.html', {
'context_course': course_module, 'context_course': course_module,
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
<li class="editor-md empty"> <li class="editor-md empty">
<button type="button" class="button-component" data-category="<%= templates[i].category %>"> <button type="button" class="button-component" data-category="<%= templates[i].category %>">
<span class="name"><%= templates[i].display_name %></span> <span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%-templates[i].support_level %>)</span>
<% } %>
</button> </button>
</li> </li>
<% } else { %> <% } else { %>
...@@ -28,6 +31,9 @@ ...@@ -28,6 +31,9 @@
<button type="button" class="button-component" data-category="<%= templates[i].category %>" <button type="button" class="button-component" data-category="<%= templates[i].category %>"
data-boilerplate="<%= templates[i].boilerplate_name %>"> data-boilerplate="<%= templates[i].boilerplate_name %>">
<span class="name"><%= templates[i].display_name %></span> <span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%- templates[i].support_level %>)</span>
<% } %>
</button> </button>
</li> </li>
<% } %> <% } %>
...@@ -43,6 +49,9 @@ ...@@ -43,6 +49,9 @@
<button type="button" class="button-component" data-category="<%= templates[i].category %>" <button type="button" class="button-component" data-category="<%= templates[i].category %>"
data-boilerplate="<%= templates[i].boilerplate_name %>"> data-boilerplate="<%= templates[i].boilerplate_name %>">
<span class="name"><%= templates[i].display_name %></span> <span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%- templates[i].support_level %>)</span>
<% } %>
</button> </button>
</li> </li>
<% } %> <% } %>
...@@ -50,4 +59,4 @@ ...@@ -50,4 +59,4 @@
</ul> </ul>
</div> </div>
<button class="cancel-button" data-type="<%= type %>"><%= gettext("Cancel") %></button> <button class="cancel-button" data-type="<%= type %>"><%= gettext("Cancel") %></button>
</div> </div>
\ No newline at end of file
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
<li class="editor-md empty"> <li class="editor-md empty">
<button type="button" class="button-component" data-category="<%= templates[i].category %>"> <button type="button" class="button-component" data-category="<%= templates[i].category %>">
<span class="name"><%= templates[i].display_name %></span> <span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%-templates[i].support_level%>)</span>
<% } %>
</button> </button>
</li> </li>
<% } else { %> <% } else { %>
...@@ -19,6 +22,9 @@ ...@@ -19,6 +22,9 @@
<button type="button" class="button-component" data-category="<%= templates[i].category %>" <button type="button" class="button-component" data-category="<%= templates[i].category %>"
data-boilerplate="<%= templates[i].boilerplate_name %>"> data-boilerplate="<%= templates[i].boilerplate_name %>">
<span class="name"><%= templates[i].display_name %></span> <span class="name"><%= templates[i].display_name %></span>
<% if (templates[i].support_level !== true){ %>
<span class="support">(<%- templates[i].support_level %>)</span>
<% } %>
</button> </button>
</li> </li>
<% } %> <% } %>
...@@ -27,3 +33,4 @@ ...@@ -27,3 +33,4 @@
<button class="cancel-button" data-type="<%= type %>"><%= gettext("Cancel") %></button> <button class="cancel-button" data-type="<%= type %>"><%= gettext("Cancel") %></button>
</div> </div>
<% } %> <% } %>
...@@ -413,6 +413,13 @@ class CourseFields(object): ...@@ -413,6 +413,13 @@ class CourseFields(object):
help=_("Enter the names of the advanced components to use in your course."), help=_("Enter the names of the advanced components to use in your course."),
scope=Scope.settings 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 has_children = True
info_sidebar_name = String( info_sidebar_name = String(
display_name=_("Course Home Sidebar Name"), display_name=_("Course Home Sidebar Name"),
......
...@@ -49,9 +49,9 @@ except ImportError: ...@@ -49,9 +49,9 @@ except ImportError:
HAS_USER_SERVICE = False HAS_USER_SERVICE = False
try: try:
from xblock_django.models import XBlockDisableConfig from xblock_django.api import disabled_xblocks
except ImportError: except ImportError:
XBlockDisableConfig = None disabled_xblocks = None
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
ASSET_IGNORE_REGEX = getattr(settings, "ASSET_IGNORE_REGEX", r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)") ASSET_IGNORE_REGEX = getattr(settings, "ASSET_IGNORE_REGEX", r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)")
...@@ -188,8 +188,8 @@ def create_modulestore_instance( ...@@ -188,8 +188,8 @@ def create_modulestore_instance(
if 'read_preference' in doc_store_config: if 'read_preference' in doc_store_config:
doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference']) doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference'])
if XBlockDisableConfig and settings.FEATURES.get('ENABLE_DISABLING_XBLOCK_TYPES', False): if disabled_xblocks:
disabled_xblock_types = XBlockDisableConfig.disabled_block_types() disabled_xblock_types = disabled_xblocks()
else: else:
disabled_xblock_types = () 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