Interfaces

Project

Pages Html

NuGet packageOwin.Framework.Pages.Html
GitHub sourceOwinFramework.Pages.Html

Home |  Readme

Mustache parser reference | The OWIN FRamework

The Mustache template parser

The Mustache template parser takes template files and replaces text within double curly braces with data. It can be used to parse Html, CSS or Javascript templates.

Mustache is a well established library that contains alot of functionallity. This parser is not an attempt to duplicate or replace Mustache, but rather to provide a simple server-side data binding that is somewhat familiar to developers that already know Mustache. As such this is a subset of the features provided by the full Mustache library.

Below is an example of a valid template:

{{VerticalText = Sample1.SampleDataProviders.VerticalText}}
<svg width="{{VerticalText: Width}}" height="{{VerticalText: Height}}">
  <style>
    text { {{VerticalText: TextStyle}} }
  </style>
  <rect width="100%" height="100%" fill="{{VerticalText: Background}}" />
  <g transform="translate({{VerticalText: X}},{{VerticalText: Y}}) rotate(-90)">
    <text class="title" textLength="{{VerticalText: TextHeight}}" lengthAdjust="spacingAndGlyphs">{{VerticalText: Caption}}</text>
  </g>
</svg>

This example happens to be SVG but any language that does not conflict with double curly braces will work.

Simple Data Binding

The simplest thing you can do is put a class name and a property name separated by a colon inside double curly braces. This will cause the template to have a dependency on the type of data identified by the class name, and each time the template is rendered it will look for this type of data in the render context and then

Note that the classes and properties in binding expression are resolved using reflection. This might seem slow, except that this resolution only happens once when the template is parsed, and reading the property on each rendering operation is just as fast as compiled code.

Class Name Aliases

To avoid repeating the full class name over and over you can define an alias for the class at the start of the template. You do this by putting the alias name and the full class name separated by and equals sign within double curly braces at the top of the template.

Class name aliases must be the very first thing in the template. You can not add these definitions further down the file.

Interfaces

You are not restricted to using class names in your binding expressions, any type will work, it just needs to have a data provider defined within your application.

Repeating

To repeat a peice of content for each item in a list, use this syntax:

{{Address=MyApp.DataModels.IAddress}}
{{#Address}}<p>{{Address:Street}},{{Address:City}},{{Address:Zip}}</p>{{/Address}}

This example creates a template that has a dependency on IList<MyApp.DataModels.IAddress>. It will look for IList<MyApp.DataModels.IAddress> in the rendering conttext and repeat the piece between {{#Address}} and {{/Address}} for each address in the list.

Note that your data provider must add an IList<T> to the data context, other types of collection will not work! In particular you should not add List<T>.

Conditional Rendering

To optionally include content in the page use this syntax:

{{Address=MyApp.DataModels.IAddress}}
{{Config=MyApp.DataModels.IConfiguration}}
{{?Config:ShowAddress}}
  {{#Address}}<p>{{Address:Street}},{{Address:City}},{{Address:Zip}}</p>{{/Address}}
{{/Config:ShowAddress}}

In this syntax, the ? indicates that this is a conditional section and is followed by a data type, a colon, and a property name. The example above assumes that you have a data provider that can provide an instance of MyApp.DataModels.IConfiguration and that this interface has a ShowAddress property.

The property that is referenced is evaluated for truthiness in a similar way to how Javascript works, i.e. all non-empty strings are considered true and all non-zero numeric values are true. You can also use boolean values of course.
You can also invert the condition using ! instead of ?, for example
{{!Config.ShowAddress}}Address redacted{{/Config.ShowAddress}}