Extending DotLiquid
Extending DotLiquid is very easy. If you do create useful filters or tags, please consider creating a pull request.
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(new RenderParameters(CultureInfo.CurrentCulture)
{
Filters = new[] { typeof(MyTextFilters), typeof(MyDateFilters) }
});
Example:
public static class TextFilter
{
public static string Textilize(string input)
{
return TextileFormatter.FormatString(input);
}
}
Template template = Template.Parse(" {{ '*hi*' | textilize }} ");
template.Render(new RenderParameters(CultureInfo.CurrentCulture)
{
Filters = new[] { typeof(TextFilter) }
});
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. Filter names in liquid markup are lower case.
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)
{
//...
}
Filters also work from F#:
open DotLiquid
type TextFilter() =
static member Textilize (input : string) =
"<b>" + input + "</b>"
Template.RegisterFilter(TextFilter().GetType());
let template = Template.Parse(" {{ '*hi*' | textilize }} ");
printfn "%s" (template.Render()) // => "<b>*hi*</b>"
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?"
Adding custom operators
It is possible to add your own custom operators like this:
Condition.Operators["IsMultipleOf"] = (left, right) => (int)left % (int)right == 0;
And use it like this in ruby casing:
{% if 16 is_multiple_of 4 %} TRUE {% endif %}
Or like this in C# casing:
{% if 16 IsMultipleOf 4 %} TRUE {% endif %}