Skip to content
JPVenson edited this page May 10, 2022 · 9 revisions

Template Partials

You can define an block of Morestachio code with {{#DECLARE name}} ... {{/DECLARE}} and insert this code everywhere with {{#Import Name}}. You can ether use an string or an full Expression to import ether by using a static name like {{#Import 'Name'}} or use an expression {{#Import data.Name}}

While you are in an Partial you can access the $recusion variable to determine how deeply nested you currently are and also the $name variable that stores the evaluated name of the current partial.

It is also possible to create recursive partials by including the partial in itself: Example:

{{#DELCARE PartialName}}
   {{$recursion}}
   {{#IF $recursion.LessThen(10)}}
      {{#IMPORT 'PartialName'}}
   {{/rec}}
{{/DECLARE}}
{{#IMPORT 'PartialName'}}

The maximum level of recursion is limited and can be set by the ParserOptionsBuilder.WithPartialStackSize(uint) (Default is 255). Do control what happens when the limit is reached you can choose to ether throw an exception or just stop the nested execution and continue with the next element in order. This is set by ParserOptionsBuilder.WithStackOverflowBehavior() (Default is PartialStackOverflowBehavior.FailWithException).

It is also possible to supply external templates as partials for your template or entirely provider your own, as partials can be managed by the ParserOptionsBuilder.WithPartialsStore. This is optional and the property can also be null.

Import #With

The #Import tag also has an option for setting the context that should be used to render the partial with. By setting the #WITH option you can supply an expression that will be used. Example

{{data.sub.value}} <-- there is an property path at the current level
{{#DELCARE PartialName}}

{{/DECLARE}}
{{#IMPORT 'PartialName' #WITH data.sub}} <-- this sets the contect of the partial to data.sub. this is essentially the same as writing:

{{#SCOPE data.sub}}
   {{#IMPORT 'PartialName'}}
{{/SCOPE}}

File Backed Partial Store

If you have seperated your partials into individual files, you can use the FileSystemPartialStore. It loads partials directly from a FileSystem.

Example File structure

/youProgram.exe
/templates/template.mdoc
/templates/partials/header.mdoc <-- contents: HELLO HEADER FROM PARTIAL
/templates/partials/footer.mdoc <-- contents: HELLO FOOTER FROM PARTIAL

Example Setup

var document = await ParserOptionsBuilder
    .New()
    .WithTemplate(template)
    .WithFileSystemPartialStore(directoryPath: "/templates", searchPattern: "*.mdoc", ignoreExtension: false, ignoreFileStructure: false)
    .ParseAndBuildAsync();
await document.CreateAnStringifyAsync();

Example template.mdoc

{{#IMPORT 'partials/header.mdoc'}} <-- if you have set the "ignoreExtension" parameter you can omit '.mdoc'. If you have set the "ignoreFileStructure" you can also omit the path 'partials/'
hello world
{{#IMPORT 'partials/footer.mdoc'}}

this will output:

HELLO HEADER FROM PARTIAL
hello world
HELLO FOOTER FROM PARTIAL