From b001ae77a4d47fdbc9f1e062c244b777d2680204 Mon Sep 17 00:00:00 2001 From: Chris Jerdonek Date: Fri, 4 May 2012 17:09:52 -0700 Subject: Shared code between RenderEngine's _make_get_section() and _get_string_value(). --- pystache/renderengine.py | 34 +++++++++++++++++++--------------- pystache/tests/test_renderengine.py | 16 ++++++++++++---- 2 files changed, 31 insertions(+), 19 deletions(-) (limited to 'pystache') diff --git a/pystache/renderengine.py b/pystache/renderengine.py index 394c22b..d2bd63c 100644 --- a/pystache/renderengine.py +++ b/pystache/renderengine.py @@ -93,13 +93,7 @@ class RenderEngine(object): # and invoked as such. The returned value MUST be # rendered against the default delimiters, then # interpolated in place of the lambda. - template = val() - if not isinstance(template, basestring): - # In case the template is an integer, for example. - template = str(template) - if type(template) is not unicode: - template = self.literal(template) - val = self._render(template, context) + val = self._render_value(val(), context) if not isinstance(val, basestring): val = str(val) @@ -202,8 +196,8 @@ class RenderEngine(object): # Otherwise, treat the value as a list. parts = [] - for element in data: - if callable(element): + for val in data: + if callable(val): # Lambdas special case section rendering and bypass pushing # the data value onto the context stack. From the spec-- # @@ -219,14 +213,12 @@ class RenderEngine(object): # https://github.com/defunkt/pystache/issues/113 # # TODO: should we check the arity? - new_template = element(template[section_start_index:section_end_index]) - # Make sure we are dealing with a unicode template string. - new_template = self.literal(new_template) - rendered = self._render(new_template, context, delimiters=delims) - parts.append(rendered) + val = val(template[section_start_index:section_end_index]) + val = self._render_value(val, context, delimiters=delims) + parts.append(val) continue - context.push(element) + context.push(val) parts.append(parsed_template.render(context)) context.pop() @@ -248,6 +240,18 @@ class RenderEngine(object): return parser.parse(template=template) + def _render_value(self, val, context, delimiters=None): + """ + Render an arbitrary value. + + """ + if not isinstance(val, basestring): + # In case the template is an integer, for example. + val = str(val) + if type(val) is not unicode: + val = self.literal(val) + return self._render(val, context, delimiters) + def _render(self, template, context, delimiters=None): """ Returns: a string of type unicode. diff --git a/pystache/tests/test_renderengine.py b/pystache/tests/test_renderengine.py index 1e83792..4e934b1 100644 --- a/pystache/tests/test_renderengine.py +++ b/pystache/tests/test_renderengine.py @@ -11,6 +11,7 @@ import unittest from pystache.context import ContextStack, KeyNotFoundError from pystache import defaults from pystache.parser import ParsingError +from pystache.renderer import Renderer from pystache.renderengine import context_get, RenderEngine from pystache.tests.common import AssertStringMixin, AssertExceptionMixin, Attachable @@ -77,11 +78,9 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin): Create and return a default RenderEngine for testing. """ - escape = defaults.TAG_ESCAPE + renderer = Renderer(string_encoding='utf-8', missing_tags='strict') + engine = renderer._make_render_engine() - engine = RenderEngine(literal=unicode, escape=escape, - resolve_context=context_get, - resolve_partial=None) return engine def _assert_render(self, expected, template, *context, **kwargs): @@ -490,6 +489,15 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin): context = {'lambda': lambda text: u'abcdé'.encode('utf-8')} self._assert_render(u'abcdé', template, context, engine=engine) + def test_section__lambda__returning_nonstring(self): + """ + Test a lambda section value returning a non-string. + + """ + template = '{{#lambda}}foo{{/lambda}}' + context = {'lambda': lambda text: len(text)} + self._assert_render(u'3', template, context) + def test_section__iterable(self): """ Check that objects supporting iteration (aside from dicts) behave like lists. -- cgit v1.2.1