wbond / pybars3

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

"if" handling #53

Closed wichert closed 5 years ago

wichert commented 5 years ago

I am trying to locally render handlebars as implemented by Mandrill. In particular something like this:

{{#if `settings.greeting == 1` }}
Hi
{{elseif `settings.greeting == 2` }}
Welcome
{{else}}
Hello
{{/if}}

Currently this fails with pybars3. There appears to fail because the grammar does not recognise the subexpression for the if helper.

wichert commented 5 years ago

I've been studying this a bit further, and it looks like mandrill is just doing some very non-standard things here that pybars3 probably should not support. I managed to get it working by doing a bit of rewriting on the source and using an extra helper:

def eq(this, a, b):
    return a == b

COMPARISON = re.compile(r'({{\s*(#if|elseif))\s+`(\S+)\s*==\s*(\S+)`')

def rewrite_comparison(source):
    def replace(m):
        return f'{m.group(1)} (eq {m.group(3)} {m.group(4)})'

    return COMPARISON.sub(replace, source)

handlebars_source = rewrite_comparison(handlebars_source)
template = Compiler().compile(handlebars_source)
output = template(data, helpers={"eq": eq})