Expression Options
Expression options configure the built-in expression engine and allow custom functions or operators to be added for use in template expressions ({{...}}).
Configuration Structure
{
"Scryber": {
"Expressions": {
"UseStandardFunctions": true,
"AllowEval": true,
"IsCaseSensitive": false,
"Register": [
{
"Name": "myFunc",
"Type": "Function",
"FunctionType": "MyNamespace.MyCustomFunction",
"FunctionAssembly": "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"Override": false,
"Enabled": true
}
]
}
}
}
Top-Level Properties
| Property | Type | Default | Description |
|---|---|---|---|
UseStandardFunctions |
bool | true |
Load the 90+ built-in expression functions (string, math, date, collection, etc.) |
AllowEval |
bool | true |
Allow dynamic expression evaluation at runtime |
IsCaseSensitive |
bool | false |
Whether function name lookups are case-sensitive |
Register[] |
array | [] |
Custom function and operator registrations |
Custom Registration Properties
| Property | Type | Required | Description |
|---|---|---|---|
Name |
string | Yes | Name used to call the function or operator in template expressions |
Type |
string | Yes | Function or Operator |
FunctionType |
string | Yes | Fully qualified type name of the implementation class |
FunctionAssembly |
string | Yes | Full assembly name with version and public key token |
Override |
bool | No | If true, replaces an existing function or operator with the same name. Default false |
Enabled |
bool | No | Set to false to disable without removing the entry. Default true |
Adding Custom Functions in Code
Use CustomFunctionOption to register functions or operators before any documents are parsed.
Register by type name
var config = Scryber.ServiceProvider.GetService<IScryberConfigurationService>();
config.ExpressionOptions.Register ??= new List<CustomFunctionOption>();
config.ExpressionOptions.Register.Add(new CustomFunctionOption(
name: "myFunc",
type: CustomFunctionType.Function,
typeName: "MyNamespace.MyCustomFunction",
assemblyName: "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
));
Register with an existing instance
If you already have an instance (useful when the class has constructor dependencies), the type and assembly names are inferred automatically:
var config = Scryber.ServiceProvider.GetService<IScryberConfigurationService>();
config.ExpressionOptions.Register ??= new List<CustomFunctionOption>();
config.ExpressionOptions.Register.Add(new CustomFunctionOption(
name: "myFunc",
type: CustomFunctionType.Function,
functionInstance: new MyNamespace.MyCustomFunction(myDependency)
));
Replacing a built-in function
Set forceOverride: true to replace an existing function with the same name:
config.ExpressionOptions.Register.Add(new CustomFunctionOption(
name: "concat",
type: CustomFunctionType.Function,
typeName: "MyNamespace.MyConcatReplacement",
assemblyName: "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
forceOverride: true
));
Registering a custom operator
config.ExpressionOptions.Register.Add(new CustomFunctionOption(
name: "??=",
type: CustomFunctionType.Operator,
typeName: "MyNamespace.MyNullCoalesceAssignOperator",
assemblyName: "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
));
Implementing a Custom Function
Custom functions must implement the expression function interface used by the Scryber expression engine. The function is invoked during data binding whenever the registered name appears in a template expression.
using Scryber.Expressive.Expressions;
using Scryber.Expressive.Expressions.Functions;
namespace MyNamespace
{
public class MyCustomFunction : FunctionBase
{
public override string Name => "myFunc";
public override object Evaluate(IExpression[] parameters, IVariableCollection variables,
Context context)
{
// Evaluate the first parameter
var input = parameters[0].Evaluate(variables, context);
// Your custom logic here
return input?.ToString()?.ToUpperInvariant();
}
}
}
Template usage once registered:
<p>{{myFunc(model.name)}}</p>
Disabling Standard Functions
If you want a minimal expression engine without the built-in function library:
{
"Scryber": {
"Expressions": {
"UseStandardFunctions": false
}
}
}
Only functions explicitly listed in Register will be available.
Related Documentation
- Configuration Structure - Full configuration file overview
- Namespace Registration - Registering custom components
- Image Factories - Custom image loading
- Font Configuration - Custom font registration