Commit 8e1e4a47 by Robert Raposa

Use markup HTML helper with Text

TNL-4160
parent 66ae31f5
...@@ -10,7 +10,7 @@ from provider.constants import CONFIDENTIAL ...@@ -10,7 +10,7 @@ from provider.constants import CONFIDENTIAL
from openedx.core.djangoapps.programs.models import ProgramsApiConfig from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin, ProgramsDataMixin from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin, ProgramsDataMixin
from openedx.core.djangolib.markup import escape from openedx.core.djangolib.markup import Text
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
...@@ -64,7 +64,7 @@ class TestProgramListing(ProgramsApiConfigMixin, ProgramsDataMixin, SharedModule ...@@ -64,7 +64,7 @@ class TestProgramListing(ProgramsApiConfigMixin, ProgramsDataMixin, SharedModule
self.mock_programs_api(data={'results': []}) self.mock_programs_api(data={'results': []})
response = self.client.get(self.studio_home) response = self.client.get(self.studio_home)
self.assertIn(escape("You haven't created any programs yet."), response.content) self.assertIn(Text("You haven't created any programs yet."), response.content)
# When data is provided, expect a program listing. # When data is provided, expect a program listing.
self.mock_programs_api() self.mock_programs_api()
......
## coding=utf-8 ## coding=utf-8
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%! <%!
from openedx.core.djangolib.markup import ugettext as _ from django.utils.translation import ugettext as _
from openedx.core.djangolib.js_utils import ( from openedx.core.djangolib.js_utils import (
dump_js_escaped_json, js_escaped_string dump_js_escaped_json, js_escaped_string
) )
......
<%page expression_filter="h"/>
<%inherit file="base.html" /> <%inherit file="base.html" />
<%def name="online_help_token()"> <%def name="online_help_token()">
<% <%
...@@ -8,27 +9,30 @@ else: ...@@ -8,27 +9,30 @@ else:
%> %>
</%def> </%def>
<%! <%!
from django.utils.translation import ugettext as _
from contentstore.views.helpers import xblock_studio_url, xblock_type_display_name from contentstore.views.helpers import xblock_studio_url, xblock_type_display_name
from openedx.core.djangolib.js_utils import ( from openedx.core.djangolib.js_utils import (
dump_js_escaped_json, js_escaped_string dump_js_escaped_json, js_escaped_string
) )
from openedx.core.djangolib.markup import HTML, ugettext as _ from openedx.core.djangolib.markup import Text, HTML
%> %>
<%block name="title">${xblock.display_name_with_default_escaped} ${xblock_type_display_name(xblock) | h}</%block>
<%block name="title">${xblock.display_name_with_default} ${xblock_type_display_name(xblock)}</%block>
<%block name="bodyclass">is-signedin course container view-container</%block> <%block name="bodyclass">is-signedin course container view-container</%block>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%block name="header_extras"> <%block name="header_extras">
% for template_name in templates: % for template_name in templates:
<script type="text/template" id="${template_name | h}-tpl"> <script type="text/template" id="${template_name}-tpl">
<%static:include path="js/${template_name}.underscore" /> <%static:include path="js/${template_name}.underscore" />
</script> </script>
% endfor % endfor
<script type="text/template" id="image-modal-tpl"> <script type="text/template" id="image-modal-tpl">
<%static:include path="common/templates/image-modal.underscore" /> <%static:include path="common/templates/image-modal.underscore" />
</script> </script>
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css') | h}" /> <link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
</%block> </%block>
<%block name="requirejs"> <%block name="requirejs">
...@@ -57,15 +61,15 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -57,15 +61,15 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
ancestor_url = xblock_studio_url(ancestor) ancestor_url = xblock_studio_url(ancestor)
%> %>
% if ancestor_url: % if ancestor_url:
<a href="${ancestor_url | h}" class="navigation-item navigation-link navigation-parent">${ancestor.display_name_with_default_escaped | h}</a> <a href="${ancestor_url}" class="navigation-item navigation-link navigation-parent">${ancestor.display_name_with_default}</a>
% else: % else:
<span class="navigation-item navigation-parent">${ancestor.display_name_with_default_escaped | h}</span> <span class="navigation-item navigation-parent">${ancestor.display_name_with_default}</span>
% endif % endif
% endfor % endfor
</small> </small>
<div class="wrapper-xblock-field incontext-editor is-editable" <div class="wrapper-xblock-field incontext-editor is-editable"
data-field="display_name" data-field-display-name="${_("Display Name")}"> 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_escaped | h}</span></h1> <h1 class="page-header-title xblock-field-value incontext-editor-value"><span class="title-value">${xblock.display_name_with_default}</span></h1>
</div> </div>
</div> </div>
...@@ -74,12 +78,12 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -74,12 +78,12 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
<ul> <ul>
% if is_unit_page: % if is_unit_page:
<li class="action-item action-view nav-item"> <li class="action-item action-view nav-item">
<a href="${published_preview_link | h}" class="button button-view action-button is-disabled" aria-disabled="true" rel="external" title="${_('Open the courseware in the LMS')}"> <a href="${published_preview_link}" class="button button-view action-button is-disabled" aria-disabled="true" rel="external" title="${_('Open the courseware in the LMS')}">
<span class="action-button-text">${_("View Live Version")}</span> <span class="action-button-text">${_("View Live Version")}</span>
</a> </a>
</li> </li>
<li class="action-item action-preview nav-item"> <li class="action-item action-preview nav-item">
<a href="${draft_preview_link | h}" class="button button-preview action-button" rel="external" title="${_('Preview the courseware in the LMS')}"> <a href="${draft_preview_link}" class="button button-preview action-button" rel="external" title="${_('Preview the courseware in the LMS')}">
<span class="action-button-text">${_("Preview")}</span> <span class="action-button-text">${_("Preview")}</span>
</a> </a>
</li> </li>
...@@ -102,7 +106,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -102,7 +106,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
<article class="content-primary"> <article class="content-primary">
<div class="container-message wrapper-message"></div> <div class="container-message wrapper-message"></div>
<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" data-locator="${xblock_locator | h}" data-course-key="${xblock_locator.course_key | h}"> <section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" data-locator="${xblock_locator}" data-course-key="${xblock_locator.course_key}">
</section> </section>
<div class="ui-loading"> <div class="ui-loading">
<p><span class="spin"><i class="icon fa fa-refresh"></i></span> <span class="copy">${_("Loading")}</span></p> <p><span class="spin"><i class="icon fa fa-refresh"></i></span> <span class="copy">${_("Loading")}</span></p>
...@@ -112,13 +116,13 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -112,13 +116,13 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
% if xblock.category == 'split_test': % if xblock.category == 'split_test':
<div class="bit"> <div class="bit">
<h3 class="title-3">${_("Adding components")}</h3> <h3 class="title-3">${_("Adding components")}</h3>
<p>${_("Select a component type under {strong_start}Add New Component{strong_end}. Then select a template.").format( <p>${Text(_("Select a component type under {strong_start}Add New Component{strong_end}. Then select a template.")).format(
strong_start=HTML('<strong>'), strong_start=HTML('<strong>'),
strong_end=HTML("</strong>"), strong_end=HTML("</strong>"),
)}</p> )}</p>
<p>${_("The new component is added at the bottom of the page or group. You can then edit and move the component.")}</p> <p>${_("The new component is added at the bottom of the page or group. You can then edit and move the component.")}</p>
<h3 class="title-3">${_("Editing components")}</h3> <h3 class="title-3">${_("Editing components")}</h3>
<p>${_("Click the {strong_start}Edit{strong_end} icon in a component to edit its content.").format( <p>${Text(_("Click the {strong_start}Edit{strong_end} icon in a component to edit its content.")).format(
strong_start=HTML('<strong>'), strong_start=HTML('<strong>'),
strong_end=HTML("</strong>"), strong_end=HTML("</strong>"),
)}</p> )}</p>
...@@ -129,7 +133,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -129,7 +133,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
<p>${_("Confirm that you have properly configured content in each of your experiment groups.")}</p> <p>${_("Confirm that you have properly configured content in each of your experiment groups.")}</p>
</div> </div>
<div class="bit external-help"> <div class="bit external-help">
<a href="${get_online_help_info(online_help_token())['doc_url'] | h}" target="_blank" class="button external-help-button">${_("Learn more about component containers")}</a> <a href="${get_online_help_info(online_help_token())['doc_url']}" target="_blank" class="button external-help-button">${_("Learn more about component containers")}</a>
</div> </div>
% elif is_unit_page: % elif is_unit_page:
<div id="publish-unit"></div> <div id="publish-unit"></div>
...@@ -139,7 +143,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -139,7 +143,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
<div class="wrapper-unit-id bar-mod-content"> <div class="wrapper-unit-id bar-mod-content">
<h5 class="title">${_("Location ID")}</h5> <h5 class="title">${_("Location ID")}</h5>
<p class="unit-id"> <p class="unit-id">
<span class="unit-id-value" id="unit-location-id-input">${unit.location.name | h}</span> <span class="unit-id-value" id="unit-location-id-input">${unit.location.name}</span>
<span class="tip"><span class="sr">Tip: </span>${_("Use this ID when you create links to this unit from other course content. You enter the ID in the URL field.")}</span> <span class="tip"><span class="sr">Tip: </span>${_("Use this ID when you create links to this unit from other course content. You enter the ID in the URL field.")}</span>
</p> </p>
</div> </div>
......
<%! from openedx.core.djangolib.markup import HTML, ugettext as _ %>
<%page expression_filter="h"/> <%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import Text, HTML
%>
<%inherit file="base.html" /> <%inherit file="base.html" />
...@@ -80,7 +84,7 @@ ...@@ -80,7 +84,7 @@
## Translators: This is an example for the name of the organization sponsoring a course, seen when filling out the form to create a new course. The organization name cannot contain spaces. ## Translators: This is an example for the name of the organization sponsoring a course, seen when filling out the form to create a new course. The organization name cannot contain spaces.
## Translators: "e.g. UniversityX or OrganizationX" is a placeholder displayed when user put no data into this field. ## Translators: "e.g. UniversityX or OrganizationX" is a placeholder displayed when user put no data into this field.
<input class="new-course-org" id="new-course-org" type="text" name="new-course-org" required placeholder="${_('e.g. UniversityX or OrganizationX')}" aria-describedby="tip-new-course-org tip-error-new-course-org" /> <input class="new-course-org" id="new-course-org" type="text" name="new-course-org" required placeholder="${_('e.g. UniversityX or OrganizationX')}" aria-describedby="tip-new-course-org tip-error-new-course-org" />
<span class="tip" id="tip-new-course-org">${_("The name of the organization sponsoring the course. {strong_start}Note: The organization name is part of the course URL.{strong_end} This cannot be changed, but you can set a different display name in Advanced Settings later.").format( <span class="tip" id="tip-new-course-org">${Text(_("The name of the organization sponsoring the course. {strong_start}Note: The organization name is part of the course URL.{strong_end} This cannot be changed, but you can set a different display name in Advanced Settings later.")).format(
strong_start=HTML('<strong>'), strong_start=HTML('<strong>'),
strong_end=HTML('</strong>'), strong_end=HTML('</strong>'),
)}</span> )}</span>
...@@ -93,7 +97,7 @@ ...@@ -93,7 +97,7 @@
## seen when filling out the form to create a new course. The number here is ## seen when filling out the form to create a new course. The number here is
## short for "Computer Science 101". It can contain letters but cannot contain spaces. ## short for "Computer Science 101". It can contain letters but cannot contain spaces.
<input class="new-course-number" id="new-course-number" type="text" name="new-course-number" required placeholder="${_('e.g. CS101')}" aria-describedby="tip-new-course-number tip-error-new-course-number" /> <input class="new-course-number" id="new-course-number" type="text" name="new-course-number" required placeholder="${_('e.g. CS101')}" aria-describedby="tip-new-course-number tip-error-new-course-number" />
<span class="tip" id="tip-new-course-number">${_("The unique number that identifies your course within your organization. {strong_start}Note: This is part of your course URL, so no spaces or special characters are allowed and it cannot be changed.{strong_end}").format( <span class="tip" id="tip-new-course-number">${Text(_("The unique number that identifies your course within your organization. {strong_start}Note: This is part of your course URL, so no spaces or special characters are allowed and it cannot be changed.{strong_end}")).format(
strong_start=HTML('<strong>'), strong_start=HTML('<strong>'),
strong_end=HTML('</strong>'), strong_end=HTML('</strong>'),
)}</span> )}</span>
...@@ -105,7 +109,7 @@ ...@@ -105,7 +109,7 @@
## Translators: This is an example for the "run" used to identify different ## Translators: This is an example for the "run" used to identify different
## instances of a course, seen when filling out the form to create a new course. ## instances of a course, seen when filling out the form to create a new course.
<input class="new-course-run" id="new-course-run" type="text" name="new-course-run" required placeholder="${_('e.g. 2014_T1')}" aria-describedby="tip-new-course-run tip-error-new-course-run" /> <input class="new-course-run" id="new-course-run" type="text" name="new-course-run" required placeholder="${_('e.g. 2014_T1')}" aria-describedby="tip-new-course-run tip-error-new-course-run" />
<span class="tip" id="tip-new-course-run">${_("The term in which your course will run. {strong_start}Note: This is part of your course URL, so no spaces or special characters are allowed and it cannot be changed.{strong_end}").format( <span class="tip" id="tip-new-course-run">${Text(_("The term in which your course will run. {strong_start}Note: This is part of your course URL, so no spaces or special characters are allowed and it cannot be changed.{strong_end}")).format(
strong_start=HTML('<strong>'), strong_start=HTML('<strong>'),
strong_end=HTML('</strong>'), strong_end=HTML('</strong>'),
)}</span> )}</span>
...@@ -165,7 +169,7 @@ ...@@ -165,7 +169,7 @@
## for "Computer Science Problems". The example number may contain letters ## for "Computer Science Problems". The example number may contain letters
## but must not contain spaces. ## but must not contain spaces.
<input class="new-library-number" id="new-library-number" type="text" name="new-library-number" required placeholder="${_('e.g. CSPROB')}" aria-describedby="tip-new-library-number tip-error-new-library-number" /> <input class="new-library-number" id="new-library-number" type="text" name="new-library-number" required placeholder="${_('e.g. CSPROB')}" aria-describedby="tip-new-library-number tip-error-new-library-number" />
<span class="tip" id="tip-new-library-number">${_("The unique code that identifies this library. {strong_start}Note: This is part of your library URL, so no spaces or special characters are allowed.{strong_end} This cannot be changed.").format( <span class="tip" id="tip-new-library-number">${Text(_("The unique code that identifies this library. {strong_start}Note: This is part of your library URL, so no spaces or special characters are allowed.{strong_end} This cannot be changed.")).format(
strong_start=HTML('<strong>'), strong_start=HTML('<strong>'),
strong_end=HTML('</strong>'), strong_end=HTML('</strong>'),
)}</span> )}</span>
...@@ -228,7 +232,7 @@ ...@@ -228,7 +232,7 @@
</div> </div>
<div class="status-message"> <div class="status-message">
<p class="copy">${_('The new course will be added to your course list in 5-10 minutes. Return to this page or {link_start}refresh it{link_end} to update the course list. The new course will need some manual configuration.').format( <p class="copy">${Text(_('The new course will be added to your course list in 5-10 minutes. Return to this page or {link_start}refresh it{link_end} to update the course list. The new course will need some manual configuration.')).format(
link_start=HTML('<a href="#" class="action-reload">'), link_start=HTML('<a href="#" class="action-reload">'),
link_end=HTML('</a>'), link_end=HTML('</a>'),
)}</p> )}</p>
...@@ -575,7 +579,7 @@ ...@@ -575,7 +579,7 @@
% if course_creator_status=='disallowed_for_this_site' and settings.FEATURES.get('STUDIO_REQUEST_EMAIL',''): % if course_creator_status=='disallowed_for_this_site' and settings.FEATURES.get('STUDIO_REQUEST_EMAIL',''):
<div class="bit"> <div class="bit">
<h3 class="title title-3">${_("Can I create courses in {studio_name}?").format(studio_name=settings.STUDIO_NAME)}</h3> <h3 class="title title-3">${_("Can I create courses in {studio_name}?").format(studio_name=settings.STUDIO_NAME)}</h3>
<p>${_("In order to create courses in {studio_name}, you must {link_start}contact {platform_name} staff to help you create a course{link_end}.").format( <p>${Text(_("In order to create courses in {studio_name}, you must {link_start}contact {platform_name} staff to help you create a course{link_end}.")).format(
studio_name=settings.STUDIO_NAME, studio_name=settings.STUDIO_NAME,
platform_name=settings.PLATFORM_NAME, platform_name=settings.PLATFORM_NAME,
link_start=HTML('<a href="mailto:{email}">').format(email=settings.FEATURES.get('STUDIO_REQUEST_EMAIL','')), link_start=HTML('<a href="mailto:{email}">').format(email=settings.FEATURES.get('STUDIO_REQUEST_EMAIL','')),
...@@ -593,7 +597,7 @@ ...@@ -593,7 +597,7 @@
% elif course_creator_status == "denied": % elif course_creator_status == "denied":
<div class="bit"> <div class="bit">
<h3 class="title title-3">${_("Can I create courses in {studio_name}?").format(studio_name=settings.STUDIO_NAME)}</h3> <h3 class="title title-3">${_("Can I create courses in {studio_name}?").format(studio_name=settings.STUDIO_NAME)}</h3>
<p>${_("Your request to author courses in {studio_name} has been denied. Please {link_start}contact {platform_name} Staff with further questions{link_end}.").format( <p>${Text(_("Your request to author courses in {studio_name} has been denied. Please {link_start}contact {platform_name} Staff with further questions{link_end}.")).format(
studio_name=settings.STUDIO_NAME, studio_name=settings.STUDIO_NAME,
platform_name=settings.PLATFORM_NAME, platform_name=settings.PLATFORM_NAME,
link_start=HTML('<a href="mailto:{email}">').format(email=settings.TECH_SUPPORT_EMAIL), link_start=HTML('<a href="mailto:{email}">').format(email=settings.TECH_SUPPORT_EMAIL),
......
<%page expression_filter="h"/>
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%! <%!
from django.utils.translation import ugettext as _
from courseware.courses import get_course_info_section, get_course_date_summary from courseware.courses import get_course_info_section, get_course_date_summary
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from openedx.core.djangolib.markup import HTML, ugettext as _ from openedx.core.djangolib.markup import Text, HTML
%> %>
<%block name="pagetitle">${_("{course_number} Course Info").format(course_number=course.display_number_with_default)}</%block> <%block name="pagetitle">${_("{course_number} Course Info").format(course_number=course.display_number_with_default)}</%block>
...@@ -21,7 +24,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -21,7 +24,7 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
<h2 class="title">${_("You are not enrolled yet")}</h2> <h2 class="title">${_("You are not enrolled yet")}</h2>
<div class="copy"> <div class="copy">
<p class='enroll-message'> <p class='enroll-message'>
${_("You are not currently enrolled in this course. {link_start}Sign up now!{link_end}").format( ${Text(_("You are not currently enrolled in this course. {link_start}Sign up now!{link_end}")).format(
link_start=HTML("<a href={}>").format(url_to_enroll), link_start=HTML("<a href={}>").format(url_to_enroll),
link_end=HTML("</a>") link_end=HTML("</a>")
)} )}
...@@ -54,8 +57,8 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -54,8 +57,8 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
<section class="container"> <section class="container">
<div class="home"> <div class="home">
<div class="page-header-main"> <div class="page-header-main">
<h1 class="page-title">${_("Welcome to {org}'s {course_name}!").format(org=course.display_org_with_default, course_name=course.display_number_with_default) | h}</h1> <h1 class="page-title">${_("Welcome to {org}'s {course_name}!").format(org=course.display_org_with_default, course_name=course.display_number_with_default)}</h1>
<h2 class="page-subtitle">${course.display_name_with_default | h}</h2> <h2 class="page-subtitle">${course.display_name_with_default}</h2>
</div> </div>
% if last_accessed_courseware_url: % if last_accessed_courseware_url:
<div class="page-header-secondary"> <div class="page-header-secondary">
...@@ -75,25 +78,25 @@ from openedx.core.djangolib.markup import HTML, ugettext as _ ...@@ -75,25 +78,25 @@ from openedx.core.djangolib.markup import HTML, ugettext as _
% endif % endif
<h1>${_("Course Updates and News")}</h1> <h1>${_("Course Updates and News")}</h1>
${get_course_info_section(request, masquerade_user, course, 'updates')} ${HTML(get_course_info_section(request, masquerade_user, course, 'updates'))}
</section> </section>
<section aria-label="${_('Handout Navigation')}" class="handouts"> <section aria-label="${_('Handout Navigation')}" class="handouts">
% if SelfPacedConfiguration.current().enable_course_home_improvements: % if SelfPacedConfiguration.current().enable_course_home_improvements:
<h1>${_("Important Course Dates")}</h1> <h1>${_("Important Course Dates")}</h1>
${get_course_date_summary(course, user)} ${HTML(get_course_date_summary(course, user))}
% endif % endif
<h1>${_(course.info_sidebar_name)}</h1> <h1>${_(course.info_sidebar_name)}</h1>
${get_course_info_section(request, masquerade_user, course, 'handouts')} ${HTML(get_course_info_section(request, masquerade_user, course, 'handouts'))}
</section> </section>
% else: % else:
<section class="updates"> <section class="updates">
<h1>${_("Course Updates &amp; News")}</h1> <h1>${_("Course Updates and News")}</h1>
${get_course_info_section(request, masquerade_user, course, 'guest_updates')} ${HTML(get_course_info_section(request, masquerade_user, course, 'guest_updates'))}
</section> </section>
<section aria-label="${_('Handout Navigation')}" class="handouts"> <section aria-label="${_('Handout Navigation')}" class="handouts">
<h1>${_("Course Handouts")}</h1> <h1>${_("Course Handouts")}</h1>
${get_course_info_section(request, masquerade_user, course, 'guest_handouts')} ${HTML(get_course_info_section(request, masquerade_user, course, 'guest_handouts'))}
</section> </section>
% endif % endif
</div> </div>
......
<%! from openedx.core.djangolib.markup import ugettext as _ %> <%! from django.utils.translation import ugettext as _ %>
<%page expression_filter="h"/> <%page expression_filter="h"/>
% for course_msg in course_enrollment_messages: % for course_msg in course_enrollment_messages:
<div class="wrapper-msg urgency-high"> <div class="wrapper-msg urgency-high">
......
...@@ -2,48 +2,31 @@ ...@@ -2,48 +2,31 @@
Utilities for use in Mako markup. Utilities for use in Mako markup.
""" """
from django.utils.translation import ugettext as django_ugettext
from django.utils.translation import ungettext as django_ungettext
import markupsafe import markupsafe
# So that we can use escape() imported from here. # Text() can be used to declare a string as plain text, as HTML() is used
escape = markupsafe.escape # pylint: disable=invalid-name # for HTML. It simply wraps markupsafe's escape, which will HTML-escape if
# it isn't already escaped.
Text = markupsafe.escape # pylint: disable=invalid-name
def ugettext(text): def HTML(html): # pylint: disable=invalid-name
"""Translate a string, and escape it as plain text.
Use like this in Mako::
<% from openedx.core.djangolib.markup import ugettext as _ %>
<p>${_("Hello, world!")}</p>
Or with formatting::
<% from openedx.core.djangolib.markup import HTML, ugettext as _ %>
${_("Write & send {start}email{end}").format(
start=HTML("<a href='mailto:ned@edx.org'>"),
end=HTML("</a>"),
)}
""" """
return markupsafe.escape(django_ugettext(text)) Mark a string as already HTML, so that it won't be escaped before output.
def ungettext(text1, text2, num): Use this function when formatting HTML into other strings. It must be
"""Translate a number-sensitive string, and escape it as plain text.""" used in conjunction with ``Text()``, and both ``HTML()`` and ``Text()``
return markupsafe.escape(django_ungettext(text1, text2, num)) must be closed before any calls to ``format()``::
def HTML(html): # pylint: disable=invalid-name
"""Mark a string as already HTML, so that it won't be escaped before output.
Use this when formatting HTML into other strings:: <%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
<% from openedx.core.djangolib.markup import HTML, ugettext as _ %> from openedx.core.djangolib.markup import Text, HTML
${_("Write & send {start}email{end}").format( %>
start=HTML("<a href='mailto:ned@edx.org'>"), ${Text(_("Write & send {start}email{end}")).format(
start=HTML("<a href='mailto:{}'>".format(user.email),
end=HTML("</a>"), end=HTML("</a>"),
)} )}
......
...@@ -6,9 +6,10 @@ Tests for openedx.core.djangolib.markup ...@@ -6,9 +6,10 @@ Tests for openedx.core.djangolib.markup
import unittest import unittest
import ddt import ddt
from django.utils.translation import ugettext as _, ungettext
from mako.template import Template from mako.template import Template
from openedx.core.djangolib.markup import escape, HTML, ugettext as _, ungettext from openedx.core.djangolib.markup import Text, HTML
@ddt.ddt @ddt.ddt
...@@ -24,12 +25,12 @@ class FormatHtmlTest(unittest.TestCase): ...@@ -24,12 +25,12 @@ class FormatHtmlTest(unittest.TestCase):
(u"<a>нтмℓ-єѕ¢αρє∂</a>", u"&lt;a&gt;нтмℓ-єѕ¢αρє∂&lt;/a&gt;"), (u"<a>нтмℓ-єѕ¢αρє∂</a>", u"&lt;a&gt;нтмℓ-єѕ¢αρє∂&lt;/a&gt;"),
) )
def test_simple(self, (before, after)): def test_simple(self, (before, after)):
self.assertEqual(unicode(_(before)), after) # pylint: disable=translation-of-non-string self.assertEqual(unicode(Text(_(before))), after) # pylint: disable=translation-of-non-string
self.assertEqual(unicode(escape(before)), after) self.assertEqual(unicode(Text(before)), after)
def test_formatting(self): def test_formatting(self):
# The whole point of this function is to make sure this works: # The whole point of this function is to make sure this works:
out = _(u"Point & click {start}here{end}!").format( out = Text(_(u"Point & click {start}here{end}!")).format(
start=HTML("<a href='http://edx.org'>"), start=HTML("<a href='http://edx.org'>"),
end=HTML("</a>"), end=HTML("</a>"),
) )
...@@ -41,7 +42,7 @@ class FormatHtmlTest(unittest.TestCase): ...@@ -41,7 +42,7 @@ class FormatHtmlTest(unittest.TestCase):
def test_nested_formatting(self): def test_nested_formatting(self):
# Sometimes, you have plain text, with html inserted, and the html has # Sometimes, you have plain text, with html inserted, and the html has
# plain text inserted. It gets twisty... # plain text inserted. It gets twisty...
out = _(u"Send {start}email{end}").format( out = Text(_(u"Send {start}email{end}")).format(
start=HTML("<a href='mailto:{email}'>").format(email="A&B"), start=HTML("<a href='mailto:{email}'>").format(email="A&B"),
end=HTML("</a>"), end=HTML("</a>"),
) )
...@@ -54,8 +55,12 @@ class FormatHtmlTest(unittest.TestCase): ...@@ -54,8 +55,12 @@ class FormatHtmlTest(unittest.TestCase):
# The default_filters used here have to match the ones in edxmako. # The default_filters used here have to match the ones in edxmako.
template = Template( template = Template(
""" """
<%! from openedx.core.djangolib.markup import HTML, ugettext as _ %> <%!
${_(u"A & {BC}").format(BC=HTML("B & C"))} from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import Text, HTML
%>
${Text(_(u"A & {BC}")).format(BC=HTML("B & C"))}
""", """,
default_filters=['decode.utf8', 'h'], default_filters=['decode.utf8', 'h'],
) )
...@@ -64,5 +69,5 @@ class FormatHtmlTest(unittest.TestCase): ...@@ -64,5 +69,5 @@ class FormatHtmlTest(unittest.TestCase):
def test_ungettext(self): def test_ungettext(self):
for i in [1, 2]: for i in [1, 2]:
out = ungettext("1 & {}", "2 & {}", i).format(HTML("<>")) out = Text(ungettext("1 & {}", "2 & {}", i)).format(HTML("<>"))
self.assertEqual(out, "{} &amp; <>".format(i)) self.assertEqual(out, "{} &amp; <>".format(i))
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