wbond / pybars3

Handlebars.js template support for Python 3 and 2
GNU Lesser General Public License v3.0
179 stars 46 forks source link

Dictionary keys take precedence over attributes #19

Closed viernullvier closed 8 years ago

viernullvier commented 9 years ago

Fixes #16, but might break legacy code in some specific edge cases (namely when passing contexts with both a get() function and custom attributes)

mjumbewu commented 9 years ago

The break seems reasonable to me. Though it makes me wonder why were checking for a get method at all. Would it not be sufficient to move the try block up and check for object attribute in the except clause? Something like:

try:
    return context[name]
except (KeyError, TypeError):
    if isinstance(name, str) and hasattr(context, name):
        return getattr(context, name)
    else:
        return default

I realize that this would break context objects that don't implement __getitem__, but it feels like a cleaner interface. Any thoughts @wbond?

(NOTE: I'm typing this with my thumbs and haven't tested it)

viernullvier commented 9 years ago

@mjumbewu: Well done, your version makes even more sense than mine. I'll update the PR right now...

wbond commented 9 years ago

I'm not so keen on removing .get() as a property accessor. I am fine with it going at the end of the list and preferring dict-access and attribute access. I think .get() is least used of those patterns in Python, however I dunno if there is a compelling reason to remove support for it. I think the handlebars pattern of allowing access to pretty much any sort of data container is useful.

viernullvier commented 9 years ago

@wbond I've just updated my PR with .get() support still intact.

tomgross commented 8 years ago

Any chance to get this merged soon? Can I help?

greggb commented 8 years ago

I think this might fix an issue I'm having where the data I receive has something.items as a list I need to iterate. Any chance for getting this merged and pushed out to pypi?

{{#something}}
    {{#if items}}{{/if items}} //error
    {{#items}}{{/items}} //error
    {{#each items}}{{/each}} // empty output
{{/something}}

TypeError: items() takes no arguments (1 given)