Filters

Templates are sandboxed, they can't call methods on objects nor do they have any access to any static functions built into the .NET Framework,
so just as Arguments define all data and objects available to templates, filters define all functionality available to templates.

The only filters registered by default are the Default Filters
containing a comprehensive suite of filters useful within View Engine or Template environments and
HTML Filters.
There's nothing special about these filters other than they're pre-registered by default, your filters have access to the same
APIs and functionality and can do anything that built-in filters can do.

Shadowing Filters

You can easily override default filters with the same name and arguments by inserting them at the start of the TemplateFilters list:

context.TemplateFilters.Insert(0, new MyTemplateFilters());

Removing Default Filters

Or if you want to start from a clean slate, the default filters can be removed by clearing the collection:

context.TemplateFilters.Clear();

What are Filters?

Filters are just C# public instance methods from a class that inherits from TemplateFilter, e.g:

Autowired using TemplateContext IOC

Autowired instances of filters can also be created using TemplateContext's configured IOC where they're
also injected with any registered IOC dependencies. To utilize this you need to specify the Type of the filter that
should be Autowired by either adding it to the ScanTypes collection:

When the TemplateContext is initialized it will go through each Type and create an autowired instance of each Type
and register them in the TemplateFilters collection. An alternative to registering a single Type is to register
an entire Assembly, e.g:

Where it will search each Type in the Assembly for Template Filters and automatically register them.

Filter Resolution

Templates will use the first matching filter with the same name and argument count it can find by searching through all
filters registered in the TemplateFilters collection, so you could override default filters with the same name by
inserting your filters as the first item in the collection, e.g:

context.TemplateFilters.Insert(0, new MyTemplateFilters());

Auto coercion into Filter argument Types

A unique feature of Filters is that each of their arguments are automatically coerced into the filter argument Type using the
powerful conversion facilities built into ServiceStack's
Auto Mapping Utils and
Text Serializers which can deserialize most of .NET's primitive Types like
DateTime, TimeSpan, Enums, etc in/out of strings as well being able to convert a Collection into other Collection
Types and any Numeric Type into any other Numeric Type which is how, despite only accepting doubles:

double squared(double value) => value * value;

squared can also be used with any other .NET Numeric Type, e.g: byte, int, long, decimal, etc.
The consequence to this is that there's no method overloading in filters, filters are matched based on their name and their number of arguments
and each argument is automatically converted into its filter method Param Type before it's called.

Context Filters

Filters can also get access to the current scope by defining a TemplateScopeContext as it's first parameter which
can be used to access arguments in the current scope or add new ones as done by the assignTo filter:

Block Filters

Filters can also write directly into the OutputStream instead of being forced to return buffered output. A Block Filter
is declared by its Task return Type where instead of returning a value it instead writes directly to the
TemplateScopeContext OutputStream as seem with the implementation of the includeFile protected filter:

For maximum performance all default filters which perform any I/O use Block filters to write directly to the OutputStream
and avoid any blocking I/O or buffering.

Block Filters ends the filter chain

Block filters effectively end the Filter chain expression since they don't return any value that can be injected into
a normal filter. The only thing that can come after a Block Filter are other Block Filters or Filter Transformers.
If any are defined, the output of the Block Filter is buffered into a MemoryStream and passed into
the next Block Filter or Filter Transformer in the chain, its output is then passed into the next one in the chain if any,
otherwise the last output is written to the OutputStream.

An example of using a Block filter with a Filter Transformer is when you want include a markdown document and then
convert it to HTML using the markdown Filter Transformer before writing its HTML output to the OutputStream:

{{ 'doc.md' | includeFile | markdown }}

Capture Block Filter Output

You can also capture the output of a Block Filter and assign it to a normal argument by using the assignTo Block Filter: