Handlebars-Net / Handlebars.Net

A real .NET Handlebars engine
MIT License
1.22k stars 213 forks source link

options.Template() doens't work as expected #525

Closed 0NotApplicable0 closed 1 year ago

0NotApplicable0 commented 1 year ago

Describe the bug

When using options.Template() with a block helper it is expected that the first block will be printed if options.Template() is called and options.Inverse() will print the second block.

Issue was not present in 1.11.5 but is when upgrading to v2.

See update comment below

Expected behavior:

options.Template() prints first block, options.Inverse() prints second block.

Test to reproduce

[Fact]
public void Descriptive_Test_Name_Here()
{
    var source = @"
                {{testing ""true""}}ITWORKED{{else}}ITDIDNTWORK{{/testing}}
     ";

     var template = Handlebars.Compile(source); // Global handlebars
     var results = template(new {});

     // Expected: "ITWORKED"
     // Actual: "ITDIDNTWORK"
}

Helper

            Handlebars.RegisterHelper(
                    "testing",
                    (writer, options, context, arguments) =>
                    {
                        var val = arguments[0];
                        if (HandlebarsUtils.IsTruthyOrNonEmpty(val))
                        {
                            options.Template(writer, context);
                        }
                        else
                        {
                            options.Inverse(writer, context);
                        }
                    });

Other related info

This was previously working on v1.11.5 but breaks when upgrading to v2.

Am I doing something super wrong on my side, is there some sort of new config in v2?

Thanks!

0NotApplicable0 commented 1 year ago

Update:

So there doesn't seem to be a bug having to do with .Template and .Inverse and the issue is coming from custom helpers that are not used with a #.

For example, if we change my above example from: {{testing ""true""}}ITWORKED{{else}}ITDIDNTWORK{{/testing}}

To: {{#testing ""true""}}ITWORKED{{else}}ITDIDNTWORK{{/testing}}

It will work.

Built in helpers like if and equals will throw an error if you are missing the #: A closing element '/if' was found without a matching open elementA closing element '/if' was found without a matching open element

Whereas custom helpers will work but not correctly.

This still seems like a bug?

oformaniuk commented 1 year ago

I would not consider this to be a bug. {{testing ""true""}} is still a valid expression. You see an exception for the if case due to the way it is implemented, if is not implemented as a helper for performance reasons as it is mapped directly onto ExpressionTree expression.