Skip to content

Latest commit

 

History

History
138 lines (99 loc) · 4.75 KB

how-to.md

File metadata and controls

138 lines (99 loc) · 4.75 KB

How to use

Stubble follows the mustache spec explicitly so anything that works in other spec compliant mustache libraries such as mustache.js, mustache.java and mustache.php should work without any issues.

The full spec can be found here.

Stubble Specifics

Stubble is designed to be as slim as possible providing almost no utility functions for finding templates or converting your data into the right format. That is left up to the user however extension packages will be provided in future for common use cases such as Json.Net and System.Data.

Standard Example Usecase

using Stubble.Core.Builders;
using System.IO;
using System.Text;

// Sync
public void SyncRender() {
  var stubble = new StubbleBuilder().Build();
  var myObj = new MyObj();
  using (StreamReader streamReader = new StreamReader(@".\Path\To\My\File.Mustache", Encoding.UTF8))
  {
      var output = stubble.Render(streamReader.ReadToEnd(), myObj);
      // Do Stuff
  }
}

// Async
public async Task RenderAsync() {
  var stubble = new StubbleBuilder().Build();
  var myObj = new MyObj();
  using (StreamReader streamReader = new StreamReader(@".\Path\To\My\File.Mustache", Encoding.UTF8))
  {
      var content = await streamReader.ReadToEndAsync();
      var output = await stubble.RenderAsync(content, myObj);
      // Do Stuff
  }
}

OR

var stubble = new StubbleBuilder().Build();
Dictionary<string, object> dataHash = GetMyData();

//Sync
var output  = stubble.Render("{{Foo}}", dataHash);

// Async
var output  = await stubble.RenderAsync("{{Foo}}", dataHash);

It's as simple as that.

Configuration

To configure your stubble instance you can provide a configuration function in which you set any specifics you like. An example of this is below:

var stubble = new StubbleBuilder()
  .Configure(settings => {
    settings.SetIgnoreCaseOnKeyLookup(true);
    settings.SetMaxRecursionDepth(512);
    settings.AddJsonNet(); // Extension method from extension library
  })
  .Build();

Dictionary<string, object> dataHash = GetMyData();
var output  = stubble.Render("{{Foo}}", dataHash);

Lambdas

Note: These details only affect the Stubble.Core renderer and not the compilation renderer since compilation does not currently support lambdas.

Stubble implements the mustache language extension for Lambdas which are anonymous functions which you can use to in your templates. There are two types of Lambdas in Stubble Tag Lambdas and Section Lambdas.

If the dynamic argument is defined, it is the context of the function much like using "this" however since the compiler can't know what you mean in your function the dynamic argument is used to be interrogated at runtime.

Interpolation: or how I learnt to return tags and love them

If you return tags from your lambda they will be expanded before being rendered. This way you can build new templates to return from your templates. My head hurts...

Tag Lambdas

Tag lambdas are rendered in place of the tag in the template. They have to be the type Func<dynamic, object> or Func<object>

Example

var obj = new {
   Bar = "Bar",
   Foo = new Func<dynamic, object>((dyn) => { return dyn.Bar; })
};

stubble.Render("{{Foo}}", obj); // Outputs: "Bar"

Section Lambdas

Section lambdas are used to wrap sections of a template. The contents of the section is passed into the lambda as an argument. They have to be one of the following types:

  • Func<dynamic, string, object>
  • Func<string, object>
  • Func<string, Func<string, string>, object>
  • Func<dynamic, string, Func<string, string>, object>

The signature with Func<string, string> as an argument will be provided a renderer that will render the passed template within the current context. This can be used for my dynamic templates.

Note: This is not particularly performant since this is an edge case and used in such scenarios. We would recommend performing any logic outside of your templates before rendering.

Example

var obj = new {
   Bar = "Bar",
   Foo = new Func<dynamic, string, object>((dyn, str) => { return str.Replace("World", dyn.Bar); })
};

stubble.Render("{{#Foo}} Hello World {{/Foo}}", obj); //Outputs: " Hello Bar "

var obj2 = new {
   Bar = "Bar",
   Foo = new Func<string, object>((str) => { return "Foo {{Bar}}"; })
};

stubble.Render("{{#Foo}} Hello World {{/Foo}}", obj2); //Outputs: "Foo Bar"

var obj3 = new {
   Bar = "Bar",
   Foo = new Func<string, Func<string, string>, object>((str, render) => { return "Foo " + render("{{Bar}}"); })
};

stubble.Render("{{#Foo}} Hello World {{/Foo}}", obj3); //Outputs: "Foo Bar"