${_("Specify a course title to use on the certificate if the course's official title is too long to be displayed well.")}
${_("For verified certificates, specify between one and four signatories and upload the associated images.")}
-
${_("To edit or delete a certificate before it is activated, hover over the top right corner of the form and select {em_start}Edit{em_end} or the delete icon.").format(em_start="", em_end="")}
-
${_("To view a sample certificate, choose a course mode and select {em_start}Preview Certificate{em_end}.").format(em_start='', em_end="")}
+
${Text(_("To edit or delete a certificate before it is activated, hover over the top right corner of the form and select {em_start}Edit{em_end} or the delete icon.")).format(em_start=HTML(""), em_end=HTML(""))}
+
${Text(_("To view a sample certificate, choose a course mode and select {em_start}Preview Certificate{em_end}.")).format(em_start=HTML(''), em_end=HTML(""))}
${_("Issuing Certificates to Learners")}
-
${_("To begin issuing course certificates, a course team member with either the Staff or Admin role selects {em_start}Activate{em_end}. Only course team members with these roles can edit or delete an activated certificate.").format(em_start="", em_end="")}
-
${_("{em_start}Do not{em_end} delete certificates after a course has started; learners who have already earned certificates will no longer be able to access them.").format(em_start="", em_end="")}
${Text(_("To begin issuing course certificates, a course team member with either the Staff or Admin role selects {em_start}Activate{em_end}. Only course team members with these roles can edit or delete an activated certificate.")).format(em_start=HTML(""), em_end=HTML(""))}
+
${Text(_("{em_start}Do not{em_end} delete certificates after a course has started; learners who have already earned certificates will no longer be able to access them.")).format(em_start=HTML(""), em_end=HTML(""))}
- <%= gettext("The following message will be displayed at the bottom of the courseware pages within your course:") %>
+ <%- gettext("The following message will be displayed at the bottom of the courseware pages within your course:") %>
diff --git a/cms/templates/js/metadata-file-uploader-item.underscore b/cms/templates/js/metadata-file-uploader-item.underscore
index 45e08c1b7b..7c7637c073 100644
--- a/cms/templates/js/metadata-file-uploader-item.underscore
+++ b/cms/templates/js/metadata-file-uploader-item.underscore
@@ -1,3 +1,3 @@
-<%= model.get('value') ? gettext('Replace') : gettext('Upload') %>
-<% if (model.get('value')) { %>" target="_blank" class="download-action download-setting"><%= gettext("Download") %>
+<%- model.get('value') ? gettext('Replace') : gettext('Upload') %>
+<% if (model.get('value')) { %>" rel="noopener" target="_blank" class="download-action download-setting"><%- gettext("Download") %>
<% } %>
diff --git a/cms/templates/textbooks.html b/cms/templates/textbooks.html
index 2a5c955224..7cd12cbc7e 100644
--- a/cms/templates/textbooks.html
+++ b/cms/templates/textbooks.html
@@ -1,9 +1,10 @@
+<%page expression_filter="h"/>
<%inherit file="base.html" />
<%def name="online_help_token()"><% return "textbooks" %>%def>
<%namespace name='static' file='static_content.html'/>
<%!
from django.utils.translation import ugettext as _
-from openedx.core.djangolib.js_utils import dump_js_escaped_json
+from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string
%>
<%block name="title">${_("Textbooks")}%block>
@@ -21,9 +22,9 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json
%block>
diff --git a/common/lib/xmodule/xmodule/lti_module.py b/common/lib/xmodule/xmodule/lti_module.py
index 248adfb58b..b439f335ae 100644
--- a/common/lib/xmodule/xmodule/lti_module.py
+++ b/common/lib/xmodule/xmodule/lti_module.py
@@ -80,6 +80,7 @@ from xmodule.editing_module import MetadataOnlyEditingDescriptor
from xmodule.lti_2_util import LTI20ModuleMixin, LTIError
from xmodule.raw_module import EmptyDataRawDescriptor
from xmodule.x_module import XModule, module_attr
+from openedx.core.djangolib.markup import HTML, Text
log = logging.getLogger(__name__)
@@ -87,6 +88,7 @@ DOCS_ANCHOR_TAG_OPEN = (
""
)
+BREAK_TAG = ' '
# Make '_' a no-op so we can scrape strings. Using lambda instead of
# `django.utils.translation.ugettext_noop` because Django cannot be imported in this file
@@ -124,39 +126,42 @@ class LTIFields(object):
)
lti_id = String(
display_name=_("LTI ID"),
- help=_(
+ help=Text(_(
"Enter the LTI ID for the external LTI provider. "
"This value must be the same LTI ID that you entered in the "
"LTI Passports setting on the Advanced Settings page."
- " See {docs_anchor_open}the edX LTI documentation{anchor_close} for more details on this setting."
- ).format(
- docs_anchor_open=DOCS_ANCHOR_TAG_OPEN,
- anchor_close=""
+ "{break_tag}See {docs_anchor_open}the edX LTI documentation{anchor_close} for more details on this setting."
+ )).format(
+ break_tag=HTML(BREAK_TAG),
+ docs_anchor_open=HTML(DOCS_ANCHOR_TAG_OPEN),
+ anchor_close=HTML("")
),
default='',
scope=Scope.settings
)
launch_url = String(
display_name=_("LTI URL"),
- help=_(
+ help=Text(_(
"Enter the URL of the external tool that this component launches. "
"This setting is only used when Hide External Tool is set to False."
- " See {docs_anchor_open}the edX LTI documentation{anchor_close} for more details on this setting."
- ).format(
- docs_anchor_open=DOCS_ANCHOR_TAG_OPEN,
- anchor_close=""
+ "{break_tag}See {docs_anchor_open}the edX LTI documentation{anchor_close} for more details on this setting."
+ )).format(
+ break_tag=HTML(BREAK_TAG),
+ docs_anchor_open=HTML(DOCS_ANCHOR_TAG_OPEN),
+ anchor_close=HTML("")
),
default='http://www.example.com',
scope=Scope.settings)
custom_parameters = List(
display_name=_("Custom Parameters"),
- help=_(
+ help=Text(_(
"Add the key/value pair for any custom parameters, such as the page your e-book should open to or "
"the background color for this component."
- " See {docs_anchor_open}the edX LTI documentation{anchor_close} for more details on this setting."
- ).format(
- docs_anchor_open=DOCS_ANCHOR_TAG_OPEN,
- anchor_close=""
+ "{break_tag}See {docs_anchor_open}the edX LTI documentation{anchor_close} for more details on this setting."
+ )).format(
+ break_tag=HTML(BREAK_TAG),
+ docs_anchor_open=HTML(DOCS_ANCHOR_TAG_OPEN),
+ anchor_close=HTML("")
),
scope=Scope.settings)
open_in_a_new_page = Boolean(
diff --git a/lms/static/js/student_account/views/RegisterView.js b/lms/static/js/student_account/views/RegisterView.js
index 9daa4720c7..70191b66e2 100644
--- a/lms/static/js/student_account/views/RegisterView.js
+++ b/lms/static/js/student_account/views/RegisterView.js
@@ -133,23 +133,24 @@
render: function(html) {
var fields = html || '',
- formErrorsTitle = gettext('An error occurred.');
+ formErrorsTitle = gettext('An error occurred.'),
+ renderHtml = _.template(this.tpl)({
+ /* We pass the context object to the template so that
+ * we can perform variable interpolation using sprintf
+ */
+ context: {
+ fields: fields,
+ currentProvider: this.currentProvider,
+ syncLearnerProfileData: this.syncLearnerProfileData,
+ providers: this.providers,
+ hasSecondaryProviders: this.hasSecondaryProviders,
+ platformName: this.platformName,
+ autoRegisterWelcomeMessage: this.autoRegisterWelcomeMessage,
+ registerFormSubmitButtonText: this.registerFormSubmitButtonText
+ }
+ });
- $(this.el).html(_.template(this.tpl)({
- /* We pass the context object to the template so that
- * we can perform variable interpolation using sprintf
- */
- context: {
- fields: fields,
- currentProvider: this.currentProvider,
- syncLearnerProfileData: this.syncLearnerProfileData,
- providers: this.providers,
- hasSecondaryProviders: this.hasSecondaryProviders,
- platformName: this.platformName,
- autoRegisterWelcomeMessage: this.autoRegisterWelcomeMessage,
- registerFormSubmitButtonText: this.registerFormSubmitButtonText
- }
- }));
+ HtmlUtils.setHtml($(this.el), HtmlUtils.HTML(renderHtml));
this.postRender();
diff --git a/lms/templates/api_admin/catalogs/edit.html b/lms/templates/api_admin/catalogs/edit.html
index a12dca712b..713fd6b805 100644
--- a/lms/templates/api_admin/catalogs/edit.html
+++ b/lms/templates/api_admin/catalogs/edit.html
@@ -4,6 +4,7 @@
<%!
from django.urls import reverse
from django.utils.translation import ugettext as _
+from openedx.core.djangolib.js_utils import js_escaped_string
%>
<%namespace name='static' file='/static_content.html'/>
@@ -13,8 +14,8 @@ from django.utils.translation import ugettext as _
<%block name="js_extra">
<%static:require_module module_name="js/api_admin/catalog_preview_factory" class_name="CatalogPreviewFactory">
CatalogPreviewFactory({
- previewUrl: "${preview_url}",
- catalogApiUrl: "${catalog_api_url}",
+ previewUrl: "${preview_url | n, js_escaped_string}",
+ catalogApiUrl: "${catalog_api_url | n, js_escaped_string}",
});
%static:require_module>
%block>
@@ -37,7 +38,7 @@ from django.utils.translation import ugettext as _
- ${form.as_p() | n}
+ ${form.as_p() | n, decode.utf8}
diff --git a/lms/templates/api_admin/catalogs/list.html b/lms/templates/api_admin/catalogs/list.html
index 843b710294..ae7e9df906 100644
--- a/lms/templates/api_admin/catalogs/list.html
+++ b/lms/templates/api_admin/catalogs/list.html
@@ -4,6 +4,7 @@
<%!
from django.urls import reverse
from django.utils.translation import ugettext as _
+from openedx.core.djangolib.js_utils import js_escaped_string
%>
<%namespace name='static' file='/static_content.html'/>
@@ -13,8 +14,8 @@ from django.utils.translation import ugettext as _
<%block name="js_extra">
<%static:require_module module_name="js/api_admin/catalog_preview_factory" class_name="CatalogPreviewFactory">
CatalogPreviewFactory({
- previewUrl: "${preview_url}",
- catalogApiUrl: "${catalog_api_url}",
+ previewUrl: "${preview_url | n, js_escaped_string}",
+ catalogApiUrl: "${catalog_api_url | n, js_escaped_string}",
});
%static:require_module>
%block>
@@ -38,7 +39,7 @@ CatalogPreviewFactory({
diff --git a/lms/templates/certificates/_badges-modal.html b/lms/templates/certificates/_badges-modal.html
index ae50e1c632..70a24e785f 100644
--- a/lms/templates/certificates/_badges-modal.html
+++ b/lms/templates/certificates/_badges-modal.html
@@ -1,3 +1,4 @@
+<%page expression_filter="h"/>
<%namespace name='static' file='../static_content.html'/>
diff --git a/openedx/core/lib/license/templates/license.html b/openedx/core/lib/license/templates/license.html
index 52bcfcbfb1..fe1141e9b9 100644
--- a/openedx/core/lib/license/templates/license.html
+++ b/openedx/core/lib/license/templates/license.html
@@ -1,4 +1,4 @@
-<%page args="license, button=False, button_size='88x31'"/>
+<%page args="license, button=False, button_size='88x31'" expression_filter="h"/>
## keep this synchronized with the contents of cms/templates/js/license-selector.underscore
<%!
from django.utils.translation import ugettext as _
diff --git a/openedx/features/learner_profile/static/learner_profile/templates/share_modal.underscore b/openedx/features/learner_profile/static/learner_profile/templates/share_modal.underscore
index 6034e3e8bf..b71e89823b 100644
--- a/openedx/features/learner_profile/static/learner_profile/templates/share_modal.underscore
+++ b/openedx/features/learner_profile/static/learner_profile/templates/share_modal.underscore
@@ -7,21 +7,32 @@
-
<%=
- interpolate(
- gettext("Create a %(link_start)sMozilla Backpack%(link_end)s account, or log in to your existing account"),
- {link_start: '', link_end: ''},
- true
- )%>
-
-
<%=
- interpolate(
- gettext("%(download_link_start)sDownload this image (right-click or option-click, save as)%(link_end)s and then %(upload_link_start)supload%(link_end)s it to your backpack.
+ <%= edx.HtmlUtils.interpolateHtml(
+ gettext("{download_link_start}Download this image (right-click or option-click, save as){link_end} and then {upload_link_start}upload{link_end} it to your backpack."),
+ {
+ download_link_start: edx.HtmlUtils.joinHtml(
+ edx.HtmlUtils.HTML(''),
+ ),
+ link_end: edx.HtmlUtils.HTML(''),
+ upload_link_start: edx.HtmlUtils.HTML('')
+ }
+ )
+ %>
+
diff --git a/themes/stanford-style/lms/templates/register-shib.html b/themes/stanford-style/lms/templates/register-shib.html
index 80e8db77a2..effa820b15 100644
--- a/themes/stanford-style/lms/templates/register-shib.html
+++ b/themes/stanford-style/lms/templates/register-shib.html
@@ -1,8 +1,10 @@
+<%page expression_filter="h" />
<%inherit file="main.html" />
<%!
from django.utils.translation import ugettext as _
from django.urls import reverse
from openedx.core.djangolib.js_utils import js_escaped_string
+from openedx.core.djangolib.markup import HTML, Text
%>
<%block name="pagetitle">${_("Preferences for {platform_name}").format(platform_name=settings.PLATFORM_NAME)}%block>
@@ -51,8 +53,10 @@ from openedx.core.djangolib.js_utils import js_escaped_string
$('#register-form').on('ajax:error', function(event, jqXHR, textStatus) {
toggleSubmitButton(true);
json = $.parseJSON(jqXHR.responseText);
+ var submission_message = $('.status.message.submission-error .message-copy');
$('.status.message.submission-error').addClass('is-shown').focus();
- $('.status.message.submission-error .message-copy').html(json.value).stop().css("display", "block");
+ edx.HtmlUtils.setHtml(submission_message, edx.HtmlUtils.ensureHtml(json.value));
+ submission_message.stop().css("display", "block");
$(".field-error").removeClass('field-error');
$("[data-field='"+json.field+"']").addClass('field-error')
});
@@ -102,9 +106,13 @@ from openedx.core.djangolib.js_utils import js_escaped_string
- ${_('Required fields are noted by bold text and an asterisk (*).')}
+ ${Text(_('Required fields are noted by {strong_indicator}bold text and an asterisk (*).{strong_close}')).format(
+ strong_indicator=HTML(''),
+ strong_close=HTML('')
+ )}