Skip to content

Commit

Permalink
Fixes issue #61: "Renderer class should handle load_template not retu…
Browse files Browse the repository at this point in the history
…rning unicode"
  • Loading branch information
cjerdonek committed Dec 22, 2011
1 parent cb7383e commit d5cee63
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 16 deletions.
12 changes: 8 additions & 4 deletions pystache/renderengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,14 @@ class RenderEngine(object):

modifiers = Modifiers()

def __init__(self, load_template=None, literal=None, escape=None):
def __init__(self, load_partial=None, literal=None, escape=None):
"""
Arguments:
load_partial: a function for loading templates by name when
loading partials. The function should accept a template name
and return a unicode template string.
escape: a function that takes a unicode or str string,
converts it to unicode, and escapes and returns it.
Expand All @@ -68,7 +72,7 @@ def __init__(self, load_template=None, literal=None, escape=None):
"""
self.escape = escape
self.literal = literal
self.load_template = load_template
self.load_partial = load_partial

def render(self, template, context):
"""
Expand Down Expand Up @@ -178,7 +182,7 @@ def _render_comment(self, tag_name):

@modifiers.set('>')
def _render_partial(self, template_name):
markup = self.load_template(template_name)
markup = self.load_partial(template_name)
return self._render(markup)

@modifiers.set('=')
Expand All @@ -194,7 +198,7 @@ def _change_delimiter(self, tag_name):

@modifiers.set('{')
@modifiers.set('&')
def render_unescaped(self, tag_name):
def _render_unescaped(self, tag_name):
"""
Render a tag without escaping it.
Expand Down
7 changes: 6 additions & 1 deletion pystache/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,12 @@ def _make_render_engine(self):
Return a RenderEngine instance for rendering.
"""
engine = RenderEngine(load_template=self.load_template,
# Make sure the return value of load_template is unicode.
def load_partial(name):
template = self.load_template(name)
return self.unicode(template)

engine = RenderEngine(load_partial=load_partial,
literal=self.literal,
escape=self._unicode_and_escape)
return engine
Expand Down
13 changes: 6 additions & 7 deletions tests/test_renderengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,20 @@ def _engine(self):
Create and return a default RenderEngine for testing.
"""
load_template = None
to_unicode = unicode

escape = lambda s: cgi.escape(to_unicode(s))
literal = to_unicode

engine = RenderEngine(literal=literal, escape=escape, load_template=None)
engine = RenderEngine(literal=literal, escape=escape, load_partial=None)
return engine

def _assert_render(self, expected, template, *context, **kwargs):
partials = kwargs.get('partials')
engine = kwargs.get('engine', self._engine())

if partials is not None:
engine.load_template = lambda key: partials[key]
engine.load_partial = lambda key: partials[key]

context = Context(*context)

Expand All @@ -49,23 +48,23 @@ def test_init(self):
"""
# In real-life, these arguments would be functions
engine = RenderEngine(load_template="load_template", literal="literal", escape="escape")
engine = RenderEngine(load_partial="foo", literal="literal", escape="escape")

self.assertEquals(engine.load_partial, "foo")
self.assertEquals(engine.escape, "escape")
self.assertEquals(engine.literal, "literal")
self.assertEquals(engine.load_template, "load_template")

def test_render(self):
self._assert_render('Hi Mom', 'Hi {{person}}', {'person': 'Mom'})

def test_render__load_template(self):
def test_render__load_partial(self):
"""
Test that render() uses the load_template attribute.
"""
engine = self._engine()
partials = {'partial': "{{person}}"}
engine.load_template = lambda key: partials[key]
engine.load_partial = lambda key: partials[key]
self._assert_render('Hi Mom', 'Hi {{>partial}}', {'person': 'Mom'}, engine=engine)

def test_render__literal(self):
Expand Down
11 changes: 7 additions & 4 deletions tests/test_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,16 +244,19 @@ def test_render__nonascii_template(self):
# correctly, we no longer need to test the rendering code paths through
# the Renderer. We can test rendering paths through only the RenderEngine
# for the same amount of code coverage.
def test_make_render_engine__load_template(self):
def test_make_render_engine__load_partial(self):
"""
Test that _make_render_engine() passes the right load_template.
Test that _make_render_engine() constructs and passes load_partial correctly.
"""
renderer = Renderer()
renderer.load_template = "foo" # in real life, this would be a function.
renderer.unicode = lambda s: s.upper() # a test version.
# In real-life, the partial would be different with each name.
renderer.load_template = lambda name: "partial"

engine = renderer._make_render_engine()
self.assertEquals(engine.load_template, "foo")
# Make sure it calls unicode.
self.assertEquals(engine.load_partial('name'), "PARTIAL")

def test_make_render_engine__literal(self):
"""
Expand Down

0 comments on commit d5cee63

Please sign in to comment.