Hook up link to create modules from templates
This commit is contained in:
@@ -6,7 +6,7 @@ import sys
|
||||
from lxml import etree
|
||||
from path import path
|
||||
|
||||
from .x_module import XModule
|
||||
from .x_module import XModule, Template
|
||||
from .xml_module import XmlDescriptor, name_to_pathname
|
||||
from .editing_module import EditingDescriptor
|
||||
from .stringify import stringify_children
|
||||
@@ -34,6 +34,10 @@ class HtmlDescriptor(XmlDescriptor, EditingDescriptor):
|
||||
module_class = HtmlModule
|
||||
filename_extension = "xml"
|
||||
|
||||
templates = [
|
||||
Template('Empty', '', [])
|
||||
]
|
||||
|
||||
# VS[compat] TODO (cpennington): Delete this method once all fall 2012 course
|
||||
# are being edited in the cms
|
||||
@classmethod
|
||||
|
||||
@@ -297,8 +297,11 @@ class ModuleStore(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
# TODO (cpennington): Replace with clone_item
|
||||
def create_item(self, location, editor):
|
||||
def clone_item(self, source, location):
|
||||
"""
|
||||
Clone a new item that is a copy of the item at the location `source`
|
||||
and writes it to `location`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def update_item(self, location, data):
|
||||
|
||||
@@ -237,20 +237,16 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
|
||||
return self._load_items(list(items), depth)
|
||||
|
||||
# TODO (cpennington): This needs to be replaced by clone_item as soon as we allow
|
||||
# creation of items from the cms
|
||||
def create_item(self, location):
|
||||
def clone_item(self, source, location):
|
||||
"""
|
||||
Create an empty item at the specified location.
|
||||
|
||||
If that location already exists, raises a DuplicateItemError
|
||||
|
||||
location: Something that can be passed to Location
|
||||
Clone a new item that is a copy of the item at the location `source`
|
||||
and writes it to `location`
|
||||
"""
|
||||
try:
|
||||
self.collection.insert({
|
||||
'_id': Location(location).dict(),
|
||||
})
|
||||
source_item = self.collection.find_one(location_to_query(source))
|
||||
source_item['_id'] = Location(location).dict()
|
||||
self.collection.insert(source_item)
|
||||
return self._load_items([source_item])[0]
|
||||
except pymongo.errors.DuplicateKeyError:
|
||||
raise DuplicateItemError(location)
|
||||
|
||||
|
||||
@@ -471,10 +471,6 @@ class XMLModuleStore(ModuleStoreBase):
|
||||
"""
|
||||
return dict( (k, self.errored_courses[k].errors) for k in self.errored_courses)
|
||||
|
||||
def create_item(self, location):
|
||||
raise NotImplementedError("XMLModuleStores are read-only")
|
||||
|
||||
|
||||
def update_item(self, location, data):
|
||||
"""
|
||||
Set the data in the item specified by the location to
|
||||
|
||||
@@ -24,13 +24,6 @@ def import_from_xml(store, data_dir, course_dirs=None,
|
||||
for course_id in module_store.modules.keys():
|
||||
for module in module_store.modules[course_id].itervalues():
|
||||
|
||||
# TODO (cpennington): This forces import to overrite the same items.
|
||||
# This should in the future create new revisions of the items on import
|
||||
try:
|
||||
store.create_item(module.location)
|
||||
except DuplicateItemError:
|
||||
log.exception('Item already exists at %s' % module.location.url())
|
||||
pass
|
||||
if 'data' in module.definition:
|
||||
store.update_item(module.location, module.definition['data'])
|
||||
if 'children' in module.definition:
|
||||
|
||||
30
common/lib/xmodule/xmodule/templates.py
Normal file
30
common/lib/xmodule/xmodule/templates.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from collections import defaultdict
|
||||
from .x_module import XModuleDescriptor
|
||||
from .modulestore import Location
|
||||
from .modulestore.django import modulestore
|
||||
|
||||
|
||||
def all_templates():
|
||||
"""
|
||||
Returns all templates for enabled modules, grouped by descriptor type
|
||||
"""
|
||||
|
||||
templates = defaultdict(list)
|
||||
for category, descriptor in XModuleDescriptor.load_classes():
|
||||
templates[category] = descriptor.templates
|
||||
|
||||
return templates
|
||||
|
||||
|
||||
def update_templates():
|
||||
"""
|
||||
Updates the set of templates in the modulestore with all templates currently
|
||||
available from the installed plugins
|
||||
"""
|
||||
|
||||
for category, templates in all_templates().items():
|
||||
for template in templates:
|
||||
template_location = Location('i4x', 'edx', 'templates', category, Location.clean_for_url_name(template.name))
|
||||
modulestore().update_item(template_location, template.data)
|
||||
modulestore().update_children(template_location, template.children)
|
||||
modulestore().update_metadata(template_location, {'display_name': template.name})
|
||||
@@ -7,6 +7,7 @@ from functools import partial
|
||||
from lxml import etree
|
||||
from lxml.etree import XMLSyntaxError
|
||||
from pprint import pprint
|
||||
from collections import namedtuple
|
||||
|
||||
from xmodule.errortracker import exc_info_to_str
|
||||
from xmodule.modulestore import Location
|
||||
@@ -71,7 +72,11 @@ class Plugin(object):
|
||||
|
||||
@classmethod
|
||||
def load_classes(cls):
|
||||
return [class_.load()
|
||||
"""
|
||||
Returns a list of containing the identifiers and their corresponding classes for all
|
||||
of the available instances of this plugin
|
||||
"""
|
||||
return [(class_.name, class_.load())
|
||||
for class_
|
||||
in pkg_resources.iter_entry_points(cls.entry_point)]
|
||||
|
||||
@@ -321,6 +326,9 @@ def policy_key(location):
|
||||
return '{cat}/{name}'.format(cat=location.category, name=location.name)
|
||||
|
||||
|
||||
Template = namedtuple("Template", "name data children")
|
||||
|
||||
|
||||
class XModuleDescriptor(Plugin, HTMLSnippet):
|
||||
"""
|
||||
An XModuleDescriptor is a specification for an element of a course. This
|
||||
@@ -361,6 +369,11 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
|
||||
equality_attributes = ('definition', 'metadata', 'location',
|
||||
'shared_state_key', '_inherited_metadata')
|
||||
|
||||
# A list of Template objects that describe possible templates that can be used
|
||||
# to create a module of this type.
|
||||
# If no templates are provided, there will be no way to create a module of this type
|
||||
templates = []
|
||||
|
||||
# ============================= STRUCTURAL MANIPULATION ===================
|
||||
def __init__(self,
|
||||
system,
|
||||
|
||||
Reference in New Issue
Block a user