Commit 1cb0d1f5 by Chris Jerdonek

Completed issue #52: "Remove the context parameter from Template.__init__()"

parent 5302934d
...@@ -3,6 +3,8 @@ History ...@@ -3,6 +3,8 @@ History
Next Release (version TBD) Next Release (version TBD)
-------------------------- --------------------------
* API change: pass the context to render to Template.render() instead of
Template.__init__(). [cjerdonek]
* Bugfix: Passing **kwargs to Template() modified the context. [cjerdonek] * Bugfix: Passing **kwargs to Template() modified the context. [cjerdonek]
* Bugfix: Passing **kwargs to Template() with no context raised an * Bugfix: Passing **kwargs to Template() with no context raised an
exception. [cjerdonek] exception. [cjerdonek]
......
...@@ -64,7 +64,8 @@ def main(sys_argv): ...@@ -64,7 +64,8 @@ def main(sys_argv):
except IOError: except IOError:
context = json.loads(context) context = json.loads(context)
print(Template(template, context).render()) template = Template(template)
print(template.render(context))
if __name__=='__main__': if __name__=='__main__':
......
...@@ -18,4 +18,5 @@ def render(template, context=None, **kwargs): ...@@ -18,4 +18,5 @@ def render(template, context=None, **kwargs):
Return the given template string rendered using the given context. Return the given template string rendered using the given context.
""" """
return Template(template, context, **kwargs).render() template = Template(template)
return template.render(context, **kwargs)
...@@ -62,7 +62,7 @@ class Template(object): ...@@ -62,7 +62,7 @@ class Template(object):
modifiers = Modifiers() modifiers = Modifiers()
def __init__(self, template=None, context=None, load_template=None, output_encoding=None, **kwargs): def __init__(self, template=None, load_template=None, output_encoding=None):
""" """
Construct a Template instance. Construct a Template instance.
...@@ -83,13 +83,23 @@ class Template(object): ...@@ -83,13 +83,23 @@ class Template(object):
information. information.
""" """
if context is None:
context = {}
if load_template is None: if load_template is None:
loader = Loader() loader = Loader()
load_template = loader.load_template load_template = loader.load_template
load_template = getattr(context, 'load_template', load_template)
self.load_template = load_template
self.output_encoding = output_encoding
self.template = template
self._compile_regexps()
def _initialize_context(self, context, **kwargs):
"""
Initialize the context attribute.
"""
if context is None:
context = {}
if isinstance(context, Context): if isinstance(context, Context):
context = context.copy() context = context.copy()
...@@ -100,11 +110,7 @@ class Template(object): ...@@ -100,11 +110,7 @@ class Template(object):
context.push(kwargs) context.push(kwargs)
self.context = context self.context = context
self.load_template = load_template
self.output_encoding = output_encoding
self.template = template
self._compile_regexps()
def _compile_regexps(self): def _compile_regexps(self):
""" """
...@@ -181,8 +187,8 @@ class Template(object): ...@@ -181,8 +187,8 @@ class Template(object):
def _render_dictionary(self, template, context): def _render_dictionary(self, template, context):
self.context.push(context) self.context.push(context)
template = Template(template, self.context, self.load_template) template = Template(template, load_template=self.load_template)
out = template.render() out = template.render(self.context)
self.context.pop() self.context.pop()
...@@ -220,8 +226,8 @@ class Template(object): ...@@ -220,8 +226,8 @@ class Template(object):
@modifiers.set('>') @modifiers.set('>')
def _render_partial(self, template_name): def _render_partial(self, template_name):
markup = self.load_template(template_name) markup = self.load_template(template_name)
template = Template(markup, self.context, self.load_template) template = Template(markup, load_template=self.load_template)
return template.render() return template.render(self.context)
@modifiers.set('=') @modifiers.set('=')
def _change_delimiter(self, tag_name): def _change_delimiter(self, tag_name):
...@@ -243,7 +249,7 @@ class Template(object): ...@@ -243,7 +249,7 @@ class Template(object):
""" """
return literal(self.context.get(tag_name, '')) return literal(self.context.get(tag_name, ''))
def render(self): def render(self, context=None, **kwargs):
""" """
Return the template rendered using the current context. Return the template rendered using the current context.
...@@ -252,6 +258,8 @@ class Template(object): ...@@ -252,6 +258,8 @@ class Template(object):
and is encoded using that encoding. and is encoded using that encoding.
""" """
self._initialize_context(context, **kwargs)
template = self._render_sections(self.template) template = self._render_sections(self.template)
result = self._render_tags(template) result = self._render_tags(template)
......
...@@ -93,8 +93,8 @@ class View(object): ...@@ -93,8 +93,8 @@ class View(object):
Return the view rendered using the current context. Return the view rendered using the current context.
""" """
template = Template(self.get_template(), self.context, self.load_template, output_encoding=encoding) template = Template(self.get_template(), self.load_template, output_encoding=encoding)
return template.render() return template.render(self.context)
def get(self, key, default=None): def get(self, key, default=None):
return self.context.get(key, default) return self.context.get(key, default)
......
import unittest import unittest
import pystache import pystache
from pystache import Template
from examples.nested_context import NestedContext from examples.nested_context import NestedContext
from examples.complex_view import ComplexView from examples.complex_view import ComplexView
from examples.lambdas import Lambdas from examples.lambdas import Lambdas
...@@ -8,16 +9,15 @@ from examples.simple import Simple ...@@ -8,16 +9,15 @@ from examples.simple import Simple
class TestSimple(unittest.TestCase): class TestSimple(unittest.TestCase):
def test_simple_render(self):
self.assertEqual('herp', pystache.Template('{{derp}}', {'derp': 'herp'}).render())
def test_nested_context(self): def test_nested_context(self):
view = NestedContext() view = NestedContext()
self.assertEquals(pystache.Template('{{#foo}}{{thing1}} and {{thing2}} and {{outer_thing}}{{/foo}}{{^foo}}Not foo!{{/foo}}', view).render(), "one and foo and two") view.template = '{{#foo}}{{thing1}} and {{thing2}} and {{outer_thing}}{{/foo}}{{^foo}}Not foo!{{/foo}}'
self.assertEquals(view.render(), "one and foo and two")
def test_looping_and_negation_context(self): def test_looping_and_negation_context(self):
view = ComplexView() view = ComplexView()
self.assertEquals(pystache.Template('{{#item}}{{header}}: {{name}} {{/item}}{{^item}} Shouldnt see me{{/item}}', view).render(), "Colors: red Colors: green Colors: blue ") view.template = '{{#item}}{{header}}: {{name}} {{/item}}{{^item}} Shouldnt see me{{/item}}'
self.assertEquals(view.render(), "Colors: red Colors: green Colors: blue ")
def test_empty_context(self): def test_empty_context(self):
view = ComplexView() view = ComplexView()
...@@ -25,13 +25,16 @@ class TestSimple(unittest.TestCase): ...@@ -25,13 +25,16 @@ class TestSimple(unittest.TestCase):
def test_callables(self): def test_callables(self):
view = Lambdas() view = Lambdas()
self.assertEquals(pystache.Template('{{#replace_foo_with_bar}}foo != bar. oh, it does!{{/replace_foo_with_bar}}', view).render(), 'bar != bar. oh, it does!') view.template = '{{#replace_foo_with_bar}}foo != bar. oh, it does!{{/replace_foo_with_bar}}'
self.assertEquals(view.render(), 'bar != bar. oh, it does!')
def test_rendering_partial(self): def test_rendering_partial(self):
view = TemplatePartial() view = TemplatePartial()
self.assertEquals(pystache.Template('{{>inner_partial}}', view).render(), 'Again, Welcome!') view.template = '{{>inner_partial}}'
self.assertEquals(view.render(), 'Again, Welcome!')
self.assertEquals(pystache.Template('{{#looping}}{{>inner_partial}} {{/looping}}', view).render(), '''Again, Welcome! Again, Welcome! Again, Welcome! ''') view.template = '{{#looping}}{{>inner_partial}} {{/looping}}'
self.assertEquals(view.render(), '''Again, Welcome! Again, Welcome! Again, Welcome! ''')
def test_non_existent_value_renders_blank(self): def test_non_existent_value_renders_blank(self):
view = Simple() view = Simple()
......
...@@ -15,23 +15,6 @@ class TemplateTestCase(unittest.TestCase): ...@@ -15,23 +15,6 @@ class TemplateTestCase(unittest.TestCase):
"""Test the Template class.""" """Test the Template class."""
def test_init__kwargs_with_no_context(self):
"""
Test passing **kwargs with no context.
"""
# This test checks that the following line raises no exception.
template = Template(foo="bar")
def test_init__kwargs_does_not_modify_context(self):
"""
Test that passing **kwargs does not modify the passed context.
"""
context = {}
template = Template(context=context, foo="bar")
self.assertEquals(context, {})
def test_render__unicode(self): def test_render__unicode(self):
template = Template(u'foo') template = Template(u'foo')
actual = template.render() actual = template.render()
...@@ -51,8 +34,46 @@ class TemplateTestCase(unittest.TestCase): ...@@ -51,8 +34,46 @@ class TemplateTestCase(unittest.TestCase):
self.assertEquals(actual, u'Poincaré') self.assertEquals(actual, u'Poincaré')
def test_render__context(self): def test_render__context(self):
template = Template('Hi {{person}}', {'person': 'Mom'}) """
self.assertEquals(template.render(), 'Hi Mom') Test render(): passing a context.
"""
template = Template('Hi {{person}}')
self.assertEquals(template.render({'person': 'Mom'}), 'Hi Mom')
def test_render__context_and_kwargs(self):
"""
Test render(): passing a context and **kwargs.
"""
template = Template('Hi {{person1}} and {{person2}}')
self.assertEquals(template.render({'person1': 'Mom'}, person2='Dad'), 'Hi Mom and Dad')
def test_render__kwargs_and_no_context(self):
"""
Test render(): passing **kwargs and no context.
"""
template = Template('Hi {{person}}')
self.assertEquals(template.render(person='Mom'), 'Hi Mom')
def test_render__context_and_kwargs__precedence(self):
"""
Test render(): **kwargs takes precedence over context.
"""
template = Template('Hi {{person}}')
self.assertEquals(template.render({'person': 'Mom'}, person='Dad'), 'Hi Dad')
def test_render__kwargs_does_not_modify_context(self):
"""
Test render(): passing **kwargs does not modify the passed context.
"""
context = {}
template = Template('Hi {{person}}')
template.render(context=context, foo="bar")
self.assertEquals(context, {})
def test_render__output_encoding(self): def test_render__output_encoding(self):
template = Template(u'Poincaré') template = Template(u'Poincaré')
......
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