Handlebars-Net / Handlebars.Net

A real .NET Handlebars engine

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Object reference hierarchy within custom helpers

drewbj21 opened this issue · comments

I noticed a strange behavior when upgrading from Handlebars 1.11.5 to Handlebars 2.x. Before upgrading, referencing an object within a built-in and custom helper worked the exact same. Here's an example:

Object:

var variablesObject = new 
{
      Test = true,
      TestValue = "Worked"
};

String to parse:

var content = "Built-in helper: {{#if Test}}{{TestValue}}{{/if}}  Custom helper: {{#contains \"test\" \"testing\"}}{{TestValue}}{{/contains}}";

Result when using Handlebars 1.11.5
Built-in helper: Worked Custom helper: Worked

Result when using Handlebars 2.0.0 or any 2.x package
Built-in helper: Worked Custom helper:

To get the value to be outputted within my custom helper in the example above, I have to go up a object hierarchy level when using a 2.x package (see below):

Modified string to parse:

var content = "Built-in helper: {{#if Test}}{{TestValue}}{{/if}}  Custom helper: {{#contains \"test\" \"testing\"}}{{../TestValue}}{{/contains}}";

Result when using Handlebars 2.0.0 or any 2.x package
Built-in helper: Worked Custom helper: Worked

Any idea why this would be happening? Here is how we are registering the custom helper:

Handlebars.RegisterHelper("contains", (writer, options, context, arguments) =>
{
    try
    {
        var value1 = Convert.ToString(arguments[0]);
        var value2 = Convert.ToString(arguments[1]);

        if (value2.Contains(value1))
        {
            options.Template(writer, (object)context);
        }
        else
        {
            options.Inverse(writer, (object)context);
        }
    }
    catch
    {
        //do something
    }
});

Edited:
@zjklee: fixed code inclusions

Hello @drewbj21
Your problem is in

options.Template(writer, (object)context);

(object)context cast is obsolete and is causing the behavior you see. context is of Context type and options.Template and options.Inverse have corresponding overloads to properly handle it - continue in the caller context. The cast results into creation of a new child context.

Hey @zjklee

That was it! Gotta love when it is a simple fix that makes sense. Thanks for the help.