Commit bc5d0e27 by Carl Whittaker

Fixed accessing mixed nested context objects. BOOM!

parent 69406c08
{{>simple}}
\ No newline at end of file
...@@ -10,4 +10,7 @@ class TemplatePartial(pystache.View): ...@@ -10,4 +10,7 @@ class TemplatePartial(pystache.View):
return '-' * len(self.title()) return '-' * len(self.title())
def looping(self): def looping(self):
return [{'item': 'one'}, {'item': 'two'}, {'item': 'three'}] return [{'item': 'one'}, {'item': 'two'}, {'item': 'three'}]
\ No newline at end of file
def thing(self):
return self['prop']
\ No newline at end of file
...@@ -19,16 +19,21 @@ def modifier(symbol): ...@@ -19,16 +19,21 @@ 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):
try: if not context_list:
return obj[name]
except KeyError:
return default return default
except:
for obj in context_list:
try: try:
return getattr(obj, name) return obj[name]
except AttributeError: except KeyError:
return default pass
except:
try:
return getattr(obj, name)
except AttributeError:
pass
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
...@@ -84,7 +89,7 @@ class Template(object): ...@@ -84,7 +89,7 @@ class Template(object):
# Lists # Lists
elif it and hasattr(it, '__iter__'): elif it and hasattr(it, '__iter__'):
if section[2] != '^': if section[2] != '^':
replacer = self._render_list(inner, it) replacer = self._render_list(inner, it)
# Falsey and Negated or Truthy and Not Negated # Falsey and Negated or Truthy and Not Negated
elif (not it and section[2] == '^') or (it and section[2] != '^'): elif (not it and section[2] == '^') or (it and section[2] != '^'):
replacer = inner replacer = inner
...@@ -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