There are lots of different ways of defining metadata as atomic values, complex objects, or powerful lazily evaluated scripts and delegates.
Generally, metadata can be any instance of any type. Statiq's powerful type conversion will help convert the metadata object to whatever type you need when you retrieve the value. Sometimes though, you need to define metadata that's a little more powerful. The sections below describe types of metadata values that are treated separately.
Computed Values
There are many cases where being able to define metadata as a computed value can be valuable. You can define computed metadata with "fat arrow" syntax. For example, placing this in the front matter of a document will result in an int
of "3" being returned for the "MyNumber" metadata key:
MyNumber: => 1 + 2
---
My number is <?#= MyNumber /?>.
The actual value should be a string (the YAML syntax above assumes a string value) that starts with =>
and is a full C# script. It can even include multiple statements:
MyNumber: "=> { int x = 1 + 2; int y = x; return y; }"
The script also has access to a number of predefined global properties available to it (see the ScriptBase
class in Statiq.Core
for all script properties):
ExecutionState
contains the currentIExecutionState
object.Context
(and thectx
shorthand) contain the current execution context.Document
(and thedoc
shorthand) contain the current document.PipelineName
: Gets the name of the currently executing pipeline.Pipeline
: Gets the currently executing pipeline.Phase
: Gets the currently executing phase of the current pipeline.Parent
: Gets the parent execution context if currently in a nested module.Module
: Gets the current executing module.Inputs
: The collection of input documents to the current module.
In addition, all metadata conversion methods are exposed as global methods. For example, if a document has another metadata value called Foo
and you wanted to get the int
value of that in another metadata value you could write something like this in your front matter:
Bar: => GetInt("Foo") + 2
Configuration Delegates
Another way of accessing the current document or execution context while computing a lazy metadata value is to use a configuration delegate. When an instance of IConfig
is added as a metadata value, it will be evaluated on every request for that value.
Lazy Values
In more advanced scenarios you sometimes want to defer figuring out the value of a metadata item until it’s accessed. This can help when the data to determine the value isn’t available yet, when computing the value would be expensive and you don’t know if it’ll actually need to be accessed, or you want to compute a fresh value each time it’s accessed. This can be accomplished by implementing IMetadataValue
. If an object that implements that interface is added as a metadata value, it’s object Get(IMetadata metadata)
method will be called when the value is requested (the metadata
argument is the current metadata object, for example the document).