Merge remote-tracking branch 'edx/master' into opaque-keys
Conflicts: cms/djangoapps/contentstore/tests/test_contentstore.py cms/djangoapps/contentstore/views/component.py cms/djangoapps/contentstore/views/item.py cms/djangoapps/contentstore/views/preview.py cms/djangoapps/contentstore/views/tests/test_container.py cms/static/js/spec/views/unit_spec.js cms/static/js/utils/module.js cms/templates/container.html cms/templates/studio_vertical_wrapper.html cms/templates/studio_xblock_wrapper.html common/djangoapps/student/views.py lms/templates/notes.html lms/templates/textannotation.html lms/templates/videoannotation.html
This commit is contained in:
@@ -157,70 +157,7 @@ def unit_handler(request, usage_key_string):
|
||||
except ItemNotFoundError:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
component_templates = defaultdict(list)
|
||||
for category in COMPONENT_TYPES:
|
||||
component_class = _load_mixed_class(category)
|
||||
# add the default template
|
||||
# TODO: Once mixins are defined per-application, rather than per-runtime,
|
||||
# this should use a cms mixed-in class. (cpennington)
|
||||
if hasattr(component_class, 'display_name'):
|
||||
display_name = component_class.display_name.default or 'Blank'
|
||||
else:
|
||||
display_name = 'Blank'
|
||||
component_templates[category].append((
|
||||
display_name,
|
||||
category,
|
||||
False, # No defaults have markdown (hardcoded current default)
|
||||
None # no boilerplate for overrides
|
||||
))
|
||||
# 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):
|
||||
component_templates[category].append((
|
||||
template['metadata'].get('display_name'),
|
||||
category,
|
||||
template['metadata'].get('markdown') is not None,
|
||||
template.get('template_id')
|
||||
))
|
||||
|
||||
# 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
|
||||
|
||||
# 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:
|
||||
# Do I need to allow for boilerplates or just defaults on the
|
||||
# class? i.e., can an advanced have more than one entry in the
|
||||
# menu? one for default and others for prefilled boilerplates?
|
||||
try:
|
||||
component_class = _load_mixed_class(category)
|
||||
|
||||
component_templates['advanced'].append(
|
||||
(
|
||||
component_class.display_name.default or category,
|
||||
category,
|
||||
False,
|
||||
None # don't override default data
|
||||
)
|
||||
)
|
||||
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
|
||||
pass
|
||||
else:
|
||||
log.error(
|
||||
"Improper format for course advanced keys! %s",
|
||||
course_advanced_keys
|
||||
)
|
||||
component_templates = _get_component_templates(course)
|
||||
|
||||
xblocks = item.get_children()
|
||||
|
||||
@@ -259,9 +196,15 @@ def unit_handler(request, usage_key_string):
|
||||
return render_to_response('unit.html', {
|
||||
'context_course': course,
|
||||
'unit': item,
|
||||
<<<<<<< HEAD
|
||||
'unit_locator': usage_key,
|
||||
'xblocks': xblocks,
|
||||
'component_templates': component_templates,
|
||||
=======
|
||||
'unit_locator': locator,
|
||||
'locators': locators,
|
||||
'component_templates': json.dumps(component_templates),
|
||||
>>>>>>> edx/master
|
||||
'draft_preview_link': preview_lms_link,
|
||||
'published_preview_link': lms_link,
|
||||
'subsection': containing_subsection,
|
||||
@@ -301,6 +244,7 @@ def container_handler(request, usage_key_string):
|
||||
except ItemNotFoundError:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
component_templates = _get_component_templates(course)
|
||||
ancestor_xblocks = []
|
||||
parent = get_parent_xblock(xblock)
|
||||
while parent and parent.category != 'sequential':
|
||||
@@ -317,11 +261,106 @@ def container_handler(request, usage_key_string):
|
||||
'xblock_locator': usage_key,
|
||||
'unit': None if not ancestor_xblocks else ancestor_xblocks[0],
|
||||
'ancestor_xblocks': ancestor_xblocks,
|
||||
'component_templates': json.dumps(component_templates),
|
||||
})
|
||||
else:
|
||||
return HttpResponseBadRequest("Only supports html requests")
|
||||
|
||||
|
||||
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_templates = []
|
||||
# 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
|
||||
# TODO: Once mixins are defined per-application, rather than per-runtime,
|
||||
# this should use a cms mixed-in class. (cpennington)
|
||||
if hasattr(component_class, 'display_name'):
|
||||
display_name = component_class.display_name.default or 'Blank'
|
||||
else:
|
||||
display_name = 'Blank'
|
||||
templates_for_category.append(create_template_dict(display_name, 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
|
||||
)
|
||||
)
|
||||
component_templates.append({"type": category, "templates": templates_for_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": []}
|
||||
# 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:
|
||||
# boilerplates not supported for advanced components
|
||||
try:
|
||||
component_class = _load_mixed_class(category)
|
||||
|
||||
advanced_component_templates['templates'].append(
|
||||
create_template_dict(
|
||||
component_class.display_name.default or category,
|
||||
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
|
||||
|
||||
|
||||
@login_required
|
||||
def _get_item_in_course(request, usage_key):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user