diff --git a/HISTORY.rst b/HISTORY.rst index 533211bc..74061a67 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,7 @@ History Next Release (version TBD) -------------------------- +* Feature: Template and View support disabling HTML escape. [cjerdonek] * Bugfix: context values no longer processed as template strings. [jakearchibald] * API change: pass the context to render to Template.render() instead of Template.__init__(). [cjerdonek] diff --git a/pystache/template.py b/pystache/template.py index 6b87d076..7a2bc8bf 100644 --- a/pystache/template.py +++ b/pystache/template.py @@ -62,7 +62,8 @@ class Template(object): modifiers = Modifiers() - def __init__(self, template=None, load_template=None, output_encoding=None): + def __init__(self, template=None, load_template=None, output_encoding=None, + disable_escape=False): """ Construct a Template instance. @@ -85,12 +86,19 @@ def __init__(self, template=None, load_template=None, output_encoding=None): loader = Loader() load_template = loader.load_template + self.disable_escape = disable_escape self.load_template = load_template self.output_encoding = output_encoding self.template = template self._compile_regexps() + def escape(self, text): + return escape(text) + + def literal(self, text): + return literal(text) + def _initialize_context(self, context, **kwargs): """ Initialize the context attribute. @@ -206,7 +214,7 @@ def _render_tags(self, template): def _render_dictionary(self, template, context): self.context.push(context) - template = Template(template, load_template=self.load_template) + template = Template(template, load_template=self.load_template, disable_escape=self.disable_escape) out = template.render(self.context) self.context.pop() @@ -236,7 +244,7 @@ def _render_tag(self, tag_name): else: return '' - return escape(raw) + return self._render_value(raw) @modifiers.set('!') def _render_comment(self, tag_name): @@ -245,7 +253,7 @@ def _render_comment(self, tag_name): @modifiers.set('>') def _render_partial(self, template_name): markup = self.load_template(template_name) - template = Template(markup, load_template=self.load_template) + template = Template(markup, load_template=self.load_template, disable_escape=self.disable_escape) return template.render(self.context) @modifiers.set('=') @@ -286,6 +294,8 @@ def render(self, context=None, **kwargs): """ self._initialize_context(context, **kwargs) + self._render_value = self.literal if self.disable_escape else self.escape + result = self._render(self.template) if self.output_encoding is not None: diff --git a/pystache/view.py b/pystache/view.py index 11570697..897444c0 100644 --- a/pystache/view.py +++ b/pystache/view.py @@ -88,12 +88,13 @@ def repl(match): return re.sub('[A-Z]', repl, template_name)[1:] - def render(self, encoding=None): + def render(self, encoding=None, disable_escape=False): """ Return the view rendered using the current context. """ - template = Template(self.get_template(), self.load_template, output_encoding=encoding) + template = Template(self.get_template(), self.load_template, output_encoding=encoding, + disable_escape=disable_escape) return template.render(self.context) def get(self, key, default=None): diff --git a/tests/test_examples.py b/tests/test_examples.py index 63267cc9..20abe882 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -34,6 +34,9 @@ def test_unicode_input(self): def test_escaped(self): self.assertEquals(Escaped().render(), "