Commit b445ee65 by Chris Jerdonek

More to finish issue #55.

parent 3dd53c1a
......@@ -128,9 +128,12 @@ class Template(object):
def _unicode_and_escape(self, s):
if not isinstance(s, unicode):
s = unicode(s)
s = self.unicode(s)
return self.escape(s)
def unicode(self, s):
return unicode(s, self.default_encoding, self.decode_errors)
def escape(self, u):
"""
Escape a unicode string, and return it.
......@@ -142,7 +145,6 @@ class Template(object):
"""
pass
def literal(self, s):
"""
Convert the given string to a unicode string, without escaping it.
......@@ -154,7 +156,7 @@ class Template(object):
markupsafe.Markup (which subclasses unicode).
"""
return self._literal(s, self.default_encoding, self.decode_errors)
return self._literal(self.unicode(s))
def _initialize_context(self, context, **kwargs):
"""
......@@ -174,7 +176,6 @@ class Template(object):
self.context = context
def _compile_regexps(self):
"""
Compile and set the regular expression attributes.
......@@ -271,7 +272,8 @@ class Template(object):
def _render_dictionary(self, template, context):
self.context.push(context)
template = Template(template, load_template=self.load_template, escape=self.escape)
template = Template(template, load_template=self.load_template, escape=self.escape,
default_encoding=self.default_encoding, decode_errors=self.decode_errors)
out = template.render(self.context)
self.context.pop()
......@@ -287,6 +289,10 @@ class Template(object):
@modifiers.set(None)
def _render_tag(self, tag_name):
"""
Return the value of a variable as an escaped unicode string.
"""
raw = self.context.get(tag_name, '')
# For methods with no return value
......@@ -301,6 +307,14 @@ class Template(object):
else:
return ''
# If we don't first convert to a string type, the call to self._unicode_and_escape()
# will yield an error like the following:
#
# TypeError: coercing to Unicode: need string or buffer, ... found
#
if not isinstance(raw, basestring):
raw = str(raw)
return self._unicode_and_escape(raw)
@modifiers.set('!')
......@@ -310,7 +324,8 @@ class Template(object):
@modifiers.set('>')
def _render_partial(self, template_name):
markup = self.load_template(template_name)
template = Template(markup, load_template=self.load_template, escape=self.escape)
template = Template(markup, load_template=self.load_template, escape=self.escape,
default_encoding=self.default_encoding, decode_errors=self.decode_errors)
return template.render(self.context)
@modifiers.set('=')
......
......@@ -88,35 +88,33 @@ class TemplateTestCase(unittest.TestCase):
template = Template(decode_errors="foo")
self.assertEquals(template.decode_errors, "foo")
def test_literal(self):
def test_unicode(self):
template = Template()
actual = template.literal("abc")
self.assertEquals(actual, "abc")
self.assertEquals(type(actual), unicode)
def test_literal__default_encoding(self):
def test_unicode__default_encoding(self):
template = Template()
template.default_encoding = "utf-8"
actual = template.literal("é")
self.assertEquals(actual, u"é")
s = "é"
def test_literal__default_encoding__error(self):
template = Template()
template.default_encoding = "ascii"
self.assertRaises(UnicodeDecodeError, template.literal, "é")
self.assertRaises(UnicodeDecodeError, template.unicode, s)
template.default_encoding = "utf-8"
self.assertEquals(template.unicode(s), u"é")
def test_literal__decode_errors(self):
def test_unicode__decode_errors(self):
template = Template()
template.default_encoding = "ascii"
s = "é"
template.default_encoding = "ascii"
template.decode_errors = "strict"
self.assertRaises(UnicodeDecodeError, template.literal, s)
self.assertRaises(UnicodeDecodeError, template.unicode, s)
template.decode_errors = "replace"
actual = template.literal(s)
# U+FFFD is the official Unicode replacement character.
self.assertEquals(actual, u'\ufffd\ufffd')
self.assertEquals(template.unicode(s), u'\ufffd\ufffd')
def test_literal__with_markupsafe(self):
if not self._was_markupsafe_imported():
......@@ -295,3 +293,37 @@ class TemplateTestCase(unittest.TestCase):
template = Template("{{#list}}{{name}}: {{greeting}}; {{/list}}")
self.assertEquals(template.render(context), "Al: Hi; Bo: Hi; ")
def test_render__encoding_in_context_value(self):
template = Template('{{test}}')
context = {'test': "déf"}
template.decode_errors = 'ignore'
template.default_encoding = 'ascii'
self.assertEquals(template.render(context), "df")
template.default_encoding = 'utf_8'
self.assertEquals(template.render(context), u"déf")
def test_render__encoding_in_section_context_value(self):
template = Template('{{#test}}{{foo}}{{/test}}')
context = {'test': {'foo': "déf"}}
template.decode_errors = 'ignore'
template.default_encoding = 'ascii'
self.assertEquals(template.render(context), "df")
template.default_encoding = 'utf_8'
self.assertEquals(template.render(context), u"déf")
def test_render__encoding_in_partial_context_value(self):
load_template = lambda x: "{{foo}}"
template = Template('{{>partial}}', load_template=load_template)
context = {'foo': "déf"}
template.decode_errors = 'ignore'
template.default_encoding = 'ascii'
self.assertEquals(template.render(context), "df")
template.default_encoding = 'utf_8'
self.assertEquals(template.render(context), u"déf")
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