Templating is a common approach to separating logic from presentation, and many options exist within the .NET ecosystem. The most popular is the Razor engine used by ASP.NET Core, but it currently has some dependencies that make it difficult to use consistently in many scenarios. That’s where alternative templating systems can provide value, as they typically work with fewer, if any, external dependencies.

As a big fan of Jekyll, Liquid is a natural choice for templating as it provides simple templating, types, iteration, control flow, and a suite of built-in helper methods. It’s also very mature and has excellent documentation. So, I was excited to try Scriban as a fast, robust, safe, and lightweight templating engine.

What is Scriban?

Scriban is the brainchild of Alexandre Mutel, and is touted as a scripting language and engine for .NET with the primary purpose of text templating. It also provides a compatibility mode for parsing and rendering Liquid templates. It’s vital to distinguish Scriban as a text templating engine, not just a web view engine. Text templating implies it can be used to generate any text-based format, including but not limited to HTML. Outside of .NET dependencies, Scriban is entirely free of external dependencies, with the option to source embed. This makes it perfect for many app host options in the .NET ecosystem.

Getting Started with Scriban

Let’s see what a “Hello World” use case would look like.

// Parse a scriban template
var template = Template.Parse("Hello !");
var result = template.Render(new { Name = "World" }); 
// => "Hello World!" 

This could look more exciting, but it hints at some mind-blowing scenarios which we’ll see in the next section. Let’s ramp it up.

Complex Liquid Scenario with Scriban

As mentioned, Liquid is a commonly-used templating language used in the Ruby on Rails community. Shopify also uses it for its online storefront platform. Let’s look at a complex C# example of a Liquid template and then break it down.

Note: If you’re using JetBrains Rider, install the Liquid plugin to get Liquid syntax highlighting.

using Scriban;  
using Scriban.Runtime;  
  
var script = new ScriptObject();  
script.Import(typeof(MyFunctions));  
script.Add("products", new Product[]  
{  
    new("Blue Socks", 10m, "plain socks"),  
    new("Gray Pants", 22m, "regular ol' pants"),  
    new("Amazing T-Shirt", 24m, 
        "the world's most fantastical t-shirt"),  
});  
  
var context = new LiquidTemplateContext();  
context.PushGlobal(script);  
  
var template = Template.ParseLiquid(
    // lang=liquid
    """
    <ul id='products'>{% for product in products %}
        <li>
            <h2>{{ product.name | append_emoji }} ({{ product.price }})</h2>
            <p>{{ product.description | truncate: 15, "..." }}</p>
        </li>{% endfor %}
    </ul>
    """);
  
var result = template.Render(context);  
  
Console.WriteLine(result);  
  
public static class MyFunctions  
{  
    public static string AppendEmoji(string input)  
        => $"{input} 🛍️";  
}  
  
public record Product(  
    string Name,  
    decimal Price,  
    string Description);

At the start of of the code, we create a new ScriptObject. This instance will contain all our variables and .NET functions we’ll want to use in our template.

The first step registers an AppendEmoji method, which gets translated into append_emoji by convention. All static methods in the MyFunctions class will be registered. You can expand your templating vocabulary with a few C# methods.

Next, we add the products global variable to our script. This collection will be used in the template to display our product collection. These are plain old C# records.

Finally, we get to the template parsing and rendering. You’ll notice the use of the truncate filter in the template. From my testing, most Liquid filters are available out of the box, which is helpful. When the template is parsed, we’re ready to render it. Here, the call to Render is provided the script context, which references our data and our C# AppendEmoji helper method.

All that’s left is to see what the results look like.

<ul id='products'>
    <li>
        <h2>Blue Socks 🛍️ (10)</h2>
        <p>plain socks</p>
    </li>
    <li>
        <h2>Gray Pants 🛍️ (22)</h2>
        <p>regular ol' ...</p>
    </li>
    <li>
        <h2>Amazing T-Shirt 🛍️ (24)</h2>
        <p>the world's ...</p>
    </li>
</ul>

That’s awesome!

Conclusion

Scriban looks like an excellent templating engine for the .NET ecosystem. With the ability to use Liquid, it goes to a whole new level. The ability to inject variables and methods into the template is also excellent. Please try it and let me know what scenarios you could use a text templating engine in.

Thank you for reading and sharing my posts with friends and colleagues.