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;
}
}
}
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)