Improved attribute and item lookup by allowing template designers to express the priority. foo.bar checks foo.bar first and then foo['bar'] and the other way round.
--HG--
branch : trunk
diff --git a/jinja2/environment.py b/jinja2/environment.py
index acb5c02..689bc92 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -286,8 +286,8 @@
"""Return a fresh lexer for the environment."""
return Lexer(self)
- def subscribe(self, obj, argument):
- """Get an item or attribute of an object."""
+ def getitem(self, obj, argument):
+ """Get an item or attribute of an object but prefer the item."""
try:
return obj[argument]
except (TypeError, LookupError):
@@ -303,6 +303,19 @@
pass
return self.undefined(obj=obj, name=argument)
+ def getattr(self, obj, attribute):
+ """Get an item or attribute of an object but prefer the attribute.
+ Unlike :meth:`getitem` the attribute *must* be a bytestring.
+ """
+ try:
+ return getattr(obj, attribute)
+ except AttributeError:
+ pass
+ try:
+ return obj[attribute]
+ except (TypeError, LookupError):
+ return self.undefined(obj=obj, name=attribute)
+
def parse(self, source, name=None, filename=None):
"""Parse the sourcecode and return the abstract syntax tree. This
tree of nodes is used by the compiler to convert the template into