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:
Calen Pennington
2014-05-22 10:52:00 -04:00
178 changed files with 4916 additions and 3629 deletions

View File

@@ -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):
"""