AzureLiquid 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package AzureLiquid --version 1.2.0                
NuGet\Install-Package AzureLiquid -Version 1.2.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AzureLiquid" Version="1.2.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add AzureLiquid --version 1.2.0                
#r "nuget: AzureLiquid, 1.2.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install AzureLiquid as a Cake Addin
#addin nuget:?package=AzureLiquid&version=1.2.0

// Install AzureLiquid as a Cake Tool
#tool nuget:?package=AzureLiquid&version=1.2.0                

Azure Liquid

The project was primarily built to aid in developing and testing Liquid template parsing solutions for Microsoft Azure cloud services.

The Liquid template engine that is used in Microsoft Azure is based on the DotLiquid library.

DotLiquid is a .Net port of the popular Ruby Liquid templating language. It is a separate project that aims to retain the same template syntax as the original, while using .NET coding conventions where possible. For more information about the original Liquid project, see https://shopify.github.io/liquid/.

This library uses my .NET 6.0 port of the same library, to allow for cross-platform compilation and tooling support.

Azure uses a set of predefined feature uses of DotLiquid. For example, an Azure Logic App mapping service uses the "content" accessor for any data submitted using a workflow action. The LiquidParser class exposes a set of SetContent methods used to either set:

  • objects (will render down to JSON)
  • JSON string
  • XML string (will parse as XDocument then to JSON)

The object can then be accessed under the "content" variable in the Liquid template.

{% assign albums = content.CATALOG.CD -%} [{%- for album in albums limit:3 %}  
{     "artist": "{{ album.ARTIST }}",     "title": "{{ album.TITLE}}"   }{% if
forloop.last == false %},{% endif %}   {%- endfor -%} ]

Our object data is in this case XML, and has been added as a hierarchical selector object, here named "CATALOG", containing an array of "CD" objects. These are loaded under the hood by parsing text to an XmlDocument then back to JSON using the SetContentXml method.

Similarly, we can load JSON data either using a string with the SetContentJson method, or using object serialization with the SetContent method. Note this method's parameter forceCamlCase allows us to ensure that camel JSON formatting is preserved in the selectors.

Azure Specific Differences

For example, an Azure LogicApp mapping service uses the content accessor. The LiquidParser exposes a set of SetContent methods used to either set:

  • objects (will render down to JSON)
  • JSON string
  • XML string (will parse as XDocument then to JSON)

The object can then be accessed under the 'content' variable in the Liquid template. This is implemented by using the LiquidParser object and using it for unit testing or for live previews/file rendering.

A key within this project is that I created it to be as compatible and usable for Azure implementations as possible. Therefore, it is important to understand how the DotLiquid and Azure implementations of the library differ from Shopify Liquid.

  • Liquid templates follow the file size limits for maps in Azure Logic Apps.

  • When using the date filter, DotLiquid supports both Ruby and .NET date format strings (but not both at the same time). By default, it will use .NET date format strings.

  • The JSON filter from the Shopify extension filters is currently not implemented in DotLiquid.

  • The standard Replace filter in the DotLiquid implementation uses regular expression (RegEx) matching, while the Shopify implementation uses simple string matching.

  • Liquid by default uses Ruby casing for output fields and filters such as {{ some_field | escape }}. The Azure implementation of DotLiquid uses C# naming convention, in which case output fields and filters would be referenced like so {{ SomeField | Escape }}.

For further details, see the Microsoft documentation.

How To Unit Test Liquid

There are a few different examples made:

// Arrange
var myObj = new MyObj( Title = "Title here");

// Act
var result = new LiquidParser()
    .SetContent(myObj, true) // 'true' => camelCase property names
    .Parse("{{ content.title }}")
    .Render();

// Assert
result.Should().NotBeEmpty("A result should have been returned");
result.Should().Be(myObj.Title, "The expected result should be returned");

See the full example

Another example can be made where we use a string body to transform the data.

/// <summary>
/// Ensures loading JSON from a file and parsing with a liquid file template works.
/// </summary>
[Fact]
public void EnsureJsonBodyTemplateParsing()
{
    // Arrange
    var parser = new LiquidParser()
        .SetContentJson(Resources.JsonTestContent)
        .Parse(Resources.JsonTestLiquidTemplate)
    var expected = Resources.TestExpectedOutput;

    // Act
    var result = parser.Render();

    // Assert
    result.Should().NotBeEmpty("A result should have been returned");
    result.Should().Be(expected, "The expected result should be returned");
}

You could similarly load the content and templates from a set of file. See the full test project for several such examples.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.0 87 12/2/2024
1.2.0 87 11/30/2024
1.1.1 26,036 11/11/2022
1.1.0 2,116 10/22/2022
1.0.5 862 10/20/2022
1.0.4 1,024 10/20/2022
1.0.3 846 10/20/2022
1.0.2 818 10/18/2022
1.0.0 82 11/30/2024