Implement a stub unified course tab
This commit is contained in:
committed by
Brian Jacobel
parent
4d1d709e5c
commit
75d89e8115
@@ -2,6 +2,8 @@
|
||||
This module is essentially a broker to xmodule/tabs.py -- it was originally introduced to
|
||||
perform some LMS-specific tab display gymnastics for the Entrance Exams feature
|
||||
"""
|
||||
import waffle
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
|
||||
@@ -9,7 +11,7 @@ from courseware.access import has_access
|
||||
from courseware.entrance_exams import user_can_skip_entrance_exam
|
||||
from openedx.core.lib.course_tabs import CourseTabPluginManager
|
||||
from student.models import CourseEnrollment
|
||||
from xmodule.tabs import CourseTab, CourseTabList, key_checker
|
||||
from xmodule.tabs import CourseTab, CourseTabList, key_checker, link_reverse_func
|
||||
|
||||
|
||||
class EnrolledTab(CourseTab):
|
||||
@@ -34,6 +36,16 @@ class CoursewareTab(EnrolledTab):
|
||||
is_movable = False
|
||||
is_default = False
|
||||
|
||||
@property
|
||||
def link_func(self):
|
||||
"""
|
||||
Returns a function that computes the URL for this tab.
|
||||
"""
|
||||
if waffle.switch_is_active('unified_course_view'):
|
||||
return link_reverse_func('unified_course_view')
|
||||
else:
|
||||
return link_reverse_func('courseware')
|
||||
|
||||
|
||||
class CourseInfoTab(CourseTab):
|
||||
"""
|
||||
|
||||
@@ -25,6 +25,7 @@ from django.http import (
|
||||
QueryDict,
|
||||
)
|
||||
from django.shortcuts import redirect
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.timezone import UTC
|
||||
from django.utils.translation import ugettext as _
|
||||
@@ -1623,3 +1624,55 @@ def financial_assistance_form(request):
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
class UnifiedCourseView(View):
|
||||
"""
|
||||
Unified view for a course.
|
||||
"""
|
||||
@method_decorator(login_required)
|
||||
@method_decorator(ensure_csrf_cookie)
|
||||
@method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True))
|
||||
@method_decorator(ensure_valid_course_key)
|
||||
def get(self, request, course_id):
|
||||
"""
|
||||
Displays the main view for the specified course.
|
||||
|
||||
Arguments:
|
||||
request: HTTP request
|
||||
course_id (unicode): course id
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
|
||||
|
||||
# Render the outline as a fragment
|
||||
outline_fragment = CourseOutlineFragmentView().render_fragment(request, course_id=course_id)
|
||||
|
||||
# Render the entire unified course view
|
||||
context = {
|
||||
'csrf': csrf(request)['csrf_token'],
|
||||
'course': course,
|
||||
'outline_fragment': outline_fragment,
|
||||
'disable_courseware_js': True,
|
||||
'uses_pattern_library': True,
|
||||
}
|
||||
return render_to_response('courseware/unified-course-view.html', context)
|
||||
|
||||
|
||||
class CourseOutlineFragmentView(FragmentView):
|
||||
"""
|
||||
Course outline fragment to be shown in the unified course view.
|
||||
"""
|
||||
|
||||
def render_fragment(self, request, course_id=None):
|
||||
"""
|
||||
Renders the course outline as a fragment.
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
|
||||
context = {
|
||||
'csrf': csrf(request)['csrf_token'],
|
||||
'course': course,
|
||||
}
|
||||
html = render_to_string('courseware/course-outline.html', context)
|
||||
return Fragment(html)
|
||||
|
||||
12
lms/templates/courseware/course-outline.html
Normal file
12
lms/templates/courseware/course-outline.html
Normal file
@@ -0,0 +1,12 @@
|
||||
## mako
|
||||
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
|
||||
<%!
|
||||
import json
|
||||
from django.utils.translation import ugettext as _
|
||||
%>
|
||||
|
||||
<section class="course-outline" id="course-outline">
|
||||
<p>Hello, world!</p>
|
||||
</section>
|
||||
72
lms/templates/courseware/unified-course-view.html
Normal file
72
lms/templates/courseware/unified-course-view.html
Normal file
@@ -0,0 +1,72 @@
|
||||
## mako
|
||||
|
||||
<%! main_css = "style-main-v2" %>
|
||||
|
||||
<%page expression_filter="h"/>
|
||||
<%inherit file="../main.html" />
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%def name="online_help_token()"><% return "courseware" %></%def>
|
||||
<%def name="course_name()">
|
||||
<% return _("{course_number} Courseware").format(course_number=course.display_number_with_default) %>
|
||||
</%def>
|
||||
|
||||
<%!
|
||||
import json
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.template.defaultfilters import escapejs
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from django_comment_client.permissions import has_permission
|
||||
from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
%>
|
||||
|
||||
<%block name="bodyclass">course</%block>
|
||||
|
||||
<%block name="pagetitle">${course_name()}</%block>
|
||||
|
||||
<%include file="../courseware/course_navigation.html" args="active_page='courseware'" />
|
||||
|
||||
<%block name="headextra">
|
||||
${HTML(outline_fragment.head_html())}
|
||||
</%block>
|
||||
|
||||
<%block name="js_extra">
|
||||
${HTML(outline_fragment.foot_html())}
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
<section class="course-view container" id="course-container">
|
||||
<header class="page-header has-secondary">
|
||||
## Breadcrumb navigation
|
||||
<div class="page-header-main">
|
||||
<nav aria-label="${_('Discussions')}" class="sr-is-focusable" tabindex="-1">
|
||||
<div class="has-breadcrumbs"></div>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="page-header-secondary">
|
||||
<div class="form-actions">
|
||||
<a class="btn btn-small" href="${reverse('courseware', kwargs={'course_id': unicode(course.id.to_deprecated_string())})}">
|
||||
${_("Resume Course")}
|
||||
</a>
|
||||
</div>
|
||||
<div class="page-header-search">
|
||||
<form class="search-form" role="search">
|
||||
<label class="field-label sr-only" for="search" id="search-hint">Search the course</label>
|
||||
<input
|
||||
class="field-input input-text search-input"
|
||||
type="search"
|
||||
name="search"
|
||||
id="search"
|
||||
placeholder="Search the course"
|
||||
/>
|
||||
<button class="btn btn-small search-btn" type="button">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="page-content">
|
||||
${HTML(outline_fragment.body_html())}
|
||||
</div>
|
||||
</section>
|
||||
</%block>
|
||||
15
lms/urls.py
15
lms/urls.py
@@ -11,6 +11,7 @@ from django.conf.urls.static import static
|
||||
from courseware.views.views import CourseTabView, EnrollStaffView, StaticCourseTabView
|
||||
from config_models.views import ConfigurationModelCurrentAPIView
|
||||
from courseware.views.index import CoursewareIndex
|
||||
from courseware.views.views import UnifiedCourseView, CourseOutlineFragmentView
|
||||
from openedx.core.djangoapps.auth_exchange.views import LoginWithAccessTokenView
|
||||
from openedx.core.djangoapps.catalog.models import CatalogIntegration
|
||||
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
|
||||
@@ -379,6 +380,20 @@ urlpatterns += (
|
||||
name='html_book',
|
||||
),
|
||||
|
||||
url(
|
||||
r'^courses/{}/course/?$'.format(
|
||||
settings.COURSE_ID_PATTERN,
|
||||
),
|
||||
UnifiedCourseView.as_view(),
|
||||
name='unified_course_view',
|
||||
),
|
||||
url(
|
||||
r'^courses/{}/course/outline?$'.format(
|
||||
settings.COURSE_ID_PATTERN,
|
||||
),
|
||||
CourseOutlineFragmentView.as_view(),
|
||||
name='course_outline_fragment_view',
|
||||
),
|
||||
url(
|
||||
r'^courses/{}/courseware/?$'.format(
|
||||
settings.COURSE_ID_PATTERN,
|
||||
|
||||
Reference in New Issue
Block a user