Handlebars-Net / Handlebars.Net.Helpers

Handlebars.Net helpers in the categories: 'Boolean', 'Constants', 'Enumerable', 'Environment', 'Math', 'Regex', 'String', 'DateTime' and 'Url'.
MIT License
40 stars 15 forks source link

Regex.IsMatch alternative to preserve context? #25

Closed Zulu-Inuoe closed 3 years ago

Zulu-Inuoe commented 3 years ago

Hello!

I stumbled on this interesting behaviour with Regex.IsMatch:

var handlebars = Handlebars.Create();
HandlebarsHelpers.Register(handlebars, opt => { opt.CustomHelperPaths = new string[0]; });
var context = new Dictionary<string, object>()
{
    ["Attributes"] = "visible",
    ["Value"] = "SomeString"
};

var expansion = handlebars.Compile("{{#Regex.IsMatch Attributes 'visible'}}{{Value}}{{/Regex.IsMatch}}")(context);

This gets me an empty string. I tried again, using {{.}} rather than {{Value}} I got the string "True"

So it looks like Regex.IsMatch will set the Handlebars context to the match result., so if I want to get at the previous context I have to do eg {{../Value}}, however this seems quite awkward and surprising. It definitely does not behave like #if and #unless do.

Now, "fixing" this to not alter context is no doubt going to break somebody's template out there since it's been this way since it was introduced

But what do you think @StefH of having a variant of IsMatch with a different name, which is exactly like IsMatch, but preserves the current context?

StefH commented 3 years ago

https://github.com/Handlebars-Net/Handlebars.Net.Helpers/pull/26

StefH commented 3 years ago

@Zulu-Inuoe I think you need to use the "#if" code:

            // Arrange
            var template = "{{#if (#Regex.IsMatch Attributes 'visible')}}{{Value}}{{/if}}";
            var context = new Dictionary<string, object>()
            {
                ["Attributes"] = "visible",
                ["Value"] = "SomeString"
            };
            var action = _handlebarsContext.Compile(template);

            // Act
            var result = action(context);

            // Assert
            result.Should().Be("SomeString");
Zulu-Inuoe commented 3 years ago

@StefH I see, that makes sense. I hadn't considered Handlebars subexpressions.

Thank you!