Transformers

You can apply a chain of multiple Stream transformations to Template output using Transformers which are just functions that accept an Input Stream and return a modified Output Stream. The MarkdownPageFormat's TransformToHtml shows an example of a Transformer which converts Markdown Input and returns a Stream of HTML output:

public class MarkdownPageFormat : PageFormat
{
    private static readonly MarkdownSharp.Markdown markdown = new MarkdownSharp.Markdown();

    public static async Task<Stream> TransformToHtml(Stream markdownStream)
    {
        using (var reader = new StreamReader(markdownStream))
        {
            var md = await reader.ReadToEndAsync();
            var html = markdown.Transform(md);
            return MemoryStreamFactory.GetStream(html.ToUtf8Bytes());
        }
    }
}

Output Transformers

You can transform the entire output of a Template with Output Transformers which you would do if both your _layout and page both contain markdown, e.g:

var context = new TemplateContext {
    PageFormats = { new MarkdownPageFormat() }
}.Init();

context.VirtualFiles.WriteFile("_layout.md", @"
The Header

{{ page }}");

context.VirtualFiles.WriteFile("page.md",  @"
## {{ title }}

The Content");
PageResult with Output Transformer
var result = new PageResult(context.GetPage("page")) 
{
    Args = { {"title", "The Title"} },
    ContentType = MimeTypes.Html,
    OutputTransformers = { MarkdownPageFormat.TransformToHtml },
};

var html = await result.RenderToStringAsync();

After the Template is evaluated it's entire output gets passed into the chain of OutputTransformers defined, which in this case will send a MemoryStream of the generated Markdown Output into the MarkdownPageFormat.TransformToHtml transformer which returns a Stream of converted HTML which is what's written to the OutputStream.

Page Transformers

You can also apply Transformations to only the Page's output using Page Transformers which you would do if only the page was in Markdown and the _layout was already in HTML, e.g:

var context = new TemplateContext {
    PageFormats = { new MarkdownPageFormat() }
}.Init();

context.VirtualFiles.WriteFile("_layout.html", @"
<html>
  <title>{{ title }}</title>
</head>
<body>
  {{ page }}
</body>");

context.VirtualFiles.WriteFile("page.md",  @"
## Transformers

The Content");
PageResult with Page Transformer
var result = new PageResult(context.GetPage("page")) 
{
    Args = { {"title", "The Title"} },
    ContentType = MimeTypes.Html,
    PageTransformers = { MarkdownPageFormat.TransformToHtml },
};

var html = await result.RenderToStringAsync();

Filter Transformers

Filter Transformers are used to apply Stream Transformations to Block Filters which you could use if you only wanted to convert an embedded Markdown file inside a Page to HTML. You can register Filter Transformers in either the TemplateContext's or PageResult's FilterTransformers Dictionary by assigning it the name you want it available in your Templates under, e.g:

var context = new TemplateContext
{
    TemplateFilters = { new TemplateProtectedFilters() },
    FilterTransformers =
    {
        ["markdown"] = MarkdownPageFormat.TransformToHtml
    }
}.Init();

context.VirtualFiles.WriteFile("doc.md", "## The Heading

The Content");

context.VirtualFiles.WriteFile("page.html", "
<div id="content">
    {{ 'doc.md' | includeFile | markdown }}
</div>");
PageResult with Filter Transformer
var html = new PageResult(context.GetPage("page")).Result;

htmlencode

The htmlencode Filter Transformer is pre-registered in TemplateContext which lets you encode Block Filter outputs which is useful when you want to HTML Encode a text file before embedding it in the page, e.g:

{{ "page.txt" | includeFile | htmlencode }}

made with by ServiceStack