Where filter does not handle truthy values correctly
williamb1024 opened this issue · comments
When using the where
filter with a single argument, the filter does not perform truthy comparisons. The equality comparison is performed with the property value controlling.
fluid/Fluid/Filters/ArrayFilters.cs
Line 156 in 74cb742
Switching itemValue
and targetValue
, such that targetValue
is controlling would result in truthy comparisons.
Here's a workaround with adding a new filter named twhere
Usage twhere
instead of where
:
{% assign filteredItems = items | twhere: "property" %}
Register in the filters:
builder.AddFluid(x => {
x.TemplateOptions.Filters.AddFilter(WhereFilter.Name, WhereFilter.Where);
});
Filter implementation with workaround:
internal static class WhereFilter
{
internal const string Name = "twhere";
// Track issue: https://github.com/sebastienros/fluid/issues/620
internal static async ValueTask<FluidValue> Where(FluidValue input, FilterArguments arguments, TemplateContext context)
{
if (input.Type != FluidValues.Array)
{
return input;
}
// First argument is the property name to match
var member = arguments.At(0).ToStringValue();
// Second argument is the value to match, or 'true' if none is defined
var targetValue = arguments.At(1).Or(BooleanValue.True);
var list = new List<FluidValue>();
foreach (var item in input.Enumerate(context))
{
var itemValue = await item.GetValueAsync(member, context);
if (itemValue.Equals(targetValue) ||
// Issue workaround for equality inconsistencies: to check if the other equals self
targetValue.Equals(itemValue))
{
list.Add(item);
}
}
return new ArrayValue(list);
}
}
So instead of comparing to true
we actually need to handle the single argument separately and convert it using ToBooleanValue()
. Can someone create a PR and a test for that?