From f123343cec7afcb22a6227f68229eac57f56ebea Mon Sep 17 00:00:00 2001 From: Eric Naeseth Date: Sat, 16 Jan 2010 16:35:50 -0600 Subject: [PATCH] Adding support for Unicode and non-ASCII-encoded bytestring output. --- examples/unicode_output.mustache | 1 + examples/unicode_output.py | 9 +++++++++ pystache/template.py | 9 ++++++--- pystache/view.py | 4 ++-- tests/test_examples.py | 9 +++++++++ tests/test_pystache.py | 8 ++++++++ 6 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 examples/unicode_output.mustache create mode 100644 examples/unicode_output.py diff --git a/examples/unicode_output.mustache b/examples/unicode_output.mustache new file mode 100644 index 00000000..8495f561 --- /dev/null +++ b/examples/unicode_output.mustache @@ -0,0 +1 @@ +

Name: {{name}}

\ No newline at end of file diff --git a/examples/unicode_output.py b/examples/unicode_output.py new file mode 100644 index 00000000..3cb92609 --- /dev/null +++ b/examples/unicode_output.py @@ -0,0 +1,9 @@ +# encoding: utf-8 + +import pystache + +class UnicodeOutput(pystache.View): + template_path = 'examples' + + def name(self): + return u'Henri Poincaré' diff --git a/pystache/template.py b/pystache/template.py index 5ab0d091..787304d0 100644 --- a/pystache/template.py +++ b/pystache/template.py @@ -34,13 +34,16 @@ def __init__(self, template, context=None): self.context = context or {} self.compile_regexps() - def render(self, template=None, context=None): + def render(self, template=None, context=None, encoding=None): """Turns a Mustache template into something wonderful.""" template = template or self.template context = context or self.context template = self.render_sections(template, context) - return self.render_tags(template, context) + result = self.render_tags(template, context) + if encoding is not None: + result = result.encode(encoding) + return result def compile_regexps(self): """Compiles our section and tag regular expressions.""" @@ -94,7 +97,7 @@ def render_tags(self, template, context): @modifier(None) def render_tag(self, tag_name, context): """Given a tag name and context, finds, escapes, and renders the tag.""" - return cgi.escape(str(context.get(tag_name, '') or '')) + return cgi.escape(unicode(context.get(tag_name, '') or '')) @modifier('!') def render_comment(self, tag_name=None, context=None): diff --git a/pystache/view.py b/pystache/view.py index e8a4f7a2..bbed2856 100644 --- a/pystache/view.py +++ b/pystache/view.py @@ -83,9 +83,9 @@ def get(self, attr, default): else: return attr - def render(self): + def render(self, encoding=None): template = self.load_template() - return Template(template, self).render() + return Template(template, self).render(encoding=encoding) def __str__(self): return self.render() diff --git a/tests/test_examples.py b/tests/test_examples.py index 4f64fac4..e073efbd 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1,3 +1,5 @@ +# encoding: utf-8 + import unittest import pystache @@ -7,6 +9,7 @@ from examples.unescaped import Unescaped from examples.template_partial import TemplatePartial from examples.delimiters import Delimiters +from examples.unicode_output import UnicodeOutput class TestView(unittest.TestCase): def test_comments(self): @@ -18,6 +21,12 @@ def test_double_section(self): * second * third""") + def test_unicode_output(self): + self.assertEquals(UnicodeOutput().render(), u'

Name: Henri Poincaré

') + + def test_encoded_output(self): + self.assertEquals(UnicodeOutput().render('utf8'), '

Name: Henri Poincar\xc3\xa9

') + def test_escaped(self): self.assertEquals(Escaped().render(), "

Bear > Shark

") diff --git a/tests/test_pystache.py b/tests/test_pystache.py index c6f01222..42981802 100644 --- a/tests/test_pystache.py +++ b/tests/test_pystache.py @@ -1,3 +1,5 @@ +# encoding: utf-8 + import unittest import pystache @@ -49,6 +51,12 @@ def test_non_strings(self): ret = pystache.render(template, { 'stats': stats }) self.assertEquals(ret, """(123 & ['something'])(chris & 0.9)""") + def test_unicode(self): + template = 'Name: {{name}}; Age: {{age}}' + ret = pystache.render(template, { 'name': u'Henri Poincaré', + 'age': 156 }) + self.assertEquals(ret, u'Name: Henri Poincaré; Age: 156') + def test_sections(self): template = """