Merge pull request #10983 from edx/diana/markup-helpers
Add new i18n markupsafe helper methods.
This commit is contained in:
51
common/djangoapps/util/markup.py
Normal file
51
common/djangoapps/util/markup.py
Normal file
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
# So that we can use escape() imported from here.
|
||||
escape = markupsafe.escape # pylint: disable=invalid-name
|
||||
|
||||
|
||||
def ugettext(text):
|
||||
"""Translate a string, and escape it as plain text.
|
||||
|
||||
Use like this in Mako::
|
||||
|
||||
<% from util.markup import ugettext as _ %>
|
||||
<p>${_("Hello, world!")}</p>
|
||||
|
||||
Or with formatting::
|
||||
|
||||
<% from util.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))
|
||||
|
||||
|
||||
def ungettext(text1, text2, num):
|
||||
"""Translate a number-sensitive string, and escape it as plain text."""
|
||||
return markupsafe.escape(django_ungettext(text1, text2, num))
|
||||
|
||||
|
||||
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::
|
||||
|
||||
<% from util.markup import HTML, ugettext as _ %>
|
||||
${_("Write & send {start}email{end}").format(
|
||||
start=HTML("<a href='mailto:ned@edx.org'>"),
|
||||
end=HTML("</a>"),
|
||||
)}
|
||||
|
||||
"""
|
||||
return markupsafe.Markup(html)
|
||||
68
common/djangoapps/util/tests/test_markup.py
Normal file
68
common/djangoapps/util/tests/test_markup.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tests for util.markup
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
import ddt
|
||||
|
||||
from edxmako.template import Template
|
||||
from util.markup import escape, HTML, ugettext as _, ungettext
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class FormatHtmlTest(unittest.TestCase):
|
||||
"""Test that we can format plain strings and HTML into them properly."""
|
||||
|
||||
@ddt.data(
|
||||
(u"hello", u"hello"),
|
||||
(u"<hello>", u"<hello>"),
|
||||
(u"It's cool", u"It's cool"),
|
||||
(u'"cool," she said.', u'"cool," she said.'),
|
||||
(u"Stop & Shop", u"Stop & Shop"),
|
||||
(u"<a>нтмℓ-єѕ¢αρє∂</a>", u"<a>нтмℓ-єѕ¢αρє∂</a>"),
|
||||
)
|
||||
def test_simple(self, (before, after)):
|
||||
self.assertEqual(unicode(_(before)), after) # pylint: disable=translation-of-non-string
|
||||
self.assertEqual(unicode(escape(before)), after)
|
||||
|
||||
def test_formatting(self):
|
||||
# The whole point of this function is to make sure this works:
|
||||
out = _(u"Point & click {start}here{end}!").format(
|
||||
start=HTML("<a href='http://edx.org'>"),
|
||||
end=HTML("</a>"),
|
||||
)
|
||||
self.assertEqual(
|
||||
unicode(out),
|
||||
u"Point & click <a href='http://edx.org'>here</a>!",
|
||||
)
|
||||
|
||||
def test_nested_formatting(self):
|
||||
# Sometimes, you have plain text, with html inserted, and the html has
|
||||
# plain text inserted. It gets twisty...
|
||||
out = _(u"Send {start}email{end}").format(
|
||||
start=HTML("<a href='mailto:{email}'>").format(email="A&B"),
|
||||
end=HTML("</a>"),
|
||||
)
|
||||
self.assertEqual(
|
||||
unicode(out),
|
||||
u"Send <a href='mailto:A&B'>email</a>",
|
||||
)
|
||||
|
||||
def test_mako(self):
|
||||
# The default_filters used here have to match the ones in edxmako.
|
||||
template = Template(
|
||||
"""
|
||||
<%! from util.markup import HTML, ugettext as _ %>
|
||||
${_(u"A & {BC}").format(BC=HTML("B & C"))}
|
||||
""",
|
||||
default_filters=['decode.utf8', 'h'],
|
||||
)
|
||||
out = template.render({})
|
||||
self.assertEqual(out.strip(), u"A & B & C")
|
||||
|
||||
def test_ungettext(self):
|
||||
for i in [1, 2]:
|
||||
out = ungettext("1 & {}", "2 & {}", i).format(HTML("<>"))
|
||||
self.assertEqual(out, "{} & <>".format(i))
|
||||
Reference in New Issue
Block a user