TemplateContextYou may need to extend a TemplateContext to overrides some methods there, typically in cases you want:
ScriptNode AST node is evaluatedIObjectAccessor for non .NET, non Dictionary<string, object> in case you are looking to expose a specific object to the runtime that requires a specific access pattern. By overriding the method GetMemberAccessorImpl you can override this aspect.ToString(span, object) method to provide custom ToString for specifics .NET objects.ScriptObject advanced usagesIt is sometimes required for a custom function to have access to the current TemplateContext or to the access to original location of the text code, where a particular expression is occurring (via a SourceSpan that gives a line, column and sourcefile )
In the ScriptObject section we described how to easily import a custom function either by using a delegate or a pre-defined .NET static functions/properties.
In some cases, you also need to have access to the current TemplateContext and also, the current SourceSpan (original location position in the text template code).
By simply adding as a first parameter TemplateContext, and optionally as a second parameter, a SourceSpan a custom function can have access to the current evaluation context:
var scriptObject1 = new ScriptObject();
// Here, we can have access to the `TemplateContext`
scriptObject1.Import("contextAccess", new Func<TemplateContext, string>(templateContext => "Yes"));
IScriptCustomFunctionSome custom functions can require deeper access to the internals for exposing a function. Scriban provides the interface IScriptCustomFunction for this matter. If an object inherits from this interface and is accessed another ScriptObject, it will call the method IScriptCustomFunction.Invoke.
namespace Scriban.Runtime
{
/// <summary>
/// Allows to create a custom function object.
/// </summary>
public interface IScriptCustomFunction
{
/// <summary>
/// Calls the custom function object.
/// </summary>
/// <param name="context">The template context</param>
/// <param name="callerContext">The script node originating this call</param>
/// <param name="parameters">The parameters of the call</param>
/// <param name="blockStatement">The current block statement this call is made</param>
/// <returns>The result of the call</returns>
object Invoke(TemplateContext context, ScriptNode callerContext, ScriptArray parameters, ScriptBlockStatement blockStatement);
}
}
As you can see, the IScriptCustomFunction gives you access to:
TemplateContext evaluating the current TemplateTemplate that is calling this custom functions, so you can precisely get information about the location of the parameters in the original source code...etc.wrap statement)The include expression is typically implemented via a IScriptCustomFunction. You can have a look at the details here