Script Plugins

Similar to using Plugins in ServiceStack to easily add functionality to a ServiceStack AppHost, you can encapsulate a suite of functionality that can be easily added to extend a ScriptContext with related functionality, e.g: You can add Markdown functionality to your scripts with:

var context = new ScriptContext {
    Plugins = { 
        new MarkdownScriptPlugin { 
            RegisterPageFormat = false
        } 
    } 
}.Init();

Which will register Markdown filter transformers, script method and script block with our ScriptContext:

public class MarkdownScriptPlugin : IScriptPlugin
{
    public bool RegisterPageFormat { get; set; } = true;

    public void Register(ScriptContext context)
    {
        if (RegisterPageFormat)
            context.PageFormats.Add(new MarkdownPageFormat());
        
        context.FilterTransformers["markdown"] = MarkdownPageFormat.TransformToHtml;
        
        context.ScriptMethods.Add(new MarkdownScriptMethods());

        ScriptConfig.DontEvaluateBlocksNamed.Add("markdown");
        
        context.ScriptBlocks.Add(new MarkdownScriptBlock());
    }
}

Creating Plugins

Plugin are simply classes that implement IScriptPlugin interface and its Register() method to extend the ScriptContext with additional functionality we want to make available:

public interface IScriptPlugin
{
    void Register(ScriptContext context);
}

Plugins can implement the interfaces below if they need to run custom logic before and after plugins are registered:

// Run before plugins are loaded:
public interface IScriptPluginBefore
{
    void BeforePluginsLoaded(ScriptContext context);
}

// Run after plugins are loaded:
public interface IScriptPluginAfter
{
    void AfterPluginsLoaded(ScriptContext context);
}

Pre-registered Plugins in ScriptContext

Pre-registered plugins are useful when you want to easily remove a pre-registered suite of functionality, e.g:

var context = new ScriptContext {
        //...
    }
    .RemovePlugins(x => x is DefaultScriptBlocks) // Remove default blocks
    .RemovePlugins(x => x is HtmlScriptBlocks)    // Remove all html blocks
    .Init();

DefaultScriptBlocks

The Default Script Blocks contain all the statement functionality in #Script which includes:

public class DefaultScriptBlocks : IScriptPlugin
{
    public void Register(ScriptContext context)
    {
        context.ScriptBlocks.AddRange(new ScriptBlock[] {
            new IfScriptBlock(),
            new EachScriptBlock(),
            new RawScriptBlock(),
            new CaptureScriptBlock(), 
            new PartialScriptBlock(),
            new WithScriptBlock(),
            new NoopScriptBlock(),
        });
    }
}

HtmlScriptBlocks

The purpose of the HTML Script Blocks is to pack a suite of generically useful functionality commonly used when generating html. All html blocks inherit the same functionality with blocks registered for the most popular HTML elements, currently:

public class HtmlScriptBlocks : IScriptPlugin
{
    /// <summary>
    /// Usages: {{#ul {each:items, class:'nav'} }} <li>{{it}}</li> {{/ul}}
    /// </summary>
    
    public void Register(ScriptContext context)
    {
        context.ScriptBlocks.AddRange(new ScriptBlock[] {
            new ScriptUlBlock(),
            new ScriptOlBlock(),
            new ScriptLiBlock(),
            new ScriptDivBlock(),
            new ScriptPBlock(), 
            new ScriptFormBlock(), 
            new ScriptInputBlock(), 
            new ScriptSelectBlock(), 
            new ScriptOptionBlock(),
            new ScriptTextAreaBlock(), 
            new ScriptButtonBlock(), 
            new ScriptTableBlock(),
            new ScriptTrBlock(),
            new ScriptTdBlock(),
            new ScriptTHeadBlock(),
            new ScriptTBodyBlock(),
            new ScriptTFootBlock(),
            new ScriptDlBlock(), 
            new ScriptDtBlock(), 
            new ScriptDdBlock(), 
            new ScriptSpanBlock(),
            new ScriptABlock(),
            new ScriptImgBlock(), 
            new ScriptEmBlock(), 
            new ScriptBBlock(), 
            new ScriptIBlock(), 
            new ScriptStrongBlock(), 
        });
    }
}

Pre-registered Plugins in SharpPagesFeature

The SharpPagesFeature in ServiceStack.dll has access to more dependencies than ScriptContext and is able to pre-register more functionality by default including:

ServiceStackScriptBlocks

Containing the {{#minifyjs}}{{/minifyjs}}, {{#minifycss}}{{/minifycss}} and {{#minifyhtml}}{{/minifyhtml}} for minifying its contents:

public class ServiceStackScriptBlocks : IScriptPlugin
{
    public void Register(ScriptContext context)
    {
        context.ScriptBlocks.AddRange(new ScriptBlock[] {
            new MinifyJsScriptBlock(), 
            new MinifyCssScriptBlock(), 
            new MinifyHtmlScriptBlock(), 
        });
    }
}

MarkdownScriptPlugin

Adds Markdown supports to Sharp Pages by default:

public class MarkdownScriptPlugin : IScriptPlugin
{
    public bool RegisterPageFormat { get; set; } = true;

    public void Register(ScriptContext context)
    {
        if (RegisterPageFormat)
            context.PageFormats.Add(new MarkdownPageFormat());
        
        context.FilterTransformers["markdown"] = MarkdownPageFormat.TransformToHtml;
        
        context.ScriptMethods.Add(new MarkdownScriptMethods());

        ScriptConfig.DontEvaluateBlocksNamed.Add("markdown");
        
        context.ScriptBlocks.Add(new MarkdownScriptBlock());
    }
}

Added using:

Plugins.Add(new MarkdownScriptPlugin { RegisterPageFormat = false });

Available Plugins

List of available plugins that's not pre-registered anywhere include:

ProtectedScriptBlocks

public class ProtectedScriptBlocks : IScriptPlugin
{
    public void Register(ScriptContext context)
    {
        context.ScriptBlocks.AddRange(new ScriptBlock[] {
            new EvalScriptBlock(), // evalTemplate script method has same functionality
        });
    }
}

Although generally not required as evalTemplate script method registered by default has equivalent functionality.

made with by ServiceStack