Commit 5e69224c by Robert Raposa

Deprecate escaping in display_name_with_default

- Remove escaping in display_name_with_default
- Move escaped version to deprecated display_name_with_default_escaped
- Does not include any other changes to remove double-escaping

Thanks to agaylard who initiated this work:
https://github.com/edx/edx-platform/pull/10756

TNL-3425
parent 424d26c9
......@@ -834,7 +834,7 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F
xblock_info = {
"id": unicode(xblock.location),
"display_name": xblock.display_name_with_default,
"display_name": xblock.display_name_with_default_escaped,
"category": xblock.category,
"edited_on": get_default_time_display(xblock.subtree_edited_on) if xblock.subtree_edited_on else None,
"published": published,
......@@ -1098,4 +1098,4 @@ def _xblock_type_and_display_name(xblock):
"""
return _('{section_or_subsection} "{display_name}"').format(
section_or_subsection=xblock_type_display_name(xblock),
display_name=xblock.display_name_with_default)
display_name=xblock.display_name_with_default_escaped)
......@@ -16,9 +16,9 @@ from openedx.core.lib.js_utils import (
<%block name="title"></%block> |
% if context_course:
<% ctx_loc = context_course.location %>
${context_course.display_name_with_default | h} |
${context_course.display_name_with_default_escaped | h} |
% elif context_library:
${context_library.display_name_with_default | h} |
${context_library.display_name_with_default_escaped | h} |
% endif
${settings.STUDIO_NAME}
</title>
......@@ -81,7 +81,7 @@ from openedx.core.lib.js_utils import (
require(['js/factories/course'], function(CourseFactory) {
CourseFactory({
id: "${escape_js_string(context_course.id) | n}",
name: "${context_course.display_name_with_default | h}",
name: "${context_course.display_name_with_default_escaped | h}",
url_name: "${context_course.location.name | h}",
org: "${context_course.location.org | h}",
num: "${context_course.location.course | h}",
......
......@@ -12,7 +12,7 @@ from contentstore.views.helpers import xblock_studio_url, xblock_type_display_na
from django.utils.translation import ugettext as _
from openedx.core.lib.js_utils import escape_json_dumps
%>
<%block name="title">${xblock.display_name_with_default} ${xblock_type_display_name(xblock) | h}</%block>
<%block name="title">${xblock.display_name_with_default_escaped} ${xblock_type_display_name(xblock) | h}</%block>
<%block name="bodyclass">is-signedin course container view-container</%block>
<%namespace name='static' file='static_content.html'/>
......@@ -55,15 +55,15 @@ from openedx.core.lib.js_utils import escape_json_dumps
ancestor_url = xblock_studio_url(ancestor)
%>
% if ancestor_url:
<a href="${ancestor_url | h}" class="navigation-item navigation-link navigation-parent">${ancestor.display_name_with_default | h}</a>
<a href="${ancestor_url | h}" class="navigation-item navigation-link navigation-parent">${ancestor.display_name_with_default_escaped | h}</a>
% else:
<span class="navigation-item navigation-parent">${ancestor.display_name_with_default | h}</span>
<span class="navigation-item navigation-parent">${ancestor.display_name_with_default_escaped | h}</span>
% endif
% endfor
</small>
<div class="wrapper-xblock-field incontext-editor is-editable"
data-field="display_name" data-field-display-name="${_("Display Name")}">
<h1 class="page-header-title xblock-field-value incontext-editor-value"><span class="title-value">${xblock.display_name_with_default | h}</span></h1>
<h1 class="page-header-title xblock-field-value incontext-editor-value"><span class="title-value">${xblock.display_name_with_default_escaped | h}</span></h1>
</div>
</div>
......
......@@ -5,7 +5,7 @@ from contentstore.views.helpers import xblock_studio_url, xblock_type_display_na
from django.utils.translation import ugettext as _
from openedx.core.lib.js_utils import escape_json_dumps
%>
<%block name="title">${context_library.display_name_with_default} ${xblock_type_display_name(context_library)}</%block>
<%block name="title">${context_library.display_name_with_default_escaped} ${xblock_type_display_name(context_library)}</%block>
<%block name="bodyclass">is-signedin course container view-container view-library</%block>
<%namespace name='static' file='static_content.html'/>
......@@ -45,7 +45,7 @@ from openedx.core.lib.js_utils import escape_json_dumps
<small class="subtitle">${_("Content Library")}</small>
<div class="wrapper-xblock-field incontext-editor is-editable"
data-field="display_name" data-field-display-name="${_("Display Name")}">
<h1 class="page-header-title xblock-field-value incontext-editor-value"><span class="title-value">${context_library.display_name_with_default}</span></h1>
<h1 class="page-header-title xblock-field-value incontext-editor-value"><span class="title-value">${context_library.display_name_with_default_escaped}</span></h1>
</div>
</div>
......
......@@ -107,7 +107,7 @@ from openedx.core.lib.js_utils import escape_json_dumps
<%block name="requirejs">
require(["js/factories/manage_users_lib"], function(ManageLibraryUsersFactory) {
ManageLibraryUsersFactory(
"${context_library.display_name_with_default | h}",
"${context_library.display_name_with_default_escaped | h}",
${escape_json_dumps(users) | n},
"${reverse('contentstore.views.course_team_handler', kwargs={'course_key_string': library_key, 'email': '@@EMAIL@@'})}",
${ request.user.id },
......
......@@ -89,10 +89,10 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url}';
<li class="action-item">
<%
email_subject = urllib.quote(_("Enroll in {course_display_name}").format(
course_display_name = context_course.display_name_with_default
course_display_name = context_course.display_name_with_default_escaped
).encode("utf-8"))
email_body = urllib.quote(_('The course "{course_display_name}", provided by {platform_name}, is open for enrollment. Please navigate to this course at {link_for_about_page} to enroll.').format(
course_display_name = context_course.display_name_with_default,
course_display_name = context_course.display_name_with_default_escaped,
platform_name = settings.PLATFORM_NAME,
link_for_about_page = link_for_about_page
).encode("utf-8"))
......
......@@ -9,7 +9,7 @@ xblock_url = xblock_studio_url(xblock)
show_inline = xblock.has_children and not xblock_url
section_class = "level-nesting" if show_inline else "level-element"
collapsible_class = "is-collapsible" if xblock.has_children else ""
label = xblock.display_name_with_default or xblock.scope_ids.block_type
label = xblock.display_name_with_default_escaped or xblock.scope_ids.block_type
messages = xblock.validate().to_json()
%>
......
......@@ -38,7 +38,7 @@
<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}">${context_course.display_name_with_default}</span>
<span class="course-title" title="${context_course.display_name_with_default_escaped}">${context_course.display_name_with_default_escaped}</span>
</a>
</h2>
......@@ -141,7 +141,7 @@
<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}">${context_library.display_name_with_default}</span>
<span class="course-title" title="${context_library.display_name_with_default_escaped}">${context_library.display_name_with_default_escaped}</span>
</a>
</h2>
......
......@@ -120,7 +120,7 @@ class ChooseModeView(View):
"course_modes_choose_url": reverse("course_modes_choose", kwargs={'course_id': course_key.to_deprecated_string()}),
"modes": modes,
"has_credit_upsell": has_credit_upsell,
"course_name": course.display_name_with_default,
"course_name": course.display_name_with_default_escaped,
"course_org": course.display_org_with_default,
"course_num": course.display_number_with_default,
"chosen_price": chosen_price,
......
......@@ -150,7 +150,7 @@ class AnnotatableModule(AnnotatableFields, XModule):
def get_html(self):
""" Renders parameters to template. """
context = {
'display_name': self.display_name_with_default,
'display_name': self.display_name_with_default_escaped,
'element_id': self.element_id,
'instructions_html': self.instructions,
'content_html': self._render_content()
......
......@@ -658,7 +658,7 @@ class CapaMixin(CapaFields):
check_button_checking = False
content = {
'name': self.display_name_with_default,
'name': self.display_name_with_default_escaped,
'html': html,
'weight': self.weight,
}
......
......@@ -57,15 +57,51 @@ def display_name_with_default(course):
like to just pass course.display_name and course.url_name as arguments to
this function, we can't do so without breaking those tests.
Note: This method no longer escapes as it once did, so the caller must
ensure it is properly escaped where necessary.
Arguments:
course (CourseDescriptor|CourseOverview): descriptor or overview of
said course.
"""
# TODO: Consider changing this to use something like xml.sax.saxutils.escape
return (
course.display_name if course.display_name is not None
else course.url_name.replace('_', ' ')
).replace('<', '&lt;').replace('>', '&gt;')
)
def display_name_with_default_escaped(course):
"""
DEPRECATED: use display_name_with_default
Calculates the display name for a course with some HTML escaping.
This follows the same logic as display_name_with_default, with
the addition of the escaping.
Here is an example of how to move away from this method in Mako html:
Before:
<span class="course-name">${course.display_name_with_default_escaped}</span>
After:
<span class="course-name">${course.display_name_with_default | h}</span>
If the context is Javascript in Mako, you'll need to follow other best practices.
Note: Switch to display_name_with_default, and ensure the caller
properly escapes where necessary.
Note: This newly introduced method should not be used. It was only
introduced to enable a quick search/replace and the ability to slowly
migrate and test switching to display_name_with_default, which is no
longer escaped.
Arguments:
course (CourseDescriptor|CourseOverview): descriptor or overview of
said course.
"""
# This escaping is incomplete. However, rather than switching this to use
# markupsafe.escape() and fixing issues, better to put that energy toward
# migrating away from this method altogether.
return course.display_name_with_default.replace('<', '&lt;').replace('>', '&gt;')
def number_for_course_location(location):
......
......@@ -127,7 +127,7 @@ class ImageAnnotationModule(AnnotatableFields, XModule):
def student_view(self, context):
""" Renders parameters to template. """
context = {
'display_name': self.display_name_with_default,
'display_name': self.display_name_with_default_escaped,
'instructions_html': self.instructions,
'token': retrieve_token(self.user_email, self.annotation_token_secret),
'tag': self.instructor_tags,
......
......@@ -224,7 +224,7 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
'path': " > ".join(display_names + [child.display_name or '']),
}
if childinfo['title'] == '':
childinfo['title'] = child.display_name_with_default
childinfo['title'] = child.display_name_with_default_escaped
contents.append(childinfo)
params = {
......
......@@ -11,6 +11,7 @@ from xmodule.course_metadata_utils import (
clean_course_key,
url_name_for_course_location,
display_name_with_default,
display_name_with_default_escaped,
number_for_course_location,
has_course_started,
has_course_ended,
......@@ -133,12 +134,18 @@ class CourseMetadataUtilsTestCase(TestCase):
TestScenario((self.demo_course.location,), self.demo_course.location.name),
TestScenario((self.html_course.location,), self.html_course.location.name),
]),
FunctionTest(display_name_with_default, [
FunctionTest(display_name_with_default_escaped, [
# Test course with no display name.
TestScenario((self.demo_course,), "Empty"),
# Test course with a display name that contains characters that need escaping.
TestScenario((self.html_course,), "Intro to &lt;html&gt;"),
]),
FunctionTest(display_name_with_default, [
# Test course with no display name.
TestScenario((self.demo_course,), "Empty"),
# Test course with a display name that contains characters that need escaping.
TestScenario((self.html_course,), "Intro to <html>"),
]),
FunctionTest(number_for_course_location, [
TestScenario((self.demo_course.location,), "DemoX.1"),
TestScenario((self.html_course.location,), "CS-203"),
......
......@@ -121,7 +121,7 @@ class TextAnnotationModule(AnnotatableFields, XModule):
""" Renders parameters to template. """
context = {
'course_key': self.runtime.course_id,
'display_name': self.display_name_with_default,
'display_name': self.display_name_with_default_escaped,
'tag': self.instructor_tags,
'source': self.source,
'instructions_html': self.instructions,
......
......@@ -334,7 +334,7 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
'cdn_eval': cdn_eval,
'cdn_exp_group': cdn_exp_group,
'id': self.location.html_id(),
'display_name': self.display_name_with_default,
'display_name': self.display_name_with_default_escaped,
'handout': self.handout,
'download_video_link': download_video_link,
'track': track_url,
......
......@@ -128,7 +128,7 @@ class VideoAnnotationModule(AnnotatableFields, XModule):
context = {
'course_key': self.runtime.course_id,
'display_name': self.display_name_with_default,
'display_name': self.display_name_with_default_escaped,
'instructions_html': self.instructions,
'sourceUrl': self.sourceurl,
'typeSource': extension,
......
......@@ -349,6 +349,21 @@ class XModuleMixin(XModuleFields, XBlock):
return course_metadata_utils.display_name_with_default(self)
@property
def display_name_with_default_escaped(self):
"""
DEPRECATED: use display_name_with_default
Return an html escaped display name for the module: use display_name if
defined in metadata, otherwise convert the url name.
Note: This newly introduced method should not be used. It was only
introduced to enable a quick search/replace and the ability to slowly
migrate and test switching to display_name_with_default, which is no
longer escaped.
"""
return course_metadata_utils.display_name_with_default_escaped(self)
@property
def xblock_kvs(self):
"""
Retrieves the internal KeyValueStore for this XModule.
......@@ -424,7 +439,7 @@ class XModuleMixin(XModuleFields, XBlock):
if self.has_children:
return sum((child.get_content_titles() for child in self.get_children()), [])
else:
return [self.display_name_with_default]
return [self.display_name_with_default_escaped]
def get_children(self, usage_id_filter=None, usage_key_filter=None): # pylint: disable=arguments-differ
"""Returns a list of XBlock instances for the children of
......
......@@ -4,7 +4,7 @@ ${_("Dear student,")}
${_("You have been invited to join {course_name} at {site_name} by a "
"member of the course staff.").format(
course_name=course.display_name_with_default,
course_name=course.display_name_with_default_escaped,
site_name=site_name
)}
......@@ -16,7 +16,7 @@ ${_("To finish your registration, please visit {registration_url} and fill "
% if auto_enroll:
${_("Once you have registered and activated your account, you will see "
"{course_name} listed on your dashboard.").format(
course_name=course.display_name_with_default
course_name=course.display_name_with_default_escaped
)}
% else:
${_("Once you have registered and activated your account, visit {course_about_url} "
......
<%! from django.utils.translation import ugettext as _ %>
${_("You have been invited to register for {course_name}").format(
course_name=course.display_name_with_default
course_name=course.display_name_with_default_escaped
)}
\ No newline at end of file
......@@ -5,7 +5,7 @@ ${_("Dear {full_name}").format(full_name=full_name)}
${_("You have been enrolled in {course_name} at {site_name} by a member "
"of the course staff. The course should now appear on your {site_name} "
"dashboard.").format(
course_name=course.display_name_with_default,
course_name=course.display_name_with_default_escaped,
site_name=site_name
)}
......
<%! from django.utils.translation import ugettext as _ %>
${_("You have been enrolled in {course_name}").format(
course_name=course.display_name_with_default
course_name=course.display_name_with_default_escaped
)}
\ No newline at end of file
......@@ -4,7 +4,7 @@ ${_("Dear Student,")}
${_("You have been un-enrolled from course {course_name} by a member "
"of the course staff. Please disregard the invitation "
"previously sent.").format(course_name=course.display_name_with_default)}
"previously sent.").format(course_name=course.display_name_with_default_escaped)}
----
${_("This email was automatically sent from {site_name} "
......
......@@ -5,13 +5,13 @@ ${_("Dear {full_name}").format(full_name=full_name)}
${_("You have been un-enrolled in {course_name} at {site_name} by a member "
"of the course staff. The course will no longer appear on your "
"{site_name} dashboard.").format(
course_name=course.display_name_with_default, site_name=site_name
course_name=course.display_name_with_default_escaped, site_name=site_name
)}
${_("Your other courses have not been affected.")}
----
${_("This email was automatically sent from {site_name} to "
"{full_name}").format(
full_name=full_name, site_name=site_name
)}
\ No newline at end of file
"{full_name}").format(
full_name=full_name, site_name=site_name
)}
<%! from django.utils.translation import ugettext as _ %>
${_("You have been un-enrolled from {course_name}").format(
course_name=course.display_name_with_default
course_name=course.display_name_with_default_escaped
)}
\ No newline at end of file
......@@ -39,7 +39,7 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth
"""
course_id = serializers.CharField(source='id', read_only=True)
name = serializers.CharField(source='display_name_with_default')
name = serializers.CharField(source='display_name_with_default_escaped')
number = serializers.CharField(source='display_number_with_default')
org = serializers.CharField(source='display_org_with_default')
short_description = serializers.CharField()
......
......@@ -89,7 +89,7 @@ def course_wiki_redirect(request, course_id): # pylint: disable=unused-argument
# Translators: this string includes wiki markup. Leave the ** and the _ alone.
_("This is the wiki for **{organization}**'s _{course_name}_.").format(
organization=course.display_org_with_default,
course_name=course.display_name_with_default,
course_name=course.display_name_with_default_escaped,
)
)
urlpath = URLPath.create_article(
......
......@@ -223,9 +223,9 @@ def get_courseware_with_tabs(course_id):
course = get_course_by_id(course_id)
chapters = [chapter for chapter in course.get_children() if not chapter.hide_from_toc]
courseware = [{
'chapter_name': c.display_name_with_default,
'chapter_name': c.display_name_with_default_escaped,
'sections': [{
'section_name': s.display_name_with_default,
'section_name': s.display_name_with_default_escaped,
'clickable_tab_count': len(s.get_children()) if (type(s) == seq_module.SequenceDescriptor) else 0,
'tabs': [{
'children_count': len(t.get_children()) if (type(t) == vertical_block.VerticalBlock) else 0,
......
......@@ -247,7 +247,7 @@ def answer_distributions(course_key):
problem_store = modulestore()
if usage_key not in state_keys_to_problem_info:
problem = problem_store.get_item(usage_key)
problem_info = (problem.url_name, problem.display_name_with_default)
problem_info = (problem.url_name, problem.display_name_with_default_escaped)
state_keys_to_problem_info[usage_key] = problem_info
return state_keys_to_problem_info[usage_key]
......@@ -374,7 +374,7 @@ def _grade(student, request, course, keep_raw_scores, field_data_cache, scores_c
format_scores = []
for section in sections:
section_descriptor = section['section_descriptor']
section_name = section_descriptor.display_name_with_default
section_name = section_descriptor.display_name_with_default_escaped
with outer_atomic():
# some problems have state that is updated independently of interaction
......@@ -449,7 +449,7 @@ def _grade(student, request, course, keep_raw_scores, field_data_cache, scores_c
correct,
total,
graded,
module_descriptor.display_name_with_default,
module_descriptor.display_name_with_default_escaped,
module_descriptor.location
)
)
......@@ -629,7 +629,7 @@ def _progress_summary(student, request, course, field_data_cache=None, scores_cl
correct,
total,
graded,
module_descriptor.display_name_with_default,
module_descriptor.display_name_with_default_escaped,
module_descriptor.location
)
......@@ -638,11 +638,11 @@ def _progress_summary(student, request, course, field_data_cache=None, scores_cl
scores.reverse()
section_total, _ = graders.aggregate_scores(
scores, section_module.display_name_with_default)
scores, section_module.display_name_with_default_escaped)
module_format = section_module.format if section_module.format is not None else ''
sections.append({
'display_name': section_module.display_name_with_default,
'display_name': section_module.display_name_with_default_escaped,
'url_name': section_module.url_name,
'scores': scores,
'section_total': section_total,
......@@ -652,8 +652,8 @@ def _progress_summary(student, request, course, field_data_cache=None, scores_cl
})
chapters.append({
'course': course.display_name_with_default,
'display_name': chapter_module.display_name_with_default,
'course': course.display_name_with_default_escaped,
'display_name': chapter_module.display_name_with_default_escaped,
'url_name': chapter_module.url_name,
'sections': sections
})
......
......@@ -166,7 +166,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
for chapter in chapters:
# Only show required content, if there is required content
# chapter.hide_from_toc is read-only (boo)
display_id = slugify(chapter.display_name_with_default)
display_id = slugify(chapter.display_name_with_default_escaped)
local_hide_from_toc = False
if required_content:
if unicode(chapter.location) not in required_content:
......@@ -184,7 +184,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
if not section.hide_from_toc:
section_context = {
'display_name': section.display_name_with_default,
'display_name': section.display_name_with_default_escaped,
'url_name': section.url_name,
'format': section.format if section.format is not None else '',
'due': section.due,
......@@ -247,7 +247,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
sections.append(section_context)
toc_chapters.append({
'display_name': chapter.display_name_with_default,
'display_name': chapter.display_name_with_default_escaped,
'display_id': display_id,
'url_name': chapter.url_name,
'sections': sections,
......@@ -941,7 +941,7 @@ def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_inf
tracking_context = {
'module': {
'display_name': descriptor.display_name_with_default,
'display_name': descriptor.display_name_with_default_escaped,
'usage_key': unicode(descriptor.location),
}
}
......
......@@ -427,7 +427,7 @@ def _index_bulk_op(request, course_key, chapter, section, position):
context = {
'csrf': csrf(request)['csrf_token'],
'accordion': render_accordion(user, request, course, chapter, section, field_data_cache),
'COURSE_TITLE': course.display_name_with_default,
'COURSE_TITLE': course.display_name_with_default_escaped,
'course': course,
'init': '',
'fragment': Fragment(),
......@@ -539,7 +539,7 @@ def _index_bulk_op(request, course_key, chapter, section, position):
save_child_position(chapter_module, section)
section_render_context = {'activate_block_id': request.GET.get('activate_block_id')}
context['fragment'] = section_module.render(STUDENT_VIEW, section_render_context)
context['section_title'] = section_descriptor.display_name_with_default
context['section_title'] = section_descriptor.display_name_with_default_escaped
else:
# section is none, so display a message
studio_url = get_studio_url(course, 'course')
......
......@@ -207,7 +207,7 @@ def get_module_context(course, item):
"""
item_dict = {
'location': unicode(item.location),
'display_name': item.display_name_with_default,
'display_name': item.display_name_with_default_escaped,
}
if item.category == 'chapter' and item.get_parent():
# course is a locator w/o branch and version
......@@ -328,7 +328,7 @@ def get_course_position(course_module):
urlargs['chapter'] = chapter.url_name
if course_module.position is not None:
return {
'display_name': chapter.display_name_with_default,
'display_name': chapter.display_name_with_default_escaped,
'url': reverse('courseware_chapter', kwargs=urlargs),
}
......@@ -340,7 +340,7 @@ def get_course_position(course_module):
urlargs['section'] = section.url_name
return {
'display_name': section.display_name_with_default,
'display_name': section.display_name_with_default_escaped,
'url': reverse('courseware_section', kwargs=urlargs)
}
......
......@@ -281,7 +281,7 @@ def get_email_params(course, auto_enroll, secure=True, course_key=None, display_
protocol = 'https' if secure else 'http'
course_key = course_key or course.id.to_deprecated_string()
display_name = display_name or course.display_name_with_default
display_name = display_name or course.display_name_with_default_escaped
stripped_site_name = microsite.get_value(
'SITE_NAME',
......
......@@ -132,7 +132,7 @@ def manage_modulestores(request, reload_dir=None, commit_id=None):
for cdir, course in def_ms.courses.items():
html += '<hr width="100%"/>'
html += '<h2>Course: %s (%s)</h2>' % (course.display_name_with_default, cdir)
html += '<h2>Course: %s (%s)</h2>' % (course.display_name_with_default_escaped, cdir)
html += '<p>commit_id=%s</p>' % get_commit_id(course)
......
......@@ -107,7 +107,7 @@ def path(block, child_to_parent, start_block):
if block is not start_block:
block_path.append({
# to be consistent with other edx-platform clients, return the defaulted display name
'name': block.display_name_with_default,
'name': block.display_name_with_default_escaped,
'category': block.category,
'id': unicode(block.location)
})
......
......@@ -1578,7 +1578,7 @@ class PaidCourseRegistration(OrderItem):
item.unit_cost = cost
item.list_price = cost
item.line_desc = _(u'Registration for Course: {course_name}').format(
course_name=course.display_name_with_default)
course_name=course.display_name_with_default_escaped)
item.currency = currency
order.currency = currency
item.report_comments = item.csv_report_comments
......@@ -1755,7 +1755,7 @@ class CourseRegCodeItem(OrderItem):
item.list_price = cost
item.qty = qty
item.line_desc = _(u'Enrollment codes for Course: {course_name}').format(
course_name=course.display_name_with_default)
course_name=course.display_name_with_default_escaped)
item.currency = currency
order.currency = currency
item.report_comments = item.csv_report_comments
......
......@@ -157,7 +157,8 @@ class CertificateStatusReport(Report):
# it in the report. These comparisons are unicode-safe.
cur_course = get_course_by_id(course_id)
university = cur_course.org
course = cur_course.number + " " + cur_course.display_name_with_default # TODO add term (i.e. Fall 2013)?
# TODO add term (i.e. Fall 2013) to course?
course = cur_course.number + " " + cur_course.display_name_with_default_escaped
counts = CourseEnrollment.objects.enrollment_counts(course_id)
total_enrolled = counts['total']
audit_enrolled = counts['audit']
......@@ -237,7 +238,7 @@ class UniversityRevenueShareReport(Report):
for course_id in course_ids_between(self.start_word, self.end_word):
cur_course = get_course_by_id(course_id)
university = cur_course.org
course = cur_course.number + " " + cur_course.display_name_with_default
course = cur_course.number + " " + cur_course.display_name_with_default_escaped
total_payments_collected = CertificateItem.verified_certificates_monetary_field_sum(course_id, 'purchased', 'unit_cost')
service_fees = CertificateItem.verified_certificates_monetary_field_sum(course_id, 'purchased', 'service_fee')
num_refunds = CertificateItem.verified_certificates_count(course_id, "refunded")
......
......@@ -2297,7 +2297,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase):
"We have successfully verified your identity for the {assessment} "
"assessment in the {course_name} course.".format(
assessment=self.assessment,
course_name=self.course.display_name_with_default
course_name=self.course.display_name_with_default_escaped
),
body
)
......@@ -2316,7 +2316,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase):
"in the {course_name} course. You have used "
"{used_attempts} out of {allowed_attempts} attempts to "
"verify your identity".format(
course_name=self.course.display_name_with_default,
course_name=self.course.display_name_with_default_escaped,
assessment=self.assessment,
used_attempts=1,
allowed_attempts=self.allowed_attempts + 1
......@@ -2361,7 +2361,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase):
"{used_attempts} out of {allowed_attempts} attempts to "
"verify your identity, and verification is no longer "
"possible".format(
course_name=self.course.display_name_with_default,
course_name=self.course.display_name_with_default_escaped,
assessment=self.assessment,
used_attempts=2,
allowed_attempts=self.allowed_attempts + 1
......@@ -2385,7 +2385,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase):
"{used_attempts} out of {allowed_attempts} attempts to "
"verify your identity, and verification is no longer "
"possible".format(
course_name=self.course.display_name_with_default,
course_name=self.course.display_name_with_default_escaped,
assessment=self.assessment,
used_attempts=1,
allowed_attempts=self.allowed_attempts + 1
......@@ -2494,7 +2494,7 @@ class TestEmailMessageWithDefaultICRVBlock(ModuleStoreTestCase):
"{used_attempts} out of {allowed_attempts} attempts to "
"verify your identity, and verification is no longer "
"possible".format(
course_name=self.course.display_name_with_default,
course_name=self.course.display_name_with_default_escaped,
assessment=self.assessment,
used_attempts=1,
allowed_attempts=1
......
......@@ -1150,7 +1150,7 @@ def _compose_message_reverification_email(
subject = "Re-verification Status"
context = {
"status": status,
"course_name": course.display_name_with_default,
"course_name": course.display_name_with_default_escaped,
"assessment": reverification_block.related_assessment
}
......@@ -1431,7 +1431,7 @@ class InCourseReverifyView(View):
context = {
'course_key': unicode(course_key),
'course_name': course.display_name_with_default,
'course_name': course.display_name_with_default_escaped,
'checkpoint_name': checkpoint.checkpoint_name,
'platform_name': settings.PLATFORM_NAME,
'usage_id': usage_id,
......
......@@ -6,7 +6,7 @@ def _message(reqm, message):
return message.format(link="<a href={url}>{url_name}</a>".format(
url = reverse('jump_to', kwargs=dict(course_id=reqm.course_id.to_deprecated_string(),
location=reqm.location.to_deprecated_string())),
url_name = reqm.display_name_with_default))
url_name = reqm.display_name_with_default_escaped))
%>
% if message:
% for reqm in module.required_modules:
......
......@@ -4,11 +4,11 @@ from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
%>
<%page args="course" />
<article class="course" id="${course.id | h}" role="region" aria-label="${course.display_name_with_default}">
<article class="course" id="${course.id | h}" role="region" aria-label="${course.display_name_with_default_escaped}">
<a href="${reverse('about_course', args=[course.id.to_deprecated_string()])}">
<header class="course-image">
<div class="cover-image">
<img src="${course.course_image_url | h}" alt="${course.display_name_with_default} ${course.display_number_with_default | h}" />
<img src="${course.course_image_url | h}" alt="${course.display_name_with_default_escaped} ${course.display_number_with_default | h}" />
<div class="learn-more" aria-hidden=true>${_("LEARN MORE")}</div>
</div>
</header>
......@@ -16,7 +16,7 @@ from django.core.urlresolvers import reverse
<h2 class="course-name">
<span class="course-organization">${course.display_org_with_default | h}</span>
<span class="course-code">${course.display_number_with_default | h}</span>
<span class="course-title">${course.display_name_with_default}</span>
<span class="course-title">${course.display_name_with_default_escaped}</span>
</h2>
<div class="course-date" aria-hidden="true">${_("Starts")}: ${course.start_datetime_text()}</div>
</div>
......
......@@ -13,7 +13,7 @@ from openedx.core.lib.courses import course_image_url
<%block name="headextra">
## OG (Open Graph) title 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:title" content="${course.display_name_with_default_escaped}" />
<meta property="og:description" content="${get_course_about_section(request, course, 'short_description')}" />
</%block>
......@@ -102,7 +102,7 @@ from openedx.core.lib.courses import course_image_url
<script src="${static.url('js/course_info.js')}"></script>
</%block>
<%block name="pagetitle">${course.display_name_with_default}</%block>
<%block name="pagetitle">${course.display_name_with_default_escaped}</%block>
<section class="course-info">
<header class="course-profile">
......@@ -111,7 +111,7 @@ from openedx.core.lib.courses import course_image_url
<section class="intro">
<hgroup>
<h1>
${course.display_name_with_default}
${course.display_name_with_default_escaped}
% if not self.theme_enabled():
<a href="#">${course.display_org_with_default | h}</a>
% endif
......@@ -220,10 +220,10 @@ from openedx.core.lib.courses import course_image_url
## or something allowing themes to do whatever they
## want here (and on this whole page, really).
% if self.stanford_theme_enabled():
<a href="http://twitter.com/intent/tweet?text=I+just+enrolled+in+${course.number}+${course.display_name_with_default}!+(http://class.stanford.edu)" class="share">
<a href="http://twitter.com/intent/tweet?text=I+just+enrolled+in+${course.number}+${course.display_name_with_default_escaped}!+(http://class.stanford.edu)" class="share">
<i class="icon fa fa-twitter"></i><span class="sr">${_("Tweet that you've enrolled in this course")}</span>
</a>
<a href="mailto:?subject=Take%20a%20course%20at%20Stanford%20online!&body=I%20just%20enrolled%20in%20${course.number}%20${course.display_name_with_default}+(http://class.stanford.edu)" class="share">
<a href="mailto:?subject=Take%20a%20course%20at%20Stanford%20online!&body=I%20just%20enrolled%20in%20${course.number}%20${course.display_name_with_default_escaped}+(http://class.stanford.edu)" class="share">
<i class="icon fa fa-envelope"></i><span class="sr">${_("Email someone to say you've enrolled in this course")}</span>
</a>
% else:
......@@ -235,7 +235,7 @@ from openedx.core.lib.courses import course_image_url
## Twitter account. {url} should appear at the end of the text.
tweet_text = _("I just enrolled in {number} {title} through {account}: {url}").format(
number=course.number,
title=course.display_name_with_default,
title=course.display_name_with_default_escaped,
account=microsite.get_value('course_about_twitter_account', settings.PLATFORM_TWITTER_ACCOUNT),
url=u"http://{domain}{path}".format(
domain=site_domain,
......@@ -250,7 +250,7 @@ from openedx.core.lib.courses import course_image_url
subject=_("Take a course with {platform} online").format(platform=platform_name),
body=_("I just enrolled in {number} {title} through {platform} {url}").format(
number=course.number,
title=course.display_name_with_default,
title=course.display_name_with_default_escaped,
platform=platform_name,
url=u"http://{domain}{path}".format(
domain=site_domain,
......
......@@ -2,11 +2,11 @@
from django.utils.translation import ugettext as _
%>
<h2>${chapter_module.display_name_with_default}</h2>
<h2>${chapter_module.display_name_with_default_escaped}</h2>
<p>${_("You were most recently in {section_link}. If you\'re done with that, choose another section on the left.").format(
section_link=u'<a href="{url}">{section_name}</a>'.format(
url=prev_section_url,
section_name=prev_section.display_name_with_default,
section_name=prev_section.display_name_with_default_escaped,
)
)}</p>
......@@ -28,7 +28,7 @@ from django.core.urlresolvers import reverse
<section class="discussion container" id="discussion-container"
data-roles="${roles | h}"
data-course-id="${course_id | h}"
data-course-name="${course.display_name_with_default | h}"
data-course-name="${course.display_name_with_default_escaped | h}"
data-user-info="${user_info | h}"
data-user-create-comment="${can_create_comment | h}"
data-user-create-subcomment="${can_create_subcomment | h}"
......
......@@ -33,7 +33,7 @@ from django.template.defaultfilters import escapejs
</nav>
</section>
<section class="course-content container discussion-user-threads" data-course-id="${course.id | h}" data-course-name="${course.display_name_with_default | h}" data-threads="${threads | h}" data-user-info="${user_info | h}" data-page="${page | h}" data-num-pages="${num_pages | h}"/>
<section class="course-content container discussion-user-threads" data-course-id="${course.id | h}" data-course-name="${course.display_name_with_default_escaped | h}" data-threads="${threads | h}" data-user-info="${user_info | h}" data-page="${page | h}" data-num-pages="${num_pages | h}"/>
</div>
</section>
......
<%! from django.utils.translation import ugettext as _ %>
${_("Welcome to {course_name}").format(course_name=course.display_name_with_default)}
${_("Welcome to {course_name}").format(course_name=course.display_name_with_default_escaped)}
${_("To get started, please visit https://{site_name}. The login information for your account follows.").format(site_name=site_name)}
......@@ -11,4 +11,4 @@ ${_("It is recommended that you change your password.")}
${_("Sincerely yours,"
""
"The {course_name} Team").format(course_name=course.display_name_with_default)}
"The {course_name} Team").format(course_name=course.display_name_with_default_escaped)}
......@@ -4,7 +4,7 @@ ${_("Dear {full_name}").format(full_name=full_name)}
${_("You have been invited to be a beta tester for {course_name} at {site_name} by a "
"member of the course staff.").format(
course_name=course.display_name_with_default,
course_name=course.display_name_with_default_escaped,
site_name=site_name
)}
......
<%! from django.utils.translation import ugettext as _ %>
${_("You have been invited to a beta test for {course_name}").format(
course_name=course.display_name_with_default
course_name=course.display_name_with_default_escaped
)}
......@@ -4,7 +4,7 @@ ${_("Dear student,")}
${_("You have been invited to join {course_name} at {site_name} by a "
"member of the course staff.").format(
course_name=display_name or course.display_name_with_default,
course_name=display_name or course.display_name_with_default_escaped,
site_name=site_name
)}
% if is_shib_course:
......@@ -26,13 +26,13 @@ ${_("To finish your registration, please visit {registration_url} and fill "
% if auto_enroll:
${_("Once you have registered and activated your account, you will see "
"{course_name} listed on your dashboard.").format(
course_name=display_name or course.display_name_with_default
course_name=display_name or course.display_name_with_default_escaped
)}
% elif course_about_url is not None:
${_("Once you have registered and activated your account, visit {course_about_url} "
"to join the course.").format(course_about_url=course_about_url)}
% else:
${_("You can then enroll in {course_name}.").format(course_name=display_name or course.display_name_with_default)}
${_("You can then enroll in {course_name}.").format(course_name=display_name or course.display_name_with_default_escaped)}
% endif
% endif
......
<%! from django.utils.translation import ugettext as _ %>
${_("You have been invited to register for {course_name}").format(
course_name=display_name or course.display_name_with_default
course_name=display_name or course.display_name_with_default_escaped
)}
\ No newline at end of file
......@@ -5,7 +5,7 @@ ${_("Dear {full_name}").format(full_name=full_name)}
${_("You have been enrolled in {course_name} at {site_name} by a member "
"of the course staff. The course should now appear on your {site_name} "
"dashboard.").format(
course_name=display_name or course.display_name_with_default,
course_name=display_name or course.display_name_with_default_escaped,
site_name=site_name
)}
......
<%! from django.utils.translation import ugettext as _ %>
${_("You have been enrolled in {course_name}").format(
course_name=display_name or course.display_name_with_default
course_name=display_name or course.display_name_with_default_escaped
)}
\ No newline at end of file
......@@ -5,7 +5,7 @@ ${_("Dear {full_name}").format(full_name=full_name)}
${_("You have been removed as a beta tester for {course_name} at {site_name} by a "
"member of the course staff. The course will remain on your dashboard, but "
"you will no longer be part of the beta testing group.").format(
course_name=course.display_name_with_default,
course_name=course.display_name_with_default_escaped,
site_name=site_name
)}
......
<%! from django.utils.translation import ugettext as _ %>
${_("You have been removed from a beta test for {course_name}").format(
course_name=course.display_name_with_default
course_name=course.display_name_with_default_escaped
)}
......@@ -4,7 +4,7 @@ ${_("Dear Student,")}
${_("You have been un-enrolled from course {course_name} by a member "
"of the course staff. Please disregard the invitation "
"previously sent.").format(course_name=display_name or course.display_name_with_default)}
"previously sent.").format(course_name=display_name or course.display_name_with_default_escaped)}
----
${_("This email was automatically sent from {site_name} "
......
......@@ -5,13 +5,13 @@ ${_("Dear {full_name}").format(full_name=full_name)}
${_("You have been un-enrolled in {course_name} at {site_name} by a member "
"of the course staff. The course will no longer appear on your "
"{site_name} dashboard.").format(
course_name=display_name or course.display_name_with_default, site_name=site_name
course_name=display_name or course.display_name_with_default_escaped, site_name=site_name
)}
${_("Your other courses have not been affected.")}
----
${_("This email was automatically sent from {site_name} to "
"{full_name}").format(
full_name=full_name, site_name=site_name
)}
\ No newline at end of file
"{full_name}").format(
full_name=full_name, site_name=site_name
)}
<%! from django.utils.translation import ugettext as _ %>
${_("You have been un-enrolled from {course_name}").format(
course_name=display_name or course.display_name_with_default
course_name=display_name or course.display_name_with_default_escaped
)}
\ No newline at end of file
......@@ -50,7 +50,7 @@ site_status_msg = get_site_status_msg(course_id)
<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}</span>
<span class="course-name">${course.display_name_with_default_escaped}</span>
</h2>
% endif
......
......@@ -51,7 +51,7 @@ site_status_msg = get_site_status_msg(course_id)
<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>
<%
display_name = course.display_name_with_default
display_name = course.display_name_with_default_escaped
if settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
ccx = get_current_ccx(course.id)
if ccx:
......
......@@ -292,7 +292,7 @@ from openedx.core.lib.courses import course_image_url
<div class="clearfix">
<div class="image">
<img class="item-image" src="${course_image_url(course)}"
alt="${course.display_number_with_default | h} ${course.display_name_with_default} Image"/>
alt="${course.display_number_with_default | h} ${course.display_name_with_default_escaped} Image"/>
</div>
<div class="data-input">
......
......@@ -20,7 +20,7 @@ from openedx.core.lib.courses import course_image_url
<img class="item-image" src="${course_image_url(course)}"
alt="${_("{course_number} {course_title} Cover Image").format(
course_number=course.display_number_with_default,
course_title=course.display_name_with_default,
course_title=course.display_name_with_default_escaped,
)}"/>
</div>
<div class="enrollment-details">
......
......@@ -20,7 +20,7 @@ from openedx.core.lib.courses import course_image_url
<img class="item-image" src="${course_image_url(course)}"
alt="${_("{course_number} {course_title} Cover Image").format(
course_number=course.display_number_with_default,
course_title=course.display_name_with_default,
course_title=course.display_name_with_default_escaped,
)}" />
</div>
<div class="enrollment-details">
......
......@@ -66,7 +66,7 @@ from openedx.core.lib.courses import course_image_url
<div class="clearfix">
<div class="image">
<img class="item-image" src="${course_image_url(course)}"
alt="${course.display_number_with_default | h} ${course.display_name_with_default} ${_('Cover Image')}" />
alt="${course.display_number_with_default | h} ${course.display_name_with_default_escaped} ${_('Cover Image')}" />
</div>
<div class="data-input">
## Translators: "Registration for:" is followed by a course name
......
......@@ -324,6 +324,20 @@ class CourseOverview(TimeStampedModel):
"""
return course_metadata_utils.display_name_with_default(self)
@property
def display_name_with_default_escaped(self):
"""
DEPRECATED: use display_name_with_default
Return html escaped reasonable display name for the course.
Note: This newly introduced method should not be used. It was only
introduced to enable a quick search/replace and the ability to slowly
migrate and test switching to display_name_with_default, which is no
longer escaped.
"""
return course_metadata_utils.display_name_with_default_escaped(self)
def has_started(self):
"""
Returns whether the the course has started.
......
......@@ -104,6 +104,7 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
'number',
'url_name',
'display_name_with_default',
'display_name_with_default_escaped',
'start_date_is_still_default',
'pre_requisite_courses',
'enrollment_domain',
......
......@@ -128,7 +128,7 @@ def wrap_xblock(
template_context = {
'content': block.display_name if display_name_only else frag.content,
'classes': css_classes,
'display_name': block.display_name_with_default,
'display_name': block.display_name_with_default_escaped,
'data_attributes': u' '.join(u'data-{}="{}"'.format(markupsafe.escape(key), markupsafe.escape(value))
for key, value in data.iteritems()),
}
......
......@@ -50,7 +50,7 @@ site_status_msg = get_site_status_msg(course_id)
<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}</span>
<span class="course-name">${course.display_name_with_default_escaped}</span>
</h2>
% endif
......
......@@ -52,7 +52,7 @@ site_status_msg = get_site_status_msg(course_id)
<h2><span class="provider">${course.display_org_with_default | h}:</span>
${course.display_number_with_default | h}
<%
display_name = course.display_name_with_default
display_name = course.display_name_with_default_escaped
if settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
ccx = get_current_ccx()
if ccx:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment