custom tabs
* still needs better error checking and testing
This commit is contained in:
@@ -16,6 +16,7 @@ from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from courseware.access import has_access
|
||||
from static_replace import replace_urls
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -77,6 +78,11 @@ def _external_link(tab, user, course, active_page):
|
||||
# external links are never active
|
||||
return [CourseTab(tab['name'], tab['link'], False)]
|
||||
|
||||
def _static_tab(tab, user, course, active_page):
|
||||
link = reverse('static_tab', args=[course.id, tab['url_slug']])
|
||||
active_str = 'static_tab_{0}'.format(tab['url_slug'])
|
||||
return [CourseTab(tab['name'], link, active_page==active_str)]
|
||||
|
||||
|
||||
def _textbooks(tab, user, course, active_page):
|
||||
"""
|
||||
@@ -123,6 +129,7 @@ VALID_TAB_TYPES = {
|
||||
'external_link': TabImpl(key_checker(['name', 'link']), _external_link),
|
||||
'textbooks': TabImpl(null_validator, _textbooks),
|
||||
'progress': TabImpl(need_name, _progress),
|
||||
'static_tab': TabImpl(key_checker(['name', 'url_slug']), _static_tab),
|
||||
}
|
||||
|
||||
|
||||
@@ -227,3 +234,33 @@ def get_default_tabs(user, course, active_page):
|
||||
tabs.append(CourseTab('Instructor', link, active_page=='instructor'))
|
||||
|
||||
return tabs
|
||||
|
||||
def get_static_tab_by_slug(tabs, tab_slug):
|
||||
"""
|
||||
Look for a tab with type 'static_tab' and the specified 'tab_slug'. Returns
|
||||
the tab (a config dict), or None if not found.
|
||||
"""
|
||||
for tab in tabs:
|
||||
# if the tab is misconfigured, this will blow up. The validation code should check...
|
||||
if tab['type'] == 'static_tab' and tab['url_slug'] == tab_slug:
|
||||
return tab
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_static_tab_contents(course, tab):
|
||||
"""
|
||||
Given a course and a static tab config dict, load the tab contents,
|
||||
returning None if not found.
|
||||
|
||||
Looks in tabs/{course_url_name}/{tab_slug}.html first, then tabs/{tab_slug}.html.
|
||||
"""
|
||||
slug = tab['url_slug']
|
||||
paths = ['tabs/{0}/{1}.html'.format(course.url_name, slug), 'tabs/{0}.html'.format(slug)]
|
||||
fs = course.system.resources_fs
|
||||
for p in paths:
|
||||
if fs.exists(p):
|
||||
with fs.open(p) as tabfile:
|
||||
# TODO: redundant with module_render.py. Want to be helper methods in static_replace or something.
|
||||
contents = replace_urls(tabfile.read(), course.metadata['data_dir'])
|
||||
return replace_urls(contents, staticfiles_prefix='/courses/'+course.id, replace_prefix='/course/')
|
||||
|
||||
@@ -22,6 +22,7 @@ from django.views.decorators.cache import cache_control
|
||||
from courseware import grades
|
||||
from courseware.access import has_access
|
||||
from courseware.courses import (get_course_with_access, get_courses_by_university)
|
||||
import courseware.tabs as tabs
|
||||
from models import StudentModuleCache
|
||||
from module_render import toc_for_course, get_module, get_instance_module
|
||||
from student.models import UserProfile
|
||||
@@ -343,6 +344,30 @@ def course_info(request, course_id):
|
||||
return render_to_response('courseware/info.html', {'course': course,
|
||||
'staff_access': staff_access,})
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def static_tab(request, course_id, tab_slug):
|
||||
"""
|
||||
Display the courses tab with the given name.
|
||||
|
||||
Assumes the course_id is in a valid format.
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'load')
|
||||
|
||||
tab = tabs.get_static_tab_by_slug(course.tabs, tab_slug)
|
||||
if tab is None:
|
||||
raise Http404
|
||||
|
||||
contents = tabs.get_static_tab_contents(course, tab)
|
||||
if contents is None:
|
||||
raise Http404
|
||||
|
||||
staff_access = has_access(request.user, course, 'staff')
|
||||
return render_to_response('courseware/static_tab.html',
|
||||
{'course': course,
|
||||
'tab': tab,
|
||||
'tab_contents': contents,
|
||||
'staff_access': staff_access,})
|
||||
|
||||
# TODO arjun: remove when custom tabs in place, see courseware/syllabus.py
|
||||
@ensure_csrf_cookie
|
||||
def syllabus(request, course_id):
|
||||
@@ -357,6 +382,7 @@ def syllabus(request, course_id):
|
||||
return render_to_response('courseware/syllabus.html', {'course': course,
|
||||
'staff_access': staff_access,})
|
||||
|
||||
|
||||
def registered_for_course(course, user):
|
||||
'''Return CourseEnrollment if user is registered for course, else False'''
|
||||
if user is None:
|
||||
|
||||
16
lms/templates/courseware/static_tab.html
Normal file
16
lms/templates/courseware/static_tab.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<%inherit file="/main.html" />
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
|
||||
<%block name="headextra">
|
||||
<%static:css group='course'/>
|
||||
</%block>
|
||||
|
||||
<%block name="title"><title>${course.number} ${tab['name']}</title></%block>
|
||||
|
||||
<%include file="/courseware/course_navigation.html" args="active_page='static_tab_{0}'.format(tab['url_slug'])" />
|
||||
|
||||
<section class="container">
|
||||
<div class="static_tab_wrapper">
|
||||
${tab_contents}
|
||||
</div>
|
||||
</section>
|
||||
@@ -164,6 +164,10 @@ if settings.COURSEWARE_ENABLED:
|
||||
'instructor.views.grade_summary', name='grade_summary'),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/enroll_students$',
|
||||
'instructor.views.enroll_students', name='enroll_students'),
|
||||
|
||||
# This MUST be the last view in the courseware--it's a catch-all for custom tabs.
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/(?P<tab_slug>.*)$',
|
||||
'courseware.views.static_tab', name="static_tab"),
|
||||
)
|
||||
|
||||
# discussion forums live within courseware, so courseware must be enabled first
|
||||
|
||||
Reference in New Issue
Block a user