custom tabs

* still needs better error checking and testing
This commit is contained in:
Victor Shnayder
2012-09-20 00:51:23 -04:00
parent 084a91e325
commit 7a88223ef7
5 changed files with 87 additions and 1 deletions

View File

@@ -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/')

View File

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

View 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>

View File

@@ -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