Commit bc5d0e27 by Carl Whittaker

Fixed accessing mixed nested context objects. BOOM!

parent 69406c08
{{>simple}}
\ No newline at end of file
...@@ -11,3 +11,6 @@ class TemplatePartial(pystache.View): ...@@ -11,3 +11,6 @@ class TemplatePartial(pystache.View):
def looping(self): def looping(self):
return [{'item': 'one'}, {'item': 'two'}, {'item': 'three'}] return [{'item': 'one'}, {'item': 'two'}, {'item': 'three'}]
def thing(self):
return self['prop']
\ No newline at end of file
...@@ -19,15 +19,20 @@ def modifier(symbol): ...@@ -19,15 +19,20 @@ def modifier(symbol):
return func return func
return set_modifier return set_modifier
def get_or_attr(obj, name, default=None): def get_or_attr(context_list, name, default=None):
if not context_list:
return default
for obj in context_list:
try: try:
return obj[name] return obj[name]
except KeyError: except KeyError:
return default pass
except: except:
try: try:
return getattr(obj, name) return getattr(obj, name)
except AttributeError: except AttributeError:
pass
return default return default
class Template(object): class Template(object):
...@@ -47,7 +52,7 @@ class Template(object): ...@@ -47,7 +52,7 @@ class Template(object):
context.update(kwargs) context.update(kwargs)
self.view = context if isinstance(context, View) else View(context=context) self.view = context if isinstance(context, View) else View(context=context)
self.context_list = [self.view]
self._compile_regexps() self._compile_regexps()
def _compile_regexps(self): def _compile_regexps(self):
...@@ -71,7 +76,7 @@ class Template(object): ...@@ -71,7 +76,7 @@ class Template(object):
section, section_name, inner = match.group(0, 1, 2) section, section_name, inner = match.group(0, 1, 2)
section_name = section_name.strip() section_name = section_name.strip()
it = get_or_attr(view, section_name, None) it = get_or_attr(self.context_list, section_name, None)
replacer = '' replacer = ''
# Callable # Callable
...@@ -108,11 +113,11 @@ class Template(object): ...@@ -108,11 +113,11 @@ class Template(object):
return template return template
def _render_dictionary(self, template, context): def _render_dictionary(self, template, context):
original_context = copy.copy(self.view.context) template = Template(template, self.view)
self.view.context.update(context) self.context_list.insert(0, context)
out = Template(template, self.view).render() template.context_list = self.context_list
self.view.context = original_context out = template.render()
self.context_list.pop(0)
return out return out
def _render_list(self, template, listing): def _render_list(self, template, listing):
...@@ -124,7 +129,7 @@ class Template(object): ...@@ -124,7 +129,7 @@ class Template(object):
@modifier(None) @modifier(None)
def _render_tag(self, tag_name, view): def _render_tag(self, tag_name, view):
raw = get_or_attr(view, tag_name, '') raw = get_or_attr(self.context_list, tag_name, '')
# For methods with no return value # For methods with no return value
if not raw and raw is not 0: if not raw and raw is not 0:
......
...@@ -76,5 +76,11 @@ Again, Welcome! ...@@ -76,5 +76,11 @@ Again, Welcome!
view.template = '{{#herp}}{{#derp}}{{nested_context_in_view}}{{/derp}}{{/herp}}' view.template = '{{#herp}}{{#derp}}{{nested_context_in_view}}{{/derp}}{{/herp}}'
self.assertEquals(view.render(), 'it works!') self.assertEquals(view.render(), 'it works!')
def test_partial_in_partial_has_access_to_grand_parent_context(self):
view = TemplatePartial()
view.context = {'prop': 'derp'}
view.template = '''{{>partial_in_partial}}'''
self.assertEquals(view.render(), 'Hi derp!')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
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