Commit 9f4df44b by Calen Pennington

Merge pull request #337 from MITx/feature/victor/use-url-names

Feature/victor/use url names
parents d90fc6b2 8db816a1
...@@ -108,7 +108,7 @@ def edit_item(request): ...@@ -108,7 +108,7 @@ def edit_item(request):
'contents': item.get_html(), 'contents': item.get_html(),
'js_module': item.js_module_name, 'js_module': item.js_module_name,
'category': item.category, 'category': item.category,
'name': item.name, 'url_name': item.url_name,
'previews': get_module_previews(request, item), 'previews': get_module_previews(request, item),
}) })
......
<section id="unit-wrapper"> <section id="unit-wrapper">
<header> <header>
<section> <section>
<h1 class="editable">${name}</h1> <h1 class="editable">${url_name}</h1>
<p class="${category}"><a href="#">${category}</a></p> <p class="${category}"><a href="#">${category}</a></p>
</section> </section>
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
% for week in weeks: % for week in weeks:
<li class="week" data-id="${week.location.url()}"> <li class="week" data-id="${week.location.url()}">
<header> <header>
<h1><a href="#" class="week-edit">${week.name}</a></h1> <h1><a href="#" class="week-edit">${week.url_name}</a></h1>
<ul> <ul>
% if 'goals' in week.metadata: % if 'goals' in week.metadata:
% for goal in week.metadata['goals']: % for goal in week.metadata['goals']:
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
data-type="${module.js_module_name}" data-type="${module.js_module_name}"
data-preview-type="${module.module_class.js_module_name}"> data-preview-type="${module.module_class.js_module_name}">
<a href="#" class="module-edit">${module.name}</a> <a href="#" class="module-edit">${module.url_name}</a>
<a href="#" class="draggable">handle</a> <a href="#" class="draggable">handle</a>
</li> </li>
% endfor % endfor
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
<a href="#" class="module-edit" <a href="#" class="module-edit"
data-id="${child.location.url()}" data-id="${child.location.url()}"
data-type="${child.js_module_name}" data-type="${child.js_module_name}"
data-preview-type="${child.module_class.js_module_name}">${child.name}</a> data-preview-type="${child.module_class.js_module_name}">${child.url_name}</a>
<a href="#" class="draggable">handle</a> <a href="#" class="draggable">handle</a>
</li> </li>
%endfor %endfor
......
...@@ -288,20 +288,30 @@ class LoncapaProblem(object): ...@@ -288,20 +288,30 @@ class LoncapaProblem(object):
try: try:
ifp = self.system.filestore.open(file) # open using ModuleSystem OSFS filestore ifp = self.system.filestore.open(file) # open using ModuleSystem OSFS filestore
except Exception as err: except Exception as err:
log.error('Error %s in problem xml include: %s' % (err, etree.tostring(inc, pretty_print=True))) log.error('Error %s in problem xml include: %s' % (
log.error('Cannot find file %s in %s' % (file, self.system.filestore)) err, etree.tostring(inc, pretty_print=True)))
if not self.system.get('DEBUG'): # if debugging, don't fail - just log error log.error('Cannot find file %s in %s' % (
file, self.system.filestore))
# if debugging, don't fail - just log error
# TODO (vshnayder): need real error handling, display to users
if not self.system.get('DEBUG'):
raise raise
else: continue else:
continue
try: try:
incxml = etree.XML(ifp.read()) # read in and convert to XML incxml = etree.XML(ifp.read()) # read in and convert to XML
except Exception as err: except Exception as err:
log.error('Error %s in problem xml include: %s' % (err, etree.tostring(inc, pretty_print=True))) log.error('Error %s in problem xml include: %s' % (
err, etree.tostring(inc, pretty_print=True)))
log.error('Cannot parse XML in %s' % (file)) log.error('Cannot parse XML in %s' % (file))
if not self.system.get('DEBUG'): # if debugging, don't fail - just log error # if debugging, don't fail - just log error
# TODO (vshnayder): same as above
if not self.system.get('DEBUG'):
raise raise
else: continue else:
parent = inc.getparent() # insert new XML into tree in place of inlcude continue
# insert new XML into tree in place of inlcude
parent = inc.getparent()
parent.insert(parent.index(inc), incxml) parent.insert(parent.index(inc), incxml)
parent.remove(inc) parent.remove(inc)
log.debug('Included %s into %s' % (file, self.problem_id)) log.debug('Included %s into %s' % (file, self.problem_id))
......
...@@ -121,13 +121,13 @@ class HtmlDescriptor(XmlDescriptor, EditingDescriptor): ...@@ -121,13 +121,13 @@ class HtmlDescriptor(XmlDescriptor, EditingDescriptor):
# Not proper format. Write html to file, return an empty tag # Not proper format. Write html to file, return an empty tag
filepath = u'{category}/{name}.html'.format(category=self.category, filepath = u'{category}/{name}.html'.format(category=self.category,
name=self.name) name=self.url_name)
resource_fs.makedir(os.path.dirname(filepath), allow_recreate=True) resource_fs.makedir(os.path.dirname(filepath), allow_recreate=True)
with resource_fs.open(filepath, 'w') as file: with resource_fs.open(filepath, 'w') as file:
file.write(self.definition['data']) file.write(self.definition['data'])
elt = etree.Element('html') elt = etree.Element('html')
elt.set("filename", self.name) elt.set("filename", self.url_name)
return elt return elt
...@@ -87,6 +87,7 @@ def path_to_location(modulestore, location, course_name=None): ...@@ -87,6 +87,7 @@ def path_to_location(modulestore, location, course_name=None):
n = len(path) n = len(path)
course_id = CourseDescriptor.location_to_id(path[0]) course_id = CourseDescriptor.location_to_id(path[0])
# pull out the location names
chapter = path[1].name if n > 1 else None chapter = path[1].name if n > 1 else None
section = path[2].name if n > 2 else None section = path[2].name if n > 2 else None
......
...@@ -23,11 +23,12 @@ class VideoModule(XModule): ...@@ -23,11 +23,12 @@ class VideoModule(XModule):
css = {'scss': [resource_string(__name__, 'css/video/display.scss')]} css = {'scss': [resource_string(__name__, 'css/video/display.scss')]}
js_module_name = "Video" js_module_name = "Video"
def __init__(self, system, location, definition, instance_state=None, shared_state=None, **kwargs): def __init__(self, system, location, definition,
XModule.__init__(self, system, location, definition, instance_state, shared_state, **kwargs) instance_state=None, shared_state=None, **kwargs):
XModule.__init__(self, system, location, definition,
instance_state, shared_state, **kwargs)
xmltree = etree.fromstring(self.definition['data']) xmltree = etree.fromstring(self.definition['data'])
self.youtube = xmltree.get('youtube') self.youtube = xmltree.get('youtube')
self.name = xmltree.get('name')
self.position = 0 self.position = 0
if instance_state is not None: if instance_state is not None:
...@@ -71,7 +72,7 @@ class VideoModule(XModule): ...@@ -71,7 +72,7 @@ class VideoModule(XModule):
'streams': self.video_list(), 'streams': self.video_list(),
'id': self.location.html_id(), 'id': self.location.html_id(),
'position': self.position, 'position': self.position,
'name': self.name, 'display_name': self.display_name,
# TODO (cpennington): This won't work when we move to data that isn't on the filesystem # TODO (cpennington): This won't work when we move to data that isn't on the filesystem
'data_dir': self.metadata['data_dir'], 'data_dir': self.metadata['data_dir'],
}) })
......
...@@ -191,11 +191,20 @@ class XModule(HTMLSnippet): ...@@ -191,11 +191,20 @@ class XModule(HTMLSnippet):
self.instance_state = instance_state self.instance_state = instance_state
self.shared_state = shared_state self.shared_state = shared_state
self.id = self.location.url() self.id = self.location.url()
self.name = self.location.name self.url_name = self.location.name
self.category = self.location.category self.category = self.location.category
self.metadata = kwargs.get('metadata', {}) self.metadata = kwargs.get('metadata', {})
self._loaded_children = None self._loaded_children = None
@property
def display_name(self):
'''
Return a display name for the module: use display_name if defined in
metadata, otherwise convert the url name.
'''
return self.metadata.get('display_name',
self.url_name.replace('_', ' '))
def get_children(self): def get_children(self):
''' '''
Return module instances for all the children of this module. Return module instances for all the children of this module.
...@@ -339,6 +348,8 @@ class XModuleDescriptor(Plugin, HTMLSnippet): ...@@ -339,6 +348,8 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
module module
display_name: The name to use for displaying this module to the display_name: The name to use for displaying this module to the
user user
url_name: The name to use for this module in urls and other places
where a unique name is needed.
format: The format of this module ('Homework', 'Lab', etc) format: The format of this module ('Homework', 'Lab', etc)
graded (bool): Whether this module is should be graded or not graded (bool): Whether this module is should be graded or not
start (string): The date for which this module will be available start (string): The date for which this module will be available
...@@ -353,7 +364,7 @@ class XModuleDescriptor(Plugin, HTMLSnippet): ...@@ -353,7 +364,7 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
self.metadata = kwargs.get('metadata', {}) self.metadata = kwargs.get('metadata', {})
self.definition = definition if definition is not None else {} self.definition = definition if definition is not None else {}
self.location = Location(kwargs.get('location')) self.location = Location(kwargs.get('location'))
self.name = self.location.name self.url_name = self.location.name
self.category = self.location.category self.category = self.location.category
self.shared_state_key = kwargs.get('shared_state_key') self.shared_state_key = kwargs.get('shared_state_key')
...@@ -361,6 +372,15 @@ class XModuleDescriptor(Plugin, HTMLSnippet): ...@@ -361,6 +372,15 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
self._inherited_metadata = set() self._inherited_metadata = set()
@property @property
def display_name(self):
'''
Return a display name for the module: use display_name if defined in
metadata, otherwise convert the url name.
'''
return self.metadata.get('display_name',
self.url_name.replace('_', ' '))
@property
def own_metadata(self): def own_metadata(self):
""" """
Return the metadata that is not inherited, but was defined on this module. Return the metadata that is not inherited, but was defined on this module.
......
...@@ -225,7 +225,7 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -225,7 +225,7 @@ class XmlDescriptor(XModuleDescriptor):
# Write it to a file if necessary # Write it to a file if necessary
if self.split_to_file(xml_object): if self.split_to_file(xml_object):
# Put this object in its own file # Put this object in its own file
filepath = self.__class__._format_filepath(self.category, self.name) filepath = self.__class__._format_filepath(self.category, self.url_name)
resource_fs.makedir(os.path.dirname(filepath), allow_recreate=True) resource_fs.makedir(os.path.dirname(filepath), allow_recreate=True)
with resource_fs.open(filepath, 'w') as file: with resource_fs.open(filepath, 'w') as file:
file.write(etree.tostring(xml_object, pretty_print=True)) file.write(etree.tostring(xml_object, pretty_print=True))
...@@ -238,10 +238,10 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -238,10 +238,10 @@ class XmlDescriptor(XModuleDescriptor):
xml_object.tail = '' xml_object.tail = ''
xml_object.set('filename', self.name) xml_object.set('filename', self.url_name)
# Add the metadata # Add the metadata
xml_object.set('url_name', self.name) xml_object.set('url_name', self.url_name)
for attr in self.metadata_attributes: for attr in self.metadata_attributes:
attr_map = self.xml_attribute_map.get(attr, AttrMap(attr)) attr_map = self.xml_attribute_map.get(attr, AttrMap(attr))
metadata_key = attr_map.metadata_key metadata_key = attr_map.metadata_key
......
...@@ -83,7 +83,7 @@ def get_course_about_section(course, section_key): ...@@ -83,7 +83,7 @@ def get_course_about_section(course, section_key):
log.warning("Missing about section {key} in course {url}".format(key=section_key, url=course.location.url())) log.warning("Missing about section {key} in course {url}".format(key=section_key, url=course.location.url()))
return None return None
elif section_key == "title": elif section_key == "title":
return course.metadata.get('display_name', course.name) return course.metadata.get('display_name', course.url_name)
elif section_key == "university": elif section_key == "university":
return course.location.org return course.location.org
elif section_key == "number": elif section_key == "number":
......
...@@ -12,18 +12,23 @@ _log = logging.getLogger("mitx.courseware") ...@@ -12,18 +12,23 @@ _log = logging.getLogger("mitx.courseware")
def grade_sheet(student, course, grader, student_module_cache): def grade_sheet(student, course, grader, student_module_cache):
""" """
This pulls a summary of all problems in the course. It returns a dictionary with two datastructures: This pulls a summary of all problems in the course. It returns a dictionary
with two datastructures:
- courseware_summary is a summary of all sections with problems in the course. It is organized as an array of chapters, - courseware_summary is a summary of all sections with problems in the
each containing an array of sections, each containing an array of scores. This contains information for graded and ungraded course. It is organized as an array of chapters, each containing an array of
problems, and is good for displaying a course summary with due dates, etc. sections, each containing an array of scores. This contains information for
graded and ungraded problems, and is good for displaying a course summary
with due dates, etc.
- grade_summary is the output from the course grader. More information on the format is in the docstring for CourseGrader. - grade_summary is the output from the course grader. More information on
the format is in the docstring for CourseGrader.
Arguments: Arguments:
student: A User object for the student to grade student: A User object for the student to grade
course: An XModule containing the course to grade course: An XModule containing the course to grade
student_module_cache: A StudentModuleCache initialized with all instance_modules for the student student_module_cache: A StudentModuleCache initialized with all
instance_modules for the student
""" """
totaled_scores = {} totaled_scores = {}
chapters = [] chapters = []
...@@ -51,12 +56,16 @@ def grade_sheet(student, course, grader, student_module_cache): ...@@ -51,12 +56,16 @@ def grade_sheet(student, course, grader, student_module_cache):
correct = total correct = total
if not total > 0: if not total > 0:
#We simply cannot grade a problem that is 12/0, because we might need it as a percentage #We simply cannot grade a problem that is 12/0, because we
#might need it as a percentage
graded = False graded = False
scores.append(Score(correct, total, graded, module.metadata.get('display_name'))) scores.append(Score(correct, total, graded,
module.metadata.get('display_name')))
section_total, graded_total = graders.aggregate_scores(
scores, s.metadata.get('display_name'))
section_total, graded_total = graders.aggregate_scores(scores, s.metadata.get('display_name'))
#Add the graded total to totaled_scores #Add the graded total to totaled_scores
format = s.metadata.get('format', "") format = s.metadata.get('format', "")
if format and graded_total.possible > 0: if format and graded_total.possible > 0:
...@@ -65,7 +74,8 @@ def grade_sheet(student, course, grader, student_module_cache): ...@@ -65,7 +74,8 @@ def grade_sheet(student, course, grader, student_module_cache):
totaled_scores[format] = format_scores totaled_scores[format] = format_scores
sections.append({ sections.append({
'section': s.metadata.get('display_name'), 'display_name': s.display_name,
'url_name': s.url_name,
'scores': scores, 'scores': scores,
'section_total': section_total, 'section_total': section_total,
'format': format, 'format': format,
...@@ -73,8 +83,9 @@ def grade_sheet(student, course, grader, student_module_cache): ...@@ -73,8 +83,9 @@ def grade_sheet(student, course, grader, student_module_cache):
'graded': graded, 'graded': graded,
}) })
chapters.append({'course': course.metadata.get('display_name'), chapters.append({'course': course.display_name,
'chapter': c.metadata.get('display_name'), 'display_name': c.display_name,
'url_name': c.url_name,
'sections': sections}) 'sections': sections})
grade_summary = grader.grade(totaled_scores) grade_summary = grader.grade(totaled_scores)
......
...@@ -61,11 +61,7 @@ def import_with_checks(course_dir, verbose=True): ...@@ -61,11 +61,7 @@ def import_with_checks(course_dir, verbose=True):
course_dirs=course_dirs) course_dirs=course_dirs)
def str_of_err(tpl): def str_of_err(tpl):
(msg, exc_info) = tpl (msg, exc_str) = tpl
if exc_info is None:
return msg
exc_str = '\n'.join(traceback.format_exception(*exc_info))
return '{msg}\n{exc}'.format(msg=msg, exc=exc_str) return '{msg}\n{exc}'.format(msg=msg, exc=exc_str)
courses = modulestore.get_courses() courses = modulestore.get_courses()
...@@ -83,7 +79,7 @@ def import_with_checks(course_dir, verbose=True): ...@@ -83,7 +79,7 @@ def import_with_checks(course_dir, verbose=True):
print '\n' print '\n'
print "=" * 40 print "=" * 40
print 'ERRORs during import:' print 'ERRORs during import:'
print '\n'.join(map(str_of_err,errors)) print '\n'.join(map(str_of_err, errors))
print "=" * 40 print "=" * 40
print '\n' print '\n'
......
...@@ -35,10 +35,12 @@ def toc_for_course(user, request, course, active_chapter, active_section): ...@@ -35,10 +35,12 @@ def toc_for_course(user, request, course, active_chapter, active_section):
Create a table of contents from the module store Create a table of contents from the module store
Return format: Return format:
[ {'name': name, 'sections': SECTIONS, 'active': bool}, ... ] [ {'display_name': name, 'url_name': url_name,
'sections': SECTIONS, 'active': bool}, ... ]
where SECTIONS is a list where SECTIONS is a list
[ {'name': name, 'format': format, 'due': due, 'active' : bool}, ...] [ {'display_name': name, 'url_name': url_name,
'format': format, 'due': due, 'active' : bool}, ...]
active is set for the section and chapter corresponding to the passed active is set for the section and chapter corresponding to the passed
parameters. Everything else comes from the xml, or defaults to "". parameters. Everything else comes from the xml, or defaults to "".
...@@ -54,19 +56,21 @@ def toc_for_course(user, request, course, active_chapter, active_section): ...@@ -54,19 +56,21 @@ def toc_for_course(user, request, course, active_chapter, active_section):
sections = list() sections = list()
for section in chapter.get_display_items(): for section in chapter.get_display_items():
active = (chapter.metadata.get('display_name') == active_chapter and active = (chapter.display_name == active_chapter and
section.metadata.get('display_name') == active_section) section.display_name == active_section)
hide_from_toc = section.metadata.get('hide_from_toc', 'false').lower() == 'true' hide_from_toc = section.metadata.get('hide_from_toc', 'false').lower() == 'true'
if not hide_from_toc: if not hide_from_toc:
sections.append({'name': section.metadata.get('display_name'), sections.append({'display_name': section.display_name,
'url_name': section.url_name,
'format': section.metadata.get('format', ''), 'format': section.metadata.get('format', ''),
'due': section.metadata.get('due', ''), 'due': section.metadata.get('due', ''),
'active': active}) 'active': active})
chapters.append({'name': chapter.metadata.get('display_name'), chapters.append({'display_name': chapter.display_name,
'url_name': chapter.url_name,
'sections': sections, 'sections': sections,
'active': chapter.metadata.get('display_name') == active_chapter}) 'active': chapter.display_name == active_chapter})
return chapters return chapters
...@@ -76,8 +80,8 @@ def get_section(course_module, chapter, section): ...@@ -76,8 +80,8 @@ def get_section(course_module, chapter, section):
or None if this doesn't specify a valid section or None if this doesn't specify a valid section
course: Course url course: Course url
chapter: Chapter name chapter: Chapter url_name
section: Section name section: Section url_name
""" """
if course_module is None: if course_module is None:
...@@ -85,7 +89,7 @@ def get_section(course_module, chapter, section): ...@@ -85,7 +89,7 @@ def get_section(course_module, chapter, section):
chapter_module = None chapter_module = None
for _chapter in course_module.get_children(): for _chapter in course_module.get_children():
if _chapter.metadata.get('display_name') == chapter: if _chapter.url_name == chapter:
chapter_module = _chapter chapter_module = _chapter
break break
...@@ -94,7 +98,7 @@ def get_section(course_module, chapter, section): ...@@ -94,7 +98,7 @@ def get_section(course_module, chapter, section):
section_module = None section_module = None
for _section in chapter_module.get_children(): for _section in chapter_module.get_children():
if _section.metadata.get('display_name') == section: if _section.url_name == section:
section_module = _section section_module = _section
break break
......
...@@ -54,11 +54,6 @@ def user_groups(user): ...@@ -54,11 +54,6 @@ def user_groups(user):
return group_names return group_names
def format_url_params(params):
return [urllib.quote(string.replace(' ', '_'))
if string is not None else None
for string in params]
@ensure_csrf_cookie @ensure_csrf_cookie
@cache_if_anonymous @cache_if_anonymous
...@@ -124,7 +119,6 @@ def profile(request, course_id, student_id=None): ...@@ -124,7 +119,6 @@ def profile(request, course_id, student_id=None):
'language': user_info.language, 'language': user_info.language,
'email': student.email, 'email': student.email,
'course': course, 'course': course,
'format_url_params': format_url_params,
'csrf': csrf(request)['csrf_token'] 'csrf': csrf(request)['csrf_token']
} }
context.update(grades.grade_sheet(student, course_module, course.grader, student_module_cache)) context.update(grades.grade_sheet(student, course_module, course.grader, student_module_cache))
...@@ -138,9 +132,9 @@ def render_accordion(request, course, chapter, section): ...@@ -138,9 +132,9 @@ def render_accordion(request, course, chapter, section):
If chapter and section are '' or None, renders a default accordion. If chapter and section are '' or None, renders a default accordion.
Returns (initialization_javascript, content)''' Returns the html string'''
# TODO (cpennington): do the right thing with courses # grab the table of contents
toc = toc_for_course(request.user, request, course, chapter, section) toc = toc_for_course(request.user, request, course, chapter, section)
active_chapter = 1 active_chapter = 1
...@@ -152,7 +146,6 @@ def render_accordion(request, course, chapter, section): ...@@ -152,7 +146,6 @@ def render_accordion(request, course, chapter, section):
('toc', toc), ('toc', toc),
('course_name', course.title), ('course_name', course.title),
('course_id', course.id), ('course_id', course.id),
('format_url_params', format_url_params),
('csrf', csrf(request)['csrf_token'])] + template_imports.items()) ('csrf', csrf(request)['csrf_token'])] + template_imports.items())
return render_to_string('accordion.html', context) return render_to_string('accordion.html', context)
...@@ -169,9 +162,9 @@ def index(request, course_id, chapter=None, section=None, ...@@ -169,9 +162,9 @@ def index(request, course_id, chapter=None, section=None,
Arguments: Arguments:
- request : HTTP request - request : HTTP request
- course : coursename (str) - course_id : course id (str: ORG/course/URL_NAME)
- chapter : chapter name (str) - chapter : chapter url_name (str)
- section : section name (str) - section : section url_name (str)
- position : position in module, eg of <sequential> module (str) - position : position in module, eg of <sequential> module (str)
Returns: Returns:
...@@ -180,16 +173,6 @@ def index(request, course_id, chapter=None, section=None, ...@@ -180,16 +173,6 @@ def index(request, course_id, chapter=None, section=None,
''' '''
course = check_course(course_id) course = check_course(course_id)
def clean(s):
''' Fixes URLs -- we convert spaces to _ in URLs to prevent
funny encoding characters and keep the URLs readable. This undoes
that transformation.
'''
return s.replace('_', ' ') if s is not None else None
chapter = clean(chapter)
section = clean(section)
try: try:
context = { context = {
'csrf': csrf(request)['csrf_token'], 'csrf': csrf(request)['csrf_token'],
...@@ -202,8 +185,6 @@ def index(request, course_id, chapter=None, section=None, ...@@ -202,8 +185,6 @@ def index(request, course_id, chapter=None, section=None,
look_for_module = chapter is not None and section is not None look_for_module = chapter is not None and section is not None
if look_for_module: if look_for_module:
# TODO (cpennington): Pass the right course in here
section_descriptor = get_section(course, chapter, section) section_descriptor = get_section(course, chapter, section)
if section_descriptor is not None: if section_descriptor is not None:
student_module_cache = StudentModuleCache(request.user, student_module_cache = StudentModuleCache(request.user,
......
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
<%def name="make_chapter(chapter)"> <%def name="make_chapter(chapter)">
<h3><a href="#">${chapter['name']}</a></h3> <h3><a href="#">${chapter['display_name']}</a></h3>
<ul> <ul>
% for section in chapter['sections']: % for section in chapter['sections']:
<li${' class="active"' if 'active' in section and section['active'] else ''}> <li${' class="active"' if 'active' in section and section['active'] else ''}>
<a href="${reverse('courseware_section', args=[course_id] + format_url_params([chapter['name'], section['name']]))}"> <a href="${reverse('courseware_section', args=[course_id, chapter['url_name'], section['url_name']])}">
<p>${section['name']} <p>${section['display_name']}
<span class="subtitle"> <span class="subtitle">
${section['format']} ${"due " + section['due'] if 'due' in section and section['due'] != '' else ''} ${section['format']} ${"due " + section['due'] if 'due' in section and section['due'] != '' else ''}
</span> </span>
......
...@@ -125,9 +125,9 @@ $(function() { ...@@ -125,9 +125,9 @@ $(function() {
<ol class="chapters"> <ol class="chapters">
%for chapter in courseware_summary: %for chapter in courseware_summary:
%if not chapter['chapter'] == "hidden": %if not chapter['display_name'] == "hidden":
<li> <li>
<h2>${ chapter['chapter'] }</h2> <h2>${ chapter['display_name'] }</h2>
<ol class="sections"> <ol class="sections">
%for section in chapter['sections']: %for section in chapter['sections']:
...@@ -138,8 +138,8 @@ $(function() { ...@@ -138,8 +138,8 @@ $(function() {
percentageString = "{0:.0%}".format( float(earned)/total) if earned > 0 and total > 0 else "" percentageString = "{0:.0%}".format( float(earned)/total) if earned > 0 and total > 0 else ""
%> %>
<h3><a href="${reverse('courseware_section', kwargs={'course_id' : course.id, 'chapter' : chapter['chapter'], 'section' : section['section']})}"> <h3><a href="${reverse('courseware_section', kwargs={'course_id' : course.id, 'chapter' : chapter['url_name'], 'section' : section['url_name']})}">
${ section['section'] }</a> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</h3> ${ section['display_name'] }</a> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</h3>
${section['format']} ${section['format']}
%if 'due' in section and section['due']!="": %if 'due' in section and section['due']!="":
due ${section['due']} due ${section['due']}
......
% if name is not UNDEFINED and name is not None: % if name is not UNDEFINED and name is not None:
<h1> ${name} </h1> <h1> ${display_name} </h1>
% endif % endif
<div id="video_${id}" class="video" data-streams="${streams}" data-caption-data-dir="${data_dir}"> <div id="video_${id}" class="video" data-streams="${streams}" data-caption-data-dir="${data_dir}">
......
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