Back to Blog
Mar 25, 2023

Implementing `groupby` custom liquid filter for .NET Fluid

Written by Zack Schwartz

Intro

Liquid is a popular template engine used in web development. Fluid, an implementation of Liquid in .NET, is used in Raytha, our open-source .NET CMS platform. However, there is no implementation of the groupby operation in the Liquid templating language. This blog post describes how Raytha implemented a custom groupby filter in Fluid to enable this operation in our platform and potentially your application too.

The groupby operation is used to group items in a collection based on a common attribute value. This is a helpful operation when creating a website, as it allows for easy organization and presentation of content.

Using the `groupby` liquid filter

To use the custom groupby filter in Raytha, first, assign the items to a liquid variable using the groupby filter. Second, loop through the items using a key and items attribute. For example:

{% assign grouped_items = Target.Items | groupby: "PublishedContent.developer_name" %}
{% for grouped_item in grouped_items %}
    {{ grouped_item.key }}
    {% for item in grouped_item.items %}
        {{ item.PublishedContent.developer_name.Value }}
    {% endfor %}
{% endfor %}

In this example, the groupby operation is performed on the developer_name attribute of the PublishedContent property.

Coding the `groupby` filter

To create the custom groupby filter, two functions are needed. The first function adds the filter to the template options. The second function performs the groupby operation on the input collection and returns the result.

The GroupBy function takes three parameters: the input collection, the property to group by, and the template context. The function groups the items in the collection based on the common attribute value and returns an array of key-value pairs.

The ApplyGroupBy function takes the item and the group by property and returns the value of the specified property. If the property is a child attribute of the PublishedContent property, the function retrieves the child attribute value. You may not need this if you do not need to groupby child attributes.

You can find Raytha's custom filters defined in our code base here: https://github.com/RaythaHQ/raytha/blob/main/src/Raytha.Web/Services/RenderEngine.cs, but we will summarize the specific code for `groupby` below.

Add the filter to the template options:

options.Filters.AddFilter("groupby", GroupBy);

Now here are two functions accordingly.

public ValueTask<FluidValue> GroupBy(FluidValue input, FilterArguments property, TemplateContext context)
{
    var groupByProperty = property.At(0).ToStringValue();
    var groups = input.Enumerate(context).GroupBy(p => ApplyGroupBy(p, groupByProperty, context));
    var result = new List<FluidValue>();
    foreach (var group in groups)
    {
        result.Add(new ObjectValue(new 
        {
            key = group.Key,
            items = group.ToList()
        }));
    }
    return new ArrayValue(result);
}

private string ApplyGroupBy(FluidValue p, string groupByProperty, TemplateContext context)
{
    if (groupByProperty.StartsWith("PublishedContent") && groupByProperty.Contains("."))
    {
        var developerName = groupByProperty.Split(".").ElementAt(1);
        return p.GetValueAsync("PublishedContent", context).Result.GetValueAsync(developerName, context).Result.ToStringValue();
    }
    else
    {
        return p.GetValueAsync(groupByProperty, context).Result.ToStringValue();
    }
}

Creating a custom groupby filter in Fluid enables the groupby operation in the Raytha platform. By grouping items in a collection based on a common attribute value, the custom filter makes it easier to organize and present content on a website.

picture of the author
Zack Schwartz @apexdodge

ENTREPRENEUR & SOFTWARE ENGINEER, AUSTIN, TX
I enjoy tackling a wide array of business challenges ranging from front line product support and operations to sales and marketing efforts. My core expertise is in software development building enterprise level web applications.


Subscribe to the Raytha newsletter