Merge pull request #11900 from edx/nasthagiri/css-template
XSS Safe by default: dashboard, header, footer, navigation, help_modal
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%!
|
||||
from django.conf import settings
|
||||
@@ -36,8 +37,8 @@
|
||||
<h2 class="info-course">
|
||||
<span class="sr">${_("Current Course:")}</span>
|
||||
<a class="course-link" href="${index_url}">
|
||||
<span class="course-org">${context_course.display_org_with_default | h}</span><span class="course-number">${context_course.display_number_with_default | h}</span>
|
||||
<span class="course-title" title="${context_course.display_name_with_default_escaped}">${context_course.display_name_with_default_escaped}</span>
|
||||
<span class="course-org">${context_course.display_org_with_default}</span><span class="course-number">${context_course.display_number_with_default}</span>
|
||||
<span class="course-title" title="${context_course.display_name_with_default}">${context_course.display_name_with_default}</span>
|
||||
</a>
|
||||
</h2>
|
||||
|
||||
@@ -139,8 +140,8 @@
|
||||
<h2 class="info-course">
|
||||
<span class="sr">${_("Current Library:")}</span>
|
||||
<a class="course-link" href="${index_url}">
|
||||
<span class="course-org">${context_library.display_org_with_default | h}</span><span class="course-number">${context_library.display_number_with_default | h}</span>
|
||||
<span class="course-title" title="${context_library.display_name_with_default_escaped}">${context_library.display_name_with_default_escaped}</span>
|
||||
<span class="course-org">${context_library.display_org_with_default}</span><span class="course-number">${context_library.display_number_with_default}</span>
|
||||
<span class="course-title" title="${context_library.display_name_with_default}">${context_library.display_name_with_default}</span>
|
||||
</a>
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -249,11 +249,14 @@ class DashboardTest(ModuleStoreTestCase):
|
||||
Test that the certificate verification status for courses is visible on the dashboard.
|
||||
"""
|
||||
self.client.login(username="jack", password="test")
|
||||
self._check_verification_status_on('verified', 'You\'re enrolled as a verified student')
|
||||
self._check_verification_status_on('honor', 'You\'re enrolled as an honor code student')
|
||||
self._check_verification_status_on('verified', 'You're enrolled as a verified student')
|
||||
self._check_verification_status_on('honor', 'You're enrolled as an honor code student')
|
||||
self._check_verification_status_off('audit', '')
|
||||
self._check_verification_status_on('professional', 'You\'re enrolled as a professional education student')
|
||||
self._check_verification_status_on('no-id-professional', 'You\'re enrolled as a professional education student')
|
||||
self._check_verification_status_on('professional', 'You're enrolled as a professional education student')
|
||||
self._check_verification_status_on(
|
||||
'no-id-professional',
|
||||
'You're enrolled as a professional education student',
|
||||
)
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def _check_verification_status_off(self, mode, value):
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%inherit file="main.html" />
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%!
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.template import RequestContext
|
||||
import third_party_auth
|
||||
from third_party_auth import pipeline
|
||||
from django.core.urlresolvers import reverse
|
||||
import json
|
||||
from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string
|
||||
%>
|
||||
|
||||
<%
|
||||
@@ -39,9 +40,9 @@ import json
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
edx.dashboard.legacy.init({
|
||||
dashboard: "${reverse('dashboard')}",
|
||||
signInUser: "${reverse('signin_user')}",
|
||||
changeEmailSettings: "${reverse('change_email_settings')}"
|
||||
dashboard: "${reverse('dashboard') | n, js_escaped_string}",
|
||||
signInUser: "${reverse('signin_user') | n, js_escaped_string}",
|
||||
changeEmailSettings: "${reverse('change_email_settings') | n, js_escaped_string}"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -54,7 +55,7 @@ import json
|
||||
<%static:require_module module_name="js/views/message_banner" class_name="MessageBannerView">
|
||||
var banner = new MessageBannerView({urgency: 'low', type: 'warning'});
|
||||
$('#content').prepend(banner.$el);
|
||||
banner.showMessage(${json.dumps(redirect_message)})
|
||||
banner.showMessage(${redirect_message | n, dump_js_escaped_json})
|
||||
</%static:require_module>
|
||||
% endif
|
||||
</%block>
|
||||
@@ -117,7 +118,7 @@ import json
|
||||
<h2>${_("Course-loading errors")}</h2>
|
||||
|
||||
% for course_dir, errors in errored_courses.items():
|
||||
<h3>${course_dir | h}</h3>
|
||||
<h3>${course_dir}</h3>
|
||||
<ul>
|
||||
% for (msg, err) in errors:
|
||||
<li>${msg}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%page args="course_overview, enrollment, show_courseware_link, cert_status, can_unenroll, credit_status, show_email_settings, course_mode_info, show_refund_option, is_paid_course, is_course_blocked, verification_status, course_requirements, dashboard_index, share_settings, course_program_info" />
|
||||
<%page args="course_overview, enrollment, show_courseware_link, cert_status, can_unenroll, credit_status, show_email_settings, course_mode_info, show_refund_option, is_paid_course, is_course_blocked, verification_status, course_requirements, dashboard_index, share_settings, course_program_info" expression_filter="h"/>
|
||||
|
||||
<%!
|
||||
import urllib
|
||||
@@ -6,9 +6,9 @@ import urllib
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ungettext
|
||||
from django.core.urlresolvers import reverse
|
||||
from markupsafe import escape
|
||||
from course_modes.models import CourseMode
|
||||
from course_modes.helpers import enrollment_mode_display
|
||||
from openedx.core.djangolib.markup import Text, HTML
|
||||
from student.helpers import (
|
||||
VERIFY_STATUS_NEED_TO_VERIFY,
|
||||
VERIFY_STATUS_SUBMITTED,
|
||||
@@ -63,16 +63,16 @@ from student.helpers import (
|
||||
% if show_courseware_link:
|
||||
% if not is_course_blocked:
|
||||
<a href="${course_target}" data-course-key="${enrollment.course_id}" class="cover">
|
||||
<img src="${course_overview.image_urls['small']}" class="course-image" alt="${_('{course_number} {course_name} Home Page').format(course_number=course_overview.number, course_name=course_overview.display_name_with_default_escaped) |h}" />
|
||||
<img src="${course_overview.image_urls['small']}" class="course-image" alt="${_('{course_number} {course_name} Home Page').format(course_number=course_overview.number, course_name=course_overview.display_name_with_default)}" />
|
||||
</a>
|
||||
% else:
|
||||
<a class="fade-cover">
|
||||
<img src="${course_overview.image_urls['small']}" class="course-image" alt="${_('{course_number} {course_name} Cover Image').format(course_number=course_overview.number, course_name=course_overview.display_name_with_default_escaped) |h}" />
|
||||
<img src="${course_overview.image_urls['small']}" class="course-image" alt="${_('{course_number} {course_name} Cover Image').format(course_number=course_overview.number, course_name=course_overview.display_name_with_default)}" />
|
||||
</a>
|
||||
% endif
|
||||
% else:
|
||||
<a class="cover">
|
||||
<img src="${course_overview.image_urls['small']}" class="course-image" alt="${_('{course_number} {course_name} Cover Image').format(course_number=course_overview.number, course_name=course_overview.display_name_with_default_escaped) | h}" />
|
||||
<img src="${course_overview.image_urls['small']}" class="course-image" alt="${_('{course_number} {course_name} Cover Image').format(course_number=course_overview.number, course_name=course_overview.display_name_with_default)}" />
|
||||
</a>
|
||||
% endif
|
||||
% if settings.FEATURES.get('ENABLE_VERIFIED_CERTIFICATES') and course_verified_certs.get('display_mode') != 'audit':
|
||||
@@ -89,17 +89,17 @@ from student.helpers import (
|
||||
<h3 class="course-title">
|
||||
% if show_courseware_link:
|
||||
% if not is_course_blocked:
|
||||
<a data-course-key="${enrollment.course_id}" href="${course_target}">${course_overview.display_name_with_default_escaped}</a>
|
||||
<a data-course-key="${enrollment.course_id}" href="${course_target}">${course_overview.display_name_with_default}</a>
|
||||
% else:
|
||||
<a class="disable-look" data-course-key="${enrollment.course_id}">${course_overview.display_name_with_default_escaped}</a>
|
||||
<a class="disable-look" data-course-key="${enrollment.course_id}">${course_overview.display_name_with_default}</a>
|
||||
% endif
|
||||
% else:
|
||||
<span>${course_overview.display_name_with_default_escaped}</span>
|
||||
<span>${course_overview.display_name_with_default}</span>
|
||||
% endif
|
||||
</h3>
|
||||
<div class="course-info">
|
||||
<span class="info-university">${course_overview.display_org_with_default | h} - </span>
|
||||
<span class="info-course-id">${course_overview.display_number_with_default | h}</span>
|
||||
<span class="info-university">${course_overview.display_org_with_default} - </span>
|
||||
<span class="info-course-id">${course_overview.display_number_with_default}</span>
|
||||
<span class="info-date-block" data-tooltip="Hi">
|
||||
% if course_overview.has_ended():
|
||||
${_("Ended - {end_date}").format(end_date=course_overview.end_datetime_text("SHORT_DATE"))}
|
||||
@@ -119,15 +119,15 @@ from student.helpers import (
|
||||
% if show_courseware_link:
|
||||
% if course_overview.has_ended():
|
||||
% if not is_course_blocked:
|
||||
<a href="${course_target}" class="enter-course archived" data-course-key="${enrollment.course_id}">${_('View Archived Course')}<span class="sr"> ${course_overview.display_name_with_default_escaped}</span></a>
|
||||
<a href="${course_target}" class="enter-course archived" data-course-key="${enrollment.course_id}">${_('View Archived Course')}<span class="sr"> ${course_overview.display_name_with_default}</span></a>
|
||||
% else:
|
||||
<a class="enter-course-blocked archived" data-course-key="${enrollment.course_id}">${_('View Archived Course')}<span class="sr"> ${course_overview.display_name_with_default_escaped}</span></a>
|
||||
<a class="enter-course-blocked archived" data-course-key="${enrollment.course_id}">${_('View Archived Course')}<span class="sr"> ${course_overview.display_name_with_default}</span></a>
|
||||
% endif
|
||||
% else:
|
||||
% if not is_course_blocked:
|
||||
<a href="${course_target}" class="enter-course" data-course-key="${enrollment.course_id}">${_('View Course')}<span class="sr"> ${course_overview.display_name_with_default_escaped}</span></a>
|
||||
<a href="${course_target}" class="enter-course" data-course-key="${enrollment.course_id}">${_('View Course')}<span class="sr"> ${course_overview.display_name_with_default}</span></a>
|
||||
% else:
|
||||
<a class="enter-course-blocked" data-course-key="${enrollment.course_id}">${_('View Course')}<span class="sr"> ${course_overview.display_name_with_default_escaped}</span></a>
|
||||
<a class="enter-course-blocked" data-course-key="${enrollment.course_id}">${_('View Course')}<span class="sr"> ${course_overview.display_name_with_default}</span></a>
|
||||
% endif
|
||||
% endif
|
||||
|
||||
@@ -178,10 +178,10 @@ from student.helpers import (
|
||||
% endif
|
||||
% endif
|
||||
<div class="wrapper-action-more" data-course-key="${enrollment.course_id}">
|
||||
<button type="button" class="action action-more" id="actions-dropdown-link-${dashboard_index}" aria-haspopup="true" aria-expanded="false" aria-controls="actions-dropdown-${dashboard_index}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}">
|
||||
<button type="button" class="action action-more" id="actions-dropdown-link-${dashboard_index}" aria-haspopup="true" aria-expanded="false" aria-controls="actions-dropdown-${dashboard_index}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}">
|
||||
<span class="sr">${_('Course options for')}</span>
|
||||
<span class="sr">
|
||||
${course_overview.display_name_with_default_escaped}
|
||||
${course_overview.display_name_with_default}
|
||||
</span>
|
||||
<i class="fa fa-cog" aria-hidden="true"></i>
|
||||
</button>
|
||||
@@ -191,69 +191,69 @@ from student.helpers import (
|
||||
<li class="actions-item" id="actions-item-unenroll-${dashboard_index}">
|
||||
% if is_paid_course and show_refund_option:
|
||||
% if not is_course_blocked:
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.") | h}">
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% else:
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.") | h}">
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% endif
|
||||
% elif is_paid_course and not show_refund_option:
|
||||
% if not is_course_blocked:
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("You will not be refunded the amount you paid.") | h}">
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("You will not be refunded the amount you paid.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% else:
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("You will not be refunded the amount you paid.") | h}">
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("You will not be refunded the amount you paid.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% endif
|
||||
% elif enrollment.mode != "verified":
|
||||
% if not is_course_blocked:
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from %(course_name)s (%(course_number)s)?") | h}">
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from %(course_name)s (%(course_number)s)?")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% else:
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from %(course_name)s (%(course_number)s)?") | h}">
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from %(course_name)s (%(course_number)s)?")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% endif
|
||||
% elif show_refund_option:
|
||||
% if not is_course_blocked:
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long | h}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.") | h}">
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% else:
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long | h}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.") | h}">
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("You will be refunded the amount you paid.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% endif
|
||||
% else:
|
||||
% if not is_course_blocked:
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long | h}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("The refund deadline for this course has passed, so you will not receive a refund.") | h}">
|
||||
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("The refund deadline for this course has passed, so you will not receive a refund.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% else:
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-course-name="${course_overview.display_name_with_default_escaped | h}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long | h}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?") | h}"
|
||||
data-refund-info="${_("The refund deadline for this course has passed, so you will not receive a refund.") | h}">
|
||||
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
|
||||
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
|
||||
data-refund-info="${_("The refund deadline for this course has passed, so you will not receive a refund.")}">
|
||||
${_('Unenroll')}
|
||||
</a>
|
||||
% endif
|
||||
@@ -263,9 +263,9 @@ from student.helpers import (
|
||||
<li class="actions-item" id="actions-item-email-settings-${dashboard_index}">
|
||||
% if show_email_settings:
|
||||
% if not is_course_blocked:
|
||||
<a href="#email-settings-modal" class="action action-email-settings" rel="leanModal" data-course-id="${course_overview.id | h}" data-course-number="${course_overview.number | h}" data-dashboard-index="${dashboard_index}" data-optout="${unicode(course_overview.id) in course_optouts}">${_('Email Settings')}</a>
|
||||
<a href="#email-settings-modal" class="action action-email-settings" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-dashboard-index="${dashboard_index}" data-optout="${unicode(course_overview.id) in course_optouts}">${_('Email Settings')}</a>
|
||||
% else:
|
||||
<a class="action action-email-settings is-disabled" data-course-id="${course_overview.id| h}" data-course-number="${course_overview.number | h}" data-dashboard-index="${dashboard_index}" data-optout="${unicode(course_overview.id) in course_optouts}">${_('Email Settings')}</a>
|
||||
<a class="action action-email-settings is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-dashboard-index="${dashboard_index}" data-optout="${unicode(course_overview.id) in course_optouts}">${_('Email Settings')}</a>
|
||||
% endif
|
||||
% endif
|
||||
</li>
|
||||
@@ -303,7 +303,7 @@ from student.helpers import (
|
||||
% endif
|
||||
</div>
|
||||
<div class="verification-cta">
|
||||
<a href="${reverse('verify_student_verify_now', kwargs={'course_id': unicode(course_overview.id)})}" class="cta" data-course-id="${course_overview.id | h}">${_('Verify Now')}</a>
|
||||
<a href="${reverse('verify_student_verify_now', kwargs={'course_id': unicode(course_overview.id)})}" class="cta" data-course-id="${course_overview.id}">${_('Verify Now')}</a>
|
||||
</div>
|
||||
% elif verification_status['status'] == VERIFY_STATUS_SUBMITTED:
|
||||
<h4 class="message-title">${_('You have already verified your ID!')}</h4>
|
||||
@@ -317,7 +317,7 @@ from student.helpers import (
|
||||
<h4 class="message-title">${_('Your verification will expire soon!')}</h4>
|
||||
## Translators: start_link and end_link will be replaced with HTML tags;
|
||||
## please do not translate these.
|
||||
<p class="message-copy">${_('Your current verification will expire before the verification deadline for this course. {start_link}Re-verify your identity now{end_link} using a webcam and a government-issued ID.').format(start_link='<a href="{href}">'.format(href=reverse('verify_student_reverify')), end_link='</a>')}</p>
|
||||
<p class="message-copy">${Text(_('Your current verification will expire before the verification deadline for this course. {start_link}Re-verify your identity now{end_link} using a webcam and a government-issued ID.')).format(start_link=HTML('<a href="{href}">'.format(href=reverse('verify_student_reverify'))), end_link=HTML('</a>'))}</p>
|
||||
% endif
|
||||
</div>
|
||||
% endif
|
||||
@@ -330,13 +330,23 @@ from student.helpers import (
|
||||
<b class="message-copy-bold">
|
||||
${_("Pursue a {cert_name_long} to highlight the knowledge and skills you gain in this course.").format(cert_name_long=cert_name_long)}
|
||||
</b><br>
|
||||
${_("It's official. It's easily shareable. It's a proven motivator to complete the course. <br>{link_start}Learn more about the verified {cert_name_long}{link_end}.").format(link_start='<a href="{}" class="verified-info" data-course-key="{}">'.format(marketing_link('WHAT_IS_VERIFIED_CERT'), enrollment.course_id), link_end="</a>", cert_name_long=cert_name_long)}
|
||||
${Text(_("It's official. It's easily shareable. "
|
||||
"It's a proven motivator to complete the course. {line_break}"
|
||||
"{link_start}Learn more about the verified {cert_name_long}{link_end}.")).format(
|
||||
line_break=HTML('<br>'),
|
||||
link_start=HTML('<a href="{}" class="verified-info" data-course-key="{}">'.format(
|
||||
marketing_link('WHAT_IS_VERIFIED_CERT'),
|
||||
enrollment.course_id
|
||||
)),
|
||||
link_end=HTML('</a>'),
|
||||
cert_name_long=cert_name_long
|
||||
)}
|
||||
</p>
|
||||
<div class="action-upgrade-container">
|
||||
% if use_ecommerce_payment_flow and course_mode_info['verified_sku']:
|
||||
<a class="action action-upgrade" href="${ecommerce_payment_page}?sku=${course_mode_info['verified_sku']}">
|
||||
% else:
|
||||
<a class="action action-upgrade" href="${reverse('verify_student_upgrade_and_verify', kwargs={'course_id': unicode(course_overview.id)})}" data-course-id="${course_overview.id | h}" data-user="${user.username | h}">
|
||||
<a class="action action-upgrade" href="${reverse('verify_student_upgrade_and_verify', kwargs={'course_id': unicode(course_overview.id)})}" data-course-id="${course_overview.id}" data-user="${user.username}">
|
||||
% endif
|
||||
<i class="action-upgrade-icon"></i>
|
||||
<span class="wrapper-copy">
|
||||
@@ -356,23 +366,23 @@ from student.helpers import (
|
||||
|
||||
% if is_course_blocked:
|
||||
<p id="block-course-msg" class="course-block">
|
||||
${_("You can no longer access this course because payment has not yet been received. "
|
||||
${Text(_("You can no longer access this course because payment has not yet been received. "
|
||||
"You can {contact_link_start}contact the account holder{contact_link_end} "
|
||||
"to request payment, or you can "
|
||||
"{unenroll_link_start}unenroll{unenroll_link_end} "
|
||||
"from this course").format(
|
||||
contact_link_start='<a href="#">',
|
||||
contact_link_end='</a>',
|
||||
unenroll_link_start=(
|
||||
"from this course")).format(
|
||||
contact_link_start=HTML('<a href="#">'),
|
||||
contact_link_end=HTML('</a>'),
|
||||
unenroll_link_start=HTML(
|
||||
'<a id="unregister_block_course" rel="leanModal" '
|
||||
'data-course-id="{course_id}" data-course-number="{course_number}" data-course-name="{course_name}" '
|
||||
'href="#unenroll-modal">'.format(
|
||||
course_id=escape(course_overview.id),
|
||||
course_number=escape(course_overview.number),
|
||||
course_name=escape(course_overview.display_name_with_default_escaped),
|
||||
)
|
||||
'href="#unenroll-modal">'
|
||||
).format(
|
||||
course_id=course_overview.id,
|
||||
course_number=course_overview.number,
|
||||
course_name=course_overview.display_name_with_default,
|
||||
),
|
||||
unenroll_link_end="</a>",
|
||||
unenroll_link_end=HTML('</a>'),
|
||||
)}
|
||||
</p>
|
||||
%endif
|
||||
@@ -383,9 +393,9 @@ from student.helpers import (
|
||||
<% prc_target = reverse('about_course', args=[unicode(course_requirements['courses'][0]['key'])]) %>
|
||||
<li class="prerequisites">
|
||||
<p class="tip">
|
||||
${_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.").format(
|
||||
link_start='<a href="{}">'.format(prc_target),
|
||||
link_end='</a>',
|
||||
${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=course_requirements['courses'][0]['display'],
|
||||
)}
|
||||
</p>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
## mako
|
||||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
## mako
|
||||
<%page expression_filter="h"/>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%include file="${static.get_themed_template_path(relative_path='theme-header.html', default_path='navigation.html')}" />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%!
|
||||
@@ -6,6 +7,8 @@ import pytz
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from openedx.core.djangolib.js_utils import js_escaped_string
|
||||
from openedx.core.djangolib.markup import Text, HTML
|
||||
from xmodule.tabs import CourseTabList
|
||||
%>
|
||||
|
||||
@@ -28,8 +31,8 @@ from xmodule.tabs import CourseTabList
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
${_('{platform_name} Help').format(
|
||||
platform_name=u'<span class="edx">{}</span>'.format(static.get_platform_name())
|
||||
${Text(_('{platform_name} Help')).format(
|
||||
platform_name=HTML(u'<span class="edx">{}</span>').format(static.get_platform_name())
|
||||
)}
|
||||
</h2>
|
||||
<hr>
|
||||
@@ -41,22 +44,30 @@ from xmodule.tabs import CourseTabList
|
||||
%>
|
||||
|
||||
% if discussion_link:
|
||||
<p>${_('For <strong>questions on course lectures, homework, tools, or materials for this course</strong>, post in the {link_start}course discussion forum{link_end}.').format(
|
||||
link_start='<a href="{url}" target="_blank">'.format(url=discussion_link),
|
||||
link_end='</a>',
|
||||
<p>${Text(_('For {strong_start}questions on course lectures, homework, tools, or materials for this course{strong_end}, post in the {link_start}course discussion forum{link_end}.')).format(
|
||||
strong_start=HTML('<strong>'),
|
||||
strong_end=HTML('</strong>'),
|
||||
link_start=HTML('<a href="{url}" target="_blank">').format(
|
||||
url=discussion_link
|
||||
),
|
||||
link_end=HTML('</a>'),
|
||||
)}
|
||||
</p>
|
||||
% endif
|
||||
|
||||
<p>${_('Have <strong>general questions about {platform_name}</strong>? You can find lots of helpful information in the {platform_name} {link_start}FAQ{link_end}.').format(
|
||||
link_start='<a href="{url}" target="_blank">'.format(
|
||||
<p>${Text(_('Have {strong_start}general questions about {platform_name}{strong_end}? You can find lots of helpful information in the {platform_name} {link_start}FAQ{link_end}.')).format(
|
||||
strong_start=HTML('<strong>'),
|
||||
strong_end=HTML('</strong>'),
|
||||
link_start=HTML('<a href="{url}" target="_blank">').format(
|
||||
url=marketing_link('FAQ')
|
||||
),
|
||||
link_end='</a>',
|
||||
link_end=HTML('</a>'),
|
||||
platform_name=static.get_platform_name())}
|
||||
</p>
|
||||
|
||||
<p>${_('Have a <strong>question about something specific</strong>? You can contact the {platform_name} general support team directly:').format(
|
||||
<p>${Text(_('Have a {strong_start}question about something specific{strong_end}? You can contact the {platform_name} general support team directly:')).format(
|
||||
strong_start=HTML('<strong>'),
|
||||
strong_end=HTML('</strong>'),
|
||||
platform_name=static.get_platform_name()
|
||||
)}</p>
|
||||
<hr>
|
||||
@@ -99,7 +110,7 @@ from xmodule.tabs import CourseTabList
|
||||
<textarea name="details" id="feedback_form_details" aria-required="true"></textarea>
|
||||
<input name="issue_type" type="hidden">
|
||||
% if course:
|
||||
<input name="course_id" type="hidden" value="${course.id.to_deprecated_string() | h}">
|
||||
<input name="course_id" type="hidden" value="${unicode(course.id)}">
|
||||
% endif
|
||||
<div class="submit">
|
||||
<input name="submit" type="submit" value="${_('Submit')}" id="feedback_submit">
|
||||
@@ -131,16 +142,16 @@ from xmodule.tabs import CourseTabList
|
||||
close_time = "22:00"
|
||||
%>
|
||||
<p>
|
||||
${_(
|
||||
${Text(_(
|
||||
'Thank you for your inquiry or feedback. We typically respond to a request '
|
||||
'within one business day (Monday to Friday, {open_time} UTC to {close_time} UTC.) In the meantime, please '
|
||||
'review our {link_start}detailed FAQs{link_end} where most questions have '
|
||||
'already been answered.'
|
||||
).format(
|
||||
)).format(
|
||||
open_time=open_time,
|
||||
close_time=close_time,
|
||||
link_start='<a href="{}" target="_blank" id="feedback-faq-link" tabindex="0">'.format(marketing_link('FAQ')),
|
||||
link_end='</a>'
|
||||
link_start=HTML('<a href="{}" target="_blank" id="feedback-faq-link" tabindex="0">').format(marketing_link('FAQ')),
|
||||
link_end=HTML('</a>')
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -201,29 +212,32 @@ from xmodule.tabs import CourseTabList
|
||||
$("#feedback_link_problem").click(function(event) {
|
||||
showFeedback(
|
||||
event,
|
||||
"${_('problem')}",
|
||||
"${_('Report a Problem')}",
|
||||
"${_('Brief description of the problem')}" + "*",
|
||||
"${_('Details of the problem you are encountering')}" + "*" + "<span class='tip'>" +
|
||||
"${_('Include error messages, steps which lead to the issue, etc.')}" + "</span>"
|
||||
"${_('problem') | n, js_escaped_string}",
|
||||
"${_('Report a Problem') | n, js_escaped_string}",
|
||||
"${_('Brief description of the problem') + '*' | n, js_escaped_string}" ,
|
||||
"${Text(_('Details of the problem you are encountering{asterisk}{begin_span}Include error messages, steps which lead to the issue, etc.{end_span}')).format(
|
||||
asterisk='*',
|
||||
begin_span=HTML('<span class=tip>'),
|
||||
end_span=HTML('</span>'),
|
||||
) | n, js_escaped_string}"
|
||||
);
|
||||
});
|
||||
$("#feedback_link_suggestion").click(function(event) {
|
||||
showFeedback(
|
||||
event,
|
||||
"${_('suggestion')}",
|
||||
"${_('Make a Suggestion')}",
|
||||
"${_('Brief description of your suggestion')}" + "*",
|
||||
"${_('Details')}" + "*"
|
||||
"${_('suggestion') | n, js_escaped_string}",
|
||||
"${_('Make a Suggestion') | n, js_escaped_string}",
|
||||
"${_('Brief description of your suggestion') + '*' | n, js_escaped_string}",
|
||||
"${_('Details') + '*' | n, js_escaped_string}"
|
||||
);
|
||||
});
|
||||
$("#feedback_link_question").click(function(event) {
|
||||
showFeedback(
|
||||
event,
|
||||
"${_('question')}",
|
||||
"${_('Ask a Question')}",
|
||||
"${_('Brief summary of your question')}" + "*",
|
||||
"${_('Details')}" + "*"
|
||||
"${_('question') | n, js_escaped_string}",
|
||||
"${_('Ask a Question') | n, js_escaped_string}",
|
||||
"${_('Brief summary of your question') + '*' | n, js_escaped_string}",
|
||||
"${_('Details') + '*' | n, js_escaped_string}"
|
||||
);
|
||||
});
|
||||
$("#feedback_form").submit(function() {
|
||||
@@ -251,21 +265,21 @@ from xmodule.tabs import CourseTabList
|
||||
$("#feedback_error").html(responseData.error).stop().css("display", "block");
|
||||
} else {
|
||||
// If no data (or malformed data) is returned, a server error occurred
|
||||
htmlStr = "${_('An error has occurred.')}";
|
||||
htmlStr = "${_('An error has occurred.') | n, js_escaped_string}";
|
||||
% if settings.FEEDBACK_SUBMISSION_EMAIL:
|
||||
htmlStr += " " + _.template(
|
||||
"${_('Please {link_start}send us e-mail{link_end}.')}", {interpolate: /\{(.+?)\}/g})(
|
||||
{link_start: '<a href="#" id="feedback_email">', link_end: '</a>'}
|
||||
);
|
||||
htmlStr += " " + "${Text(_('Please {link_start}send us e-mail{link_end}.')).format(
|
||||
link_start=HTML('<a href="#" id="feedback_email">'),
|
||||
link_end=HTML('</a>'),
|
||||
) | n, js_escaped_string}";
|
||||
% else:
|
||||
// If no email is configured, we can't do much other than
|
||||
// ask the user to try again later
|
||||
htmlStr += " " + "${_('Please try again later.')}";
|
||||
htmlStr += " " + "${_('Please try again later.') | n, js_escaped_string}";
|
||||
% endif
|
||||
$("#feedback_error").html(htmlStr).stop().css("display", "block");
|
||||
% if settings.FEEDBACK_SUBMISSION_EMAIL:
|
||||
$("#feedback_email").click(function(e) {
|
||||
mailto = "mailto:" + "${settings.FEEDBACK_SUBMISSION_EMAIL}" +
|
||||
mailto = "mailto:" + "${settings.FEEDBACK_SUBMISSION_EMAIL | n, js_escaped_string}" +
|
||||
"?subject=" + $("#feedback_form input[name='subject']").val() +
|
||||
"&body=" + $("#feedback_form textarea[name='details']").val();
|
||||
window.open(mailto);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
## mako
|
||||
<%page expression_filter="h"/>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%namespace file='main.html' import="login_query"/>
|
||||
<%!
|
||||
@@ -48,9 +49,9 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
|
||||
% if course and not disable_courseware_header:
|
||||
<h2 class="course-header">
|
||||
<span class="provider">${course.display_org_with_default | h}:</span>
|
||||
<span class="course-number">${course.display_number_with_default | h}</span>
|
||||
<span class="course-name">${course.display_name_with_default_escaped}</span>
|
||||
<span class="provider">${course.display_org_with_default}:</span>
|
||||
<span class="course-number">${course.display_number_with_default}</span>
|
||||
<span class="course-name">${course.display_name_with_default}</span>
|
||||
</h2>
|
||||
% endif
|
||||
|
||||
@@ -140,7 +141,15 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
</header>
|
||||
% if course:
|
||||
<!--[if lte IE 9]>
|
||||
<div class="ie-banner" aria-hidden="true">${_('<strong>Warning:</strong> Your browser is not fully supported. We strongly recommend using {chrome_link} or {ff_link}.').format(chrome_link='<a href="https://www.google.com/chrome" target="_blank">Chrome</a>', ff_link='<a href="http://www.mozilla.org/firefox" target="_blank">Firefox</a>')}</div>
|
||||
<div class="ie-banner" aria-hidden="true">
|
||||
${Text(_('{begin_strong}Warning:{end_strong} Your browser is not fully supported. We strongly recommend using {chrome_link} or {ff_link}.')).format(
|
||||
begin_strong=HTML('<strong>'),
|
||||
end_strong=HTML('</strong>'),
|
||||
chrome_link=HTML('<a href="https://www.google.com/chrome" target="_blank">Chrome</a>'),
|
||||
ff_link=HTML('<a href="http://www.mozilla.org/firefox" target="_blank">Firefox</a>'),
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<![endif]-->
|
||||
% endif
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
## mako
|
||||
<%page expression_filter="h"/>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%namespace file='main.html' import="login_query"/>
|
||||
<%!
|
||||
@@ -8,6 +9,7 @@ from django.utils.translation import ugettext as _
|
||||
from lms.djangoapps.ccx.overrides import get_current_ccx
|
||||
from microsite_configuration import microsite
|
||||
from microsite_configuration.templatetags.microsite import platform_name
|
||||
from openedx.core.djangolib.markup import Text, HTML
|
||||
from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_urls_for_user
|
||||
|
||||
# App that handles subdomain specific branding
|
||||
@@ -48,10 +50,10 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
</h1>
|
||||
|
||||
% if course:
|
||||
<h2 class="course-header"><span class="provider">${course.display_org_with_default | h}:</span>
|
||||
<span class="course-number">${course.display_number_with_default | h}</span>
|
||||
<h2 class="course-header"><span class="provider">${course.display_org_with_default}:</span>
|
||||
<span class="course-number">${course.display_number_with_default}</span>
|
||||
<%
|
||||
display_name = course.display_name_with_default_escaped
|
||||
display_name = course.display_name_with_default
|
||||
if settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
|
||||
ccx = get_current_ccx(course.id)
|
||||
if ccx:
|
||||
@@ -194,7 +196,15 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
</header>
|
||||
% if course:
|
||||
<!--[if lte IE 9]>
|
||||
<div class="ie-banner" aria-hidden="true">${_('<strong>Warning:</strong> Your browser is not fully supported. We strongly recommend using {chrome_link} or {ff_link}.').format(chrome_link='<a href="https://www.google.com/chrome" target="_blank">Chrome</a>', ff_link='<a href="http://www.mozilla.org/firefox" target="_blank">Firefox</a>')}</div>
|
||||
<div class="ie-banner" aria-hidden="true">
|
||||
${Text(_('{begin_strong}Warning:{end_strong} Your browser is not fully supported. We strongly recommend using {chrome_link} or {ff_link}.')).format(
|
||||
begin_strong=HTML('<strong>'),
|
||||
end_strong=HTML('</strong>'),
|
||||
chrome_link=HTML('<a href="https://www.google.com/chrome" target="_blank">Chrome</a>'),
|
||||
ff_link=HTML('<a href="http://www.mozilla.org/firefox" target="_blank">Firefox</a>'),
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<![endif]-->
|
||||
% endif
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<%page expression_filter="h"/>
|
||||
|
||||
% if show_bookmark_button:
|
||||
<%include file='bookmark_button.html' args="bookmark_id=bookmark_id, is_bookmarked=bookmarked"/>
|
||||
@@ -6,7 +7,7 @@
|
||||
<div class="vert-mod">
|
||||
% for idx, item in enumerate(items):
|
||||
<div class="vert vert-${idx}" data-id="${item['id']}">
|
||||
${item['content']}
|
||||
${item['content'] | n, unicode}
|
||||
</div>
|
||||
% endfor
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%inherit file="main.html" />
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%!
|
||||
@@ -8,6 +9,7 @@ from third_party_auth import pipeline
|
||||
from microsite_configuration import microsite
|
||||
from django.core.urlresolvers import reverse
|
||||
import json
|
||||
from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string
|
||||
%>
|
||||
|
||||
<%
|
||||
@@ -40,9 +42,9 @@ import json
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
edx.dashboard.legacy.init({
|
||||
dashboard: "${reverse('dashboard')}",
|
||||
signInUser: "${reverse('signin_user')}",
|
||||
changeEmailSettings: "${reverse('change_email_settings')}"
|
||||
dashboard: "${reverse('dashboard') | n, js_escaped_string}",
|
||||
signInUser: "${reverse('signin_user') | n, js_escaped_string}",
|
||||
changeEmailSettings: "${reverse('change_email_settings') | n, js_escaped_string}"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -55,7 +57,7 @@ import json
|
||||
<%static:require_module module_name="js/views/message_banner" class_name="MessageBannerView">
|
||||
var banner = new MessageBannerView({urgency: 'low', type: 'warning'});
|
||||
$('#content').prepend(banner.$el);
|
||||
banner.showMessage(${json.dumps(redirect_message)})
|
||||
banner.showMessage(${redirect_message | n, dump_js_escaped_json})
|
||||
</%static:require_module>
|
||||
% endif
|
||||
</%block>
|
||||
@@ -118,7 +120,7 @@ import json
|
||||
<h2>${_("Course-loading errors")}</h2>
|
||||
|
||||
% for course_dir, errors in errored_courses.items():
|
||||
<h3>${course_dir | h}</h3>
|
||||
<h3>${course_dir}</h3>
|
||||
<ul>
|
||||
% for (msg, err) in errors:
|
||||
<li>${msg}
|
||||
|
||||
Reference in New Issue
Block a user