Skip to content

DotLiquid for Developers

Willem Danny edited this page · 11 revisions

First steps

Getting started with DotLiquid is very easy. A DotLiquid template is rendered in two steps: Parse and Render. For an overview of the DotLiquid syntax, please read DotLiquid for Designers.

Template template = Template.Parse("hi {{name}}");  // Parses and compiles the template
template.Render(Hash.FromAnonymousObject(new { name = "tobi" })); // Renders the output => "hi tobi"

The Parse step creates a fully compiled template which can be re-used. You can store it in memory or in a cache for faster rendering later.

All parameters you want to use in your DotLiquid templates have to be passed as parameters to the Render method. DotLiquid does not know about your C# (or VB.NET) local or instance variables.

Rules for template rendering parameters

Objects that you pass to Template.Render must satisfy one of the following conditions:

  • Type is an integral type (int, string, decimal, etc.) or anonymous type
  • Class inherits from Drop (more info)
  • Class implements ILiquidizable
  • Class is decorated with [LiquidType] attribute. Note that you must specify the allowed member names. For example: [LiquidType("AllowedMember1", "AllowedMember2")].
  • Type is registered with Template.RegisterSafeType(Type type, string[] allowedMembers)
  • Type is registered with Template.RegisterSafeType(Type type, Func<object, object> func)

Extending DotLiquid

Extending DotLiquid is very easy. If you do create useful filters or tags, please consider creating a "pull request" to this repository (formosatek/dotliquid).

Create your own filters

Creating filters is very easy. Filters are just methods which take one parameter and return a modified string. You can use your own filters by passing an array of filter types to the Render call like this: template.Render(filters: new[] { typeof(MyTextFilters), typeof(MyDateFilters) });

public static class TextFilter
{
    public static string Textilize(string input)
    {
        return TextileFormatter.FormatString(input);
    }
}

Template template = Template.Parse(" {{ '*hi*' | Textilize }} ");
template.Render(filters: new[] { typeof(TextFilter) }); // => "<b>hi</b>" 

Alternatively, you can register your filters globally:

public static class TextFilter
{
    public static string Textilize(string input)
    {
        return TextileFormatter.FormatString(input);
    }
}

Template.RegisterFilter(typeof(TextFilter));

Once the filter is globally registered, you can simply use it:

Template template = Template.Parse(" {{ '*hi*' | Textilize }} ");
template.Render(); // => "<b>hi</b>" 

A filter can access the current context if you add a Context object as the first argument to your filter method. DotLiquid will automatically pass the current context to your filter:

public static String MyFilter(Context context, String input)
{
    //...
}

Create your own tags

To create a new tag, simply inherit from DotLiquid.Tag and register your tag with DotLiquid.Template.

public class Random : DotLiquid.Tag
{
    private int _max;

    public override void Initialize(string tagName, string markup, List<string> tokens)
    {
        base.Initialize(tagName, markup, tokens);
        _max = Convert.ToInt32(markup);
    }

    public override void Render(Context context, TextWriter result)
    {
        result.Write(new Random().Next(_max).ToString());
    }
}

Template.RegisterTag<Random>("random");

Template template = Template.Parse(" {% random 5 %}");
template.Render(); // => "3"

Create your own tag blocks

All tag blocks are parsed by DotLiquid. To create a new block, you just have to inherit from DotLiquid.Block and register your block with DotLiquid.Template.

public class Random : DotLiquid.Block
{
    private int _max;

    public override void Initialize(string tagName, string markup, List<string> tokens)
    {
        base.Initialize(tagName, markup, tokens);
        _max = Convert.ToInt32(markup);
    }

    public override void Render(Context context, StreamWriter result)
    {
        if (new System.Random().Next(_max) == 0)
            base.Render(context, result);
    }
}

Template.RegisterTag<Random>("random");

string text = " {% random 5 %} wanna hear a joke? {% endrandom %} ";
Template template = Template.Parse(text);
template.Render(); // => In 20% of the cases, this will output "wanna hear a joke?"
Something went wrong with that request. Please try again.