handlebars.jshandlebarshelperhandlebars.net

Handlebars not resolve binding within helper


I play a little with handlebars.Net and have a problem with BlockHelper and bindings.

The template (see below) should iterate between persons and only write persons into the result if it´s age is over 18. I think my helper works fine but Handlebars.Net doesn't resolve my binding within the Helper-Block.

I've got this template:

{{#Persons}}
    {{gt Age '18'}}
        Test
        {{Firstname}} {{Lastname}}
    {{/gt}}
{{/Persons}}

This is my data:

                {
                    new
                    {
                        Firstname = "Luka",
                        Lastname = "Datrik",
                        Age = "28"
                    },
                    new
                    {
                        Firstname = "Max",
                        Lastname = "Mustermann",
                        Age = "18"
                    },
                    new
                    {
                        Firstname = "John",
                        Lastname = "Doe",
                        Age = "33"
                    }
                };

The result should be something like:

Test
Luka Datrik
Test
John Doe

But Handlebars doesn´t resolve my binding within the GreaterThan-Block Is this wanted or a bug?

Here my complete code in C#

static void Main(string[] args)
        {
            HandlebarsHelper.Register();

            var rawFile = File.ReadAllText(".\\TextFile1.txt");

            //var content = new XDocument(rawFile).Element("PrintLayout").FirstNode.ToString();

            var template = Handlebars.Compile(rawFile);
            var result = template(new Dynamic());

            File.WriteAllText("temp.txt", result);

            System.Diagnostics.Process.Start("temp.txt");
        }

Helper:

namespace HandlebarsTests
{
    public static class HandlebarsHelper
    {
        public static readonly new string Equals = "eq";
        public static readonly string LowerThan = "lt";
        public static readonly string GreaterThan = "gt";
        public static readonly string GreaterEquals = "ge";
        public static readonly string LowerEquals = "le";
        public static readonly string DateFormat = "dateFormat";
        public static readonly string FormatStringIndicator = "formatString";

        public static void Register()
        {
            Handlebars.RegisterHelper(DateFormat, (output, context, data) =>
            {
                if (!DateTime.TryParse(data[0].ToString(), out DateTime date))
                {
                    output.WriteSafeString(data[0].ToString());
                    return;
                }

                var dictionary = data[1] as HandlebarsDotNet.Compiler.HashParameterDictionary;
                var formatString = dictionary[FormatStringIndicator];

                output.WriteSafeString(date.ToString(formatString.ToString()));
            });

            Handlebars.RegisterHelper(Equals, (output, options, context, data) =>
            {
                if (data.Length != 2)
                    options.Inverse(output, null);

                if (data[0].Equals(data[1]))
                    options.Template(output, null);
                else
                    options.Inverse(output, null);
            });
            Handlebars.RegisterHelper(LowerThan, (output, options, context, data) =>
            {
                IntegerOperation(LowerThan, ref output, ref options, ref data);
            });

            Handlebars.RegisterHelper(GreaterThan, (output, options, context, data) =>
            {
                IntegerOperation(GreaterThan, ref output, ref options, ref data);
            });

            Handlebars.RegisterHelper(LowerEquals, (output, options, context, data) =>
            {
                IntegerOperation(LowerEquals, ref output, ref options, ref data);
            });

            Handlebars.RegisterHelper(GreaterEquals, (output, options, context, data) =>
            {
                IntegerOperation(GreaterEquals, ref output, ref options, ref data);
            });
        }

        private static void IntegerOperation(string operation, ref System.IO.TextWriter output, ref HelperOptions options, ref object[] data)
        {
            if (data.Length != 2)
            {
                options.Inverse(output, null);
                return;
            }

            if (!int.TryParse(data[0].ToString(), out int leftValue))
            {
                options.Inverse(output, null);
                return;
            }

            if (!int.TryParse(data[1].ToString(), out int rightValue))
            {
                options.Inverse(output, null);
                return;
            }

            switch (operation)
            {
                case "lt":
                    if (leftValue < rightValue)
                        options.Template(output, null);
                    else
                        options.Inverse(output, null);
                    break;
                case "le":
                    if (leftValue <= rightValue)
                        options.Template(output, null);
                    else
                        options.Inverse(output, null);
                    break;
                case "gt":
                    if (leftValue > rightValue)
                        options.Template(output, null);
                    else
                        options.Inverse(output, null);
                    break;
                case "ge":
                    if (leftValue >= rightValue)
                        options.Template(output, null);
                    else
                        options.Inverse(output, null);
                    break;
                default:
                    break;
            }

        }
    }

Solution

  • I´ve found the solution:

    Example for Equals:

    Handlebars.RegisterHelper(Equals, (output, options, context, data) =>
                {
                    if (data.Length != 2)
                        options.Inverse(output, context);
    
                    if (data[0].Equals(data[1]))
                        options.Template(output, context);
                    else
                        options.Inverse(output, context);
                });
    

    I think it´s a recursive call from options.Template(output, context)