308 lines
12 KiB
HTML
308 lines
12 KiB
HTML
<%page expression_filter="h"/>
|
|
<%namespace name='static' file='../static_content.html'/>
|
|
<%!
|
|
from django.utils.translation import gettext as _
|
|
from django.utils.translation import pgettext
|
|
from django.urls import reverse
|
|
from lms.djangoapps.courseware.courses import get_course_about_section
|
|
from django.conf import settings
|
|
from common.djangoapps.edxmako.shortcuts import marketing_link
|
|
from openedx.core.djangolib.js_utils import js_escaped_string
|
|
from openedx.core.djangolib.markup import clean_dangerous_html, HTML, Text
|
|
from openedx.core.lib.courses import course_image_url
|
|
%>
|
|
|
|
<%inherit file="../main.html" />
|
|
<%block name="headextra">
|
|
<%
|
|
site_domain = static.get_value('site_domain', settings.SITE_NAME)
|
|
site_protocol = 'https' if settings.HTTPS == 'on' else 'http'
|
|
|
|
og_img_url = "{protocol}://{domain}{path}".format(
|
|
protocol=site_protocol,
|
|
domain=site_domain,
|
|
path=course_image_urls['large']
|
|
)
|
|
%>
|
|
## OG (Open Graph) title, image and description added below to give social media info to display
|
|
## (https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content#tags)
|
|
<meta property="og:title" content="${course.display_name_with_default}" />
|
|
<meta property="og:image" content="${og_img_url}" />
|
|
<meta property="og:description" content="${get_course_about_section(request, course, 'short_description')}" />
|
|
</%block>
|
|
|
|
<%block name="js_extra">
|
|
<script type="text/javascript">
|
|
(function() {
|
|
$(".register").click(function(event) {
|
|
$("#class_enroll_form").submit();
|
|
event.preventDefault();
|
|
});
|
|
|
|
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
|
|
if (xhr.status == 200) {
|
|
if (xhr.responseText == "") {
|
|
location.href = "${reverse('dashboard') | n, js_escaped_string}";
|
|
}
|
|
else {
|
|
location.href = xhr.responseText;
|
|
}
|
|
} else if (xhr.status == 403) {
|
|
// redirect unauthenticated user to the login page
|
|
location.replace("${reverse('signin_user') | n, js_escaped_string}?next=" + encodeURIComponent("${request.path | n, js_escaped_string}"));
|
|
} else {
|
|
$('#register_error').text(
|
|
(xhr.responseText ? xhr.responseText : "${_("An error occurred. Please try again later.") | n, js_escaped_string}")
|
|
).css("display", "block");
|
|
}
|
|
});
|
|
|
|
})(this)
|
|
</script>
|
|
|
|
<script src="${static.url('js/course_info.js')}"></script>
|
|
</%block>
|
|
|
|
<%block name="pagetitle">${course.display_name_with_default}</%block>
|
|
|
|
<section class="course-info">
|
|
|
|
<%block name="course_about_header">
|
|
<header class="course-profile">
|
|
<div class="intro-inner-wrapper">
|
|
<div class="table">
|
|
<section class="intro">
|
|
<div class="heading-group">
|
|
<p><small>${course.display_org_with_default}</small></p>
|
|
<h1>${course.display_name_with_default}</h1>
|
|
<br />
|
|
<p>${get_course_about_section(request, course, 'short_description')}</p>
|
|
</div>
|
|
|
|
<div class="main-cta">
|
|
%if user.is_authenticated and registered:
|
|
%if show_courseware_link:
|
|
<a href="${course_target}">
|
|
%endif
|
|
|
|
<span class="register disabled">${_("You are enrolled in this course")}</span>
|
|
|
|
%if show_courseware_link:
|
|
<strong>${_("View Course")}</strong>
|
|
</a>
|
|
%endif
|
|
|
|
% elif is_course_full:
|
|
<span class="register disabled">
|
|
${_("Course is full")}
|
|
</span>
|
|
% elif invitation_only and not can_enroll:
|
|
<span class="register disabled">${_("Enrollment in this course is by invitation only")}</span>
|
|
## Shib courses need the enrollment button to be displayed even when can_enroll is False,
|
|
## because AnonymousUsers cause can_enroll for shib courses to be False, but we need them to be able to click
|
|
## so that they can register and become a real user that can enroll.
|
|
% elif not is_shib_course and not can_enroll:
|
|
<span class="register disabled">${_("Enrollment is Closed")}</span>
|
|
%elif allow_anonymous:
|
|
%if show_courseware_link:
|
|
<a href="${course_target}">
|
|
<strong>${_("View Course")}</strong>
|
|
</a>
|
|
%endif
|
|
%else:
|
|
<%
|
|
if ecommerce_checkout:
|
|
reg_href = ecommerce_checkout_link
|
|
else:
|
|
reg_href="#"
|
|
if single_paid_mode:
|
|
href_class = "add-to-cart"
|
|
else:
|
|
href_class = "register"
|
|
%>
|
|
<a href="${reg_href}" class="${href_class}">
|
|
${_("Enroll Now")}
|
|
</a>
|
|
<div id="register_error"></div>
|
|
%endif
|
|
</div>
|
|
|
|
</section>
|
|
% if get_course_about_section(request, course, "video"):
|
|
<a href="#video-modal" class="media" rel="leanModal">
|
|
<div class="hero">
|
|
<img src="${course_image_urls['large']}" alt="" />
|
|
<div class="play-intro"></div>
|
|
</div>
|
|
</a>
|
|
%else:
|
|
<div class="media">
|
|
<div class="hero">
|
|
<img src="${course_image_urls['large']}" alt="" />
|
|
</div>
|
|
</div>
|
|
% endif
|
|
</div>
|
|
</div>
|
|
</header>
|
|
</%block>
|
|
|
|
<div class="container">
|
|
|
|
<%block name="course_about_details">
|
|
<div class="details">
|
|
% if staff_access and studio_url is not None:
|
|
<div class="wrap-instructor-info studio-view">
|
|
<a class="instructor-info-action" href="${studio_url}">${_("View About Page in studio")}</a>
|
|
</div>
|
|
% endif
|
|
|
|
<div class="inner-wrapper">
|
|
${clean_dangerous_html(get_course_about_section(request, course, "overview"))}
|
|
</div>
|
|
</div>
|
|
</%block>
|
|
|
|
<div class="course-sidebar">
|
|
<div class="course-summary">
|
|
|
|
<%include file="course_about_sidebar_header.html" />
|
|
|
|
<%block name="course_about_important_dates">
|
|
<ol class="important-dates">
|
|
<li class="important-dates-item">
|
|
<span class="icon fa fa-info-circle" aria-hidden="true"></span>
|
|
<p class="important-dates-item-title">${_("Course Number")}</p>
|
|
<span class="important-dates-item-text course-number">${course.display_number_with_default}</span>
|
|
</li>
|
|
% if not course.start_date_is_still_default:
|
|
<%
|
|
course_start_date = course.advertised_start or course.start
|
|
%>
|
|
<li class="important-dates-item">
|
|
<span class="icon fa fa-calendar" aria-hidden="true"></span>
|
|
<p class="important-dates-item-title">${_("Classes Start")}</p>
|
|
% if isinstance(course_start_date, str):
|
|
<span class="important-dates-item-text start-date">${course_start_date}</span>
|
|
% else:
|
|
<%
|
|
course_date_string = course_start_date.strftime('%Y-%m-%dT%H:%M:%S%z')
|
|
%>
|
|
<span class="important-dates-item-text start-date localized_datetime" data-format="shortDate" data-datetime="${course_date_string}" data-language="${LANGUAGE_CODE}"></span>
|
|
% endif
|
|
</li>
|
|
% endif
|
|
## We plan to ditch end_date (which is not stored in course metadata),
|
|
## but for backwards compatibility, show about/end_date blob if it exists.
|
|
% if course.end:
|
|
<%
|
|
course_end_date = course.end
|
|
%>
|
|
|
|
<li class="important-dates-item">
|
|
<span class="icon fa fa-calendar" aria-hidden="true"></span>
|
|
<p class="important-dates-item-title">${_("Classes End")}</p>
|
|
% if isinstance(course_end_date, str):
|
|
<span class="important-dates-item-text final-date">${course_end_date}</span>
|
|
% else:
|
|
<%
|
|
course_date_string = course_end_date.strftime('%Y-%m-%dT%H:%M:%S%z')
|
|
%>
|
|
<span class="important-dates-item-text final-date localized_datetime" data-format="shortDate" data-datetime="${course_date_string}" data-language="${LANGUAGE_CODE}"></span>
|
|
% endif
|
|
</li>
|
|
% endif
|
|
|
|
% if get_course_about_section(request, course, "effort"):
|
|
<li class="important-dates-item"><span class="icon fa fa-pencil" aria-hidden="true"></span><p class="important-dates-item-title">${_("Estimated Effort")}</p><span class="important-dates-item-text effort">${get_course_about_section(request, course, "effort")}</span></li>
|
|
% endif
|
|
|
|
##<li class="important-dates-item"><span class="icon fa fa-clock-o" aria-hidden="true"></span><p class="important-dates-item-title">${_('Course Length')}</p><span class="important-dates-item-text course-length">${_('{number} weeks').format(number=15)}</span></li>
|
|
|
|
%if course_price and (is_cosmetic_price_enabled):
|
|
<li class="important-dates-item">
|
|
<span class="icon fa fa-money" aria-hidden="true"></span>
|
|
<p class="important-dates-item-title">${_("Price")}</p>
|
|
<span class="important-dates-item-text">${course_price}</span>
|
|
</li>
|
|
%endif
|
|
|
|
% if pre_requisite_courses:
|
|
<% prc_target = reverse('about_course', args=[str(pre_requisite_courses[0]['key'])]) %>
|
|
<li class="prerequisite-course important-dates-item">
|
|
<span class="icon fa fa-list-ul" aria-hidden="true"></span>
|
|
<p class="important-dates-item-title">${_("Prerequisites")}</p>
|
|
## Multiple pre-requisite courses are not supported on frontend that's why we are pulling first element
|
|
<span class="important-dates-item-text pre-requisite"><a href="${prc_target}">${pre_requisite_courses[0]['display']}</a></span>
|
|
<p class="tip">
|
|
${Text(_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.")).format(
|
|
link_start=HTML('<a href="{}">').format(prc_target),
|
|
link_end=HTML('</a>'),
|
|
prc_display=pre_requisite_courses[0]['display'],
|
|
)}
|
|
</p>
|
|
</li>
|
|
% endif
|
|
|
|
% if get_course_about_section(request, course, "prerequisites"):
|
|
<li class="important-dates-item">
|
|
<span class="icon fa fa-book" aria-hidden="true"></span>
|
|
<p class="important-dates-item-title">${_("Requirements")}</p>
|
|
<span class="important-dates-item-text prerequisites">${get_course_about_section(request, course, "prerequisites")}</span>
|
|
</li>
|
|
% endif
|
|
</ol>
|
|
</%block>
|
|
</div>
|
|
|
|
## For now, ocw links are the only thing that goes in additional resources
|
|
% if get_course_about_section(request, course, "ocw_links"):
|
|
<div class="additional-resources">
|
|
<header>
|
|
<h1>${_("Additional Resources")}</h1>
|
|
</div>
|
|
|
|
<div>
|
|
## "MITOpenCourseware" should *not* be translated
|
|
<h2 class="opencourseware">MITOpenCourseware</h2>
|
|
${get_course_about_section(request, course, "ocw_links")}
|
|
</div>
|
|
</div>
|
|
%endif
|
|
|
|
% if sidebar_html_enabled:
|
|
% if get_course_about_section(request, course, "about_sidebar_html"):
|
|
<section class="about-sidebar-html">
|
|
${get_course_about_section(request, course, "about_sidebar_html")}
|
|
</section>
|
|
% endif
|
|
%endif
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
## Need to put this hidden form on the page so that the registration button works.
|
|
## Since it's no harm to display a hidden form, we display it with the most permissive conditional
|
|
## which is when the student is not registered.
|
|
%if active_reg_button or is_shib_course:
|
|
<div style="display: none;">
|
|
<form id="class_enroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
|
|
<fieldset class="enroll_fieldset">
|
|
<legend class="sr">${pgettext("self","Enroll")}</legend>
|
|
<input name="course_id" type="hidden" value="${course.id}">
|
|
<input name="enrollment_action" type="hidden" value="enroll">
|
|
</fieldset>
|
|
<div class="submit">
|
|
<input name="submit" type="submit" value="${pgettext('self','enroll')}">
|
|
</div>
|
|
</form>
|
|
</div>
|
|
%endif
|
|
|
|
<%include file="../video_modal.html" />
|
|
|
|
<%static:require_module_async module_name="js/dateutil_factory" class_name="DateUtilFactory">
|
|
DateUtilFactory.transform(iterationKey=".localized_datetime");
|
|
</%static:require_module_async>
|