Expressions: Mustache templates

How to use Mustache templates with PIP.Services.

Key takeaways

MustacheTemplate PIP.Services component used to construct and evaluate Mustache templates.
Basic constructors Helpers used to construct more complex templates.
template MustacheTemplate ‘s property used to create templates.
evaluate MustacheTemplate ‘s method used to validate Mustache templates.

Introduction

PIP.Services offers an implementation of a Mustache engine available in its Expressions module. This implementation of Mustache is enhanced with the addition of some helpers. In this tutorial, you will learn how to use the MustacheTemplate component, which can be used to evaluate Mustache templates. First, we will see its pre-requisites, then, we will learn some basic constructions supported by the component. Finally, we will see some examples of its usage.

Pre-requisites

In order to use the Mustache template library, we must first install the Expressions module by running the following command:

npm install pip-services3-expressions-nodex --save
dotnet add package PipServices3.Expressions
go get -u github.com/pip-services3-go/pip-services3-expressions-go@latest
dart pub add pip_services3_components
pip install pip_services3_expressions
Not available

Managing Mustache templates

PIP.Services uses a set of basic constructions to create Mustache-like templates. In this section, we will learn how to use them to build and evaluate different templates.

Basic constructions

The library supports the following injections and conditional blocks:

Variable {{{NAME}}}
Conditional (if) {{ #if VARIABLE }}Some value or {{{VARIABLE2}}} {{/if}}
Conditional negation (if – else) {{{#unless VARIABLE}}} Some value or {{{VARIABLE}}} {{{/unless}}}
If-else equivalent {{ #if VARIABLE }} Some value or {{{VARIABLE}}} {{/if}}{{{^VARIABLE}}} Some value or {{{VARIABLE}}} {{{/VARIABLE}}}

Pre-requisites

To use Mustache templates, we must import the MustacheTemplate class. The following command shows how to do this:

import { MustacheTemplate } from "pip-services3-expressions-nodex";
using PipServices3.Expressions.Mustache;
import (
	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)
import 'package:pip_services3_expressions/pip_services3_expressions.dart';
from pip_services3_expressions.mustache.MustacheTemplate import MustacheTemplate
Not available

Examples

Below are some examples of evaluations:

a) Variable

Variables that have a dictionary structure can be used to validate a template. The following example shows how to use the evaluate_with_variables method.

import { MustacheTemplate } from "pip-services3-expressions-nodex";


export function main() {
    // variable
    let template = new MustacheTemplate();
    template.template = "Hello, {{{NAME}}}";
    let variables = { "NAME": "Alex" };

    let result = template.evaluateWithVariables(variables);
    console.log(result);
}
using PipServices3.Expressions.Mustache;

using System;
using System.Collections.Generic;

namespace ExampleApp
{

    class Program
    {
        static void Main(string[] args)
        {
            // variable
            var template = new MustacheTemplate();
            template.Template = "Hello, {{{NAME}}}";
            var variables = new Dictionary<string, dynamic>{
                { "NAME", "Alex" },
            };
   
            var result = template.EvaluateWithVariables(variables);
            Console.WriteLine(result);
        }
    }
}

package main

import (
	"fmt"

	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)

func main() {
	// variable
	template := mustache.NewMustacheTemplate()
	template.SetTemplate("Hello, {{{NAME}}}")
	variables := map[string]string{
		"NAME": "Alex",
	}

	result, _ := template.EvaluateWithVariables(variables)

	fmt.Println(result)
}

import 'package:pip_services3_expressions/pip_services3_expressions.dart';

void main(List<String> arguments) {
  // variable
  var template = MustacheTemplate();
  template.template = 'Hello, {{{NAME}}}';
  var variables = {'NAME': 'Alex'};

  var result = template.evaluateWithVariables(variables);
  print(result);
}

# variable
template = MustacheTemplate()
template.template = "Hello, {{{NAME}}}"
variables = {
    'NAME': 'Alex',
}

result = template.evaluate_with_variables(variables)
print(result)
Not available

Which produces the following output:

figure 1
b) Conditional

To create a conditional template, we use the #if helper. An example of its usage will be a template that creates the message “Hello, (Name)”. The variable used has two fields namely name and exclamation. The last one represents a Boolean value which if it is set to true, the message will show an added exclamation mark.

Note: In general, any value that is interpreted by a specific language as false when the “If” operator is executed will be interpreted as false. Otherwise, it is considered true. For example, in Python, false values are None, False, 0, and ‘’. Node.js adds an empty list to them.

The following example shows how to create a conditional template:

import { MustacheTemplate } from "pip-services3-expressions-nodex";


export function main() {
    // variable
    let template = new MustacheTemplate();
    template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}";
    let variables = { "NAME": "Alex" , "EXCLAMATION": "1" };

    let result = template.evaluateWithVariables(variables);
    console.log(result);
}

using PipServices3.Expressions.Mustache;

using System;
using System.Collections.Generic;

namespace ExampleApp
{

    class Program
    {
        static void Main(string[] args)
        {
            // variable
            var template = new MustacheTemplate();
            template.Template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}";
            var variables = new Dictionary<string, dynamic>{
                { "NAME", "Alex" },
                {"EXCLAMATION", "1" }
            };
   
            var result = template.EvaluateWithVariables(variables);
            Console.WriteLine(result);
        }
    }
}

package main

import (
	"fmt"

	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)

func main() {
	// conditional construction
	template := mustache.NewMustacheTemplate()
	template.SetTemplate("Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}")
	variables := map[string]string{
		"NAME":        "Alex",
		"EXCLAMATION": "1",
	}

	result, _ := template.EvaluateWithVariables(variables)

	fmt.Println(result)
}

import 'package:pip_services3_expressions/pip_services3_expressions.dart';

void main(List<String> arguments) {
  // variable
  var template = MustacheTemplate();
  template.template = 'Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}';
  var variables = {'NAME': 'Alex', 'EXCLAMATION': '1'};

  var result = template.evaluateWithVariables(variables);
  print(result);
}

# conditional construction
template = MustacheTemplate()
template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}"
variables = {
    'NAME': 'Alex',
    'EXCLAMATION': '1'
}

result = template.evaluate_with_variables(variables)
print(result)
Not available

After running the above code, we will see the following result:

figure 2

And, if we set the exclamation to None, we will get a message without an exclamation mark:

import { MustacheTemplate } from "pip-services3-expressions-nodex";


export function main() {
    // variable
    let template = new MustacheTemplate();
    template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}";
    let variables = { "NAME": "Alex" , "EXCLAMATION": false };

    let result = template.evaluateWithVariables(variables);
    console.log(result);
}

using PipServices3.Expressions.Mustache;

using System;
using System.Collections.Generic;

namespace ExampleApp
{

    class Program
    {
        static void Main(string[] args)
        {
            // variable
            var template = new MustacheTemplate();
            template.Template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}";
            var variables = new Dictionary<string, dynamic>{
                { "NAME", "Alex" },
                {"EXCLAMATION", false }
            };
   
            var result = template.EvaluateWithVariables(variables);
            Console.WriteLine(result);
        }
    }
}

package main

import (
	"fmt"

	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)

func main() {
	// conditional construction
	template := mustache.NewMustacheTemplate()
	template.SetTemplate("Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}")
	variables := map[string]string{
		"NAME":        "Alex",
		"EXCLAMATION": "",
	}

	result, _ := template.EvaluateWithVariables(variables)

	fmt.Println(result)
}

import 'package:pip_services3_expressions/pip_services3_expressions.dart';

void main(List<String> arguments) {
  // variable
  var template = MustacheTemplate();
  template.template = 'Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}';
  var variables = {'NAME': 'Alex', 'EXCLAMATION': false};

  var result = template.evaluateWithVariables(variables);
  print(result);
}


# conditional construction
template = MustacheTemplate()
template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}"
variables = {
    'NAME': 'Alex',
    'EXCLAMATION': False
}

result = template.evaluate_with_variables(variables)
print(result)
Not available
figure 3
c) Conditional negation (if-else)

Now, we want to modify our program to define a template that if the exclamation value is equal to false, it adds a dot at the end. Otherwise, it ends with an exclamation mark.

In the first case, our code is:

import { MustacheTemplate } from "pip-services3-expressions-nodex";


export function main() {
    // "if else" construction
    let template = new MustacheTemplate();
    template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}";
    let variables = { "NAME": "Alex" , "EXCLAMATION": false };

    let result = template.evaluateWithVariables(variables);
    console.log(result);
}

using PipServices3.Expressions.Mustache;

using System;
using System.Collections.Generic;

namespace ExampleApp
{

    class Program
    {
        static void Main(string[] args)
        {
            // "if else" construction
            var template = new MustacheTemplate();
            template.Template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}";
            var variables = new Dictionary<string, dynamic>{
                { "NAME", "Alex" },
                {"EXCLAMATION", false }
            };
   
            var result = template.EvaluateWithVariables(variables);
            Console.WriteLine(result);
        }
    }
}

package main

import (
	"fmt"

	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)

func main() {
	// "if else" construction
	template := mustache.NewMustacheTemplate()
	template.SetTemplate("Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}")
	variables := map[string]string{
		"NAME":        "Alex",
		"EXCLAMATION": "",
	}

	result, _ := template.EvaluateWithVariables(variables)

	fmt.Println(result)
}

import 'package:pip_services3_expressions/pip_services3_expressions.dart';

void main(List<String> arguments) {
  // "if else" construction
  var template = MustacheTemplate();
  template.template =
      'Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}';
  var variables = {'NAME': 'Alex', 'EXCLAMATION': false};

  var result = template.evaluateWithVariables(variables);
  print(result);
}


# "if else" construction
template = MustacheTemplate()
template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}"
variables = {
    'NAME': 'Alex',
    'EXCLAMATION': False
}

result = template.evaluate_with_variables(variables)
print(result)
Not available

And the result is:

figure 4

In the second case, we just modify the value of EXCLAMATION to true,

import { MustacheTemplate } from "pip-services3-expressions-nodex";


export function main() {
    // "if else" construction
    let template = new MustacheTemplate();
    template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}";
    let variables = { "NAME": "Alex" , "EXCLAMATION": "1" };

    let result = template.evaluateWithVariables(variables);
    console.log(result);
}

using PipServices3.Expressions.Mustache;

using System;
using System.Collections.Generic;

namespace ExampleApp
{

    class Program
    {
        static void Main(string[] args)
        {
            // "if else" construction
            var template = new MustacheTemplate();
            template.Template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}";
            var variables = new Dictionary<string, dynamic>{
                { "NAME", "Alex" },
                {"EXCLAMATION", "1" }
            };
   
            var result = template.EvaluateWithVariables(variables);
            Console.WriteLine(result);
        }
    }
}

package main

import (
	"fmt"

	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)

func main() {
	// "if else" construction
	template := mustache.NewMustacheTemplate()
	template.SetTemplate("Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}")
	variables := map[string]string{
		"NAME":        "Alex",
		"EXCLAMATION": "1",
	}

	result, _ := template.EvaluateWithVariables(variables)

	fmt.Println(result)
}

import 'package:pip_services3_expressions/pip_services3_expressions.dart';

void main(List<String> arguments) {
  // "if else" construction
  var template = MustacheTemplate();
  template.template =
      'Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}';
  var variables = {'NAME': 'Alex', 'EXCLAMATION': '1'};

  var result = template.evaluateWithVariables(variables);
  print(result);
}


# "if else" construction
template = MustacheTemplate()
template.template = "Hello, {{{NAME}}}{{ #if EXCLAMATION }}!{{/if}}{{{^EXCLAMATION}}}.{{{/EXCLAMATION}}}"
variables = {
    'NAME': 'Alex',
    'EXCLAMATION': True
}

result = template.evaluate_with_variables(variables)
print(result)
Not available

and we get a string ended in an exclamation mark.

figure 5
d) If-else equivalent

We can also create an equivalent if-else structure by using the #unless helper. The following code shows how to do this:

import { MustacheTemplate } from "pip-services3-expressions-nodex";


export function main() {
    // equivalent constructions
    let template = new MustacheTemplate();
    template.template = "Hello, {{{NAME}}}{{{#unless EXCLAMATION}}}.{{{/unless}}}";
    let variables = { "NAME": "Alex" , "EXCLAMATION": "1" };

    let result = template.evaluateWithVariables(variables);
    console.log(result);
}

using PipServices3.Expressions.Mustache;

using System;
using System.Collections.Generic;

namespace ExampleApp
{

    class Program
    {
        static void Main(string[] args)
        {
            // equivalent constructions
            var template = new MustacheTemplate();
            template.Template = "Hello, {{{NAME}}}{{{#unless EXCLAMATION}}}.{{{/unless}}}";
            var variables = new Dictionary<string, dynamic>{
                { "NAME", "Alex" },
                {"EXCLAMATION", "1" }
            };
   
            var result = template.EvaluateWithVariables(variables);
            Console.WriteLine(result);
        }
    }
}

package main

import (
	"fmt"

	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)

func main() {
	// equivalent constructions
	template := mustache.NewMustacheTemplate()
	template.SetTemplate("Hello, {{{NAME}}}{{{#unless EXCLAMATION}}}.{{{/unless}}}")
	variables := map[string]string{
		"NAME":        "Alex",
		"EXCLAMATION": "1",
	}

	result, _ := template.EvaluateWithVariables(variables)

	fmt.Println(result)
}

import 'package:pip_services3_expressions/pip_services3_expressions.dart';

void main(List<String> arguments) {
  // equivalent constructions
  var template = MustacheTemplate();
  template.template =
      'Hello, {{{NAME}}}{{{#unless EXCLAMATION}}}.{{{/unless}}}';
  var variables = {'NAME': 'Alex', 'EXCLAMATION': '1'};

  var result = template.evaluateWithVariables(variables);
  print(result);
}


# equivalent constructions
template = MustacheTemplate()
template.template = "Hello, {{{NAME}}}{{{#unless EXCLAMATION}}}.{{{/unless}}}"
variables = {
    'NAME': 'Alex',
    'EXCLAMATION': True    
}

result = template.evaluate_with_variables(variables)
print(result)
Not available
figure 6
e) Using default variables

We can also assign default variables to a template and use the evaluate function to check their values. The following is an example of this:

import { MustacheTemplate } from "pip-services3-expressions-nodex";


export function main() {
    // equivalent constructions
    let template = new MustacheTemplate();
    template.template = "Hello Mr, {{{NAME}}} {{{SURNAME}}}";
    let variables = { "NAME": "Joe", "SURNAME": "Smith" , "EXCLAMATION": false };
    
    for(let key in variables)
        template.defaultVariables[key] = variables[key];


    let result = template.evaluate();
    console.log(result);
}
using PipServices3.Expressions.Mustache;

using System;
using System.Collections.Generic;

namespace ExampleApp
{

    class Program
    {
        static void Main(string[] args)
        {
            // equivalent constructions
            var template = new MustacheTemplate();
            template.Template = "Hello Mr, {{{NAME}}} {{{SURNAME}}}";
            var variables = new Dictionary<string, dynamic>{
                { "NAME", "Joe" },
                { "SURNAME", "Smith" },
                { "EXCLAMATION", false }
            };

            foreach (var varibale in variables)
                template.DefaultVariables[varibale.Key] = varibale.Value;

            var result = template.Evaluate();
            Console.WriteLine(result);
        }
    }
}

package main

import (
	"fmt"

	mustache "github.com/pip-services3-go/pip-services3-expressions-go/mustache"
)

func main() {
	variable := map[string]string{
		"NAME":        "Joe ",
		"SURNAME":     "Smith",
		"ESCLAMATION": "",
	}
	template := mustache.NewMustacheTemplate()
	template.SetTemplate("Hello Mr, {{{NAME}}} {{{SURNAME}}}")
	template.SetDefaultVariables(variable)
	result, _ := template.Evaluate()

	fmt.Println(result)
}

import 'package:pip_services3_expressions/pip_services3_expressions.dart';

void main(List<String> arguments) {
  // equivalent constructions
  var template = MustacheTemplate();
  template.template = 'Hello Mr, {{{NAME}}} {{{SURNAME}}}';
  var variables = {'NAME': 'Joe', 'SURNAME': 'Smith', 'EXCLAMATION': false};

  template.defaultVariables.addEntries(variables.entries);

  var result = template.evaluate();
  print(result);
}

variable = {
    'NAME': 'Joe ',
    'SURNAME': 'Smith',
    'ESCLAMATION': None
}

template = MustacheTemplate()
template.template = "Hello Mr, {{{NAME}}} {{{SURNAME}}}"
template.default_variables = variable
result = template.evaluate()
print(result)
Not available

Which will result in:

figure 6

Moreover, as variables have a dictionary structure, we can also define the default value as:

template.defaultVariables['NAME'] = 'Joe';
template.defaultVariables['SURNAME'] = 'Smith';

template.DefaultVariables["NAME"] = "Joe";
template.DefaultVariables["SURNAME"] = "Smith";

template.SetDefaultVariables(
	map[string]string{
		"NAME":    "Joe ",
		"SURNAME": "Smith",
	},
)

template.defaultVariables['NAME'] = 'Joe';
template.defaultVariables['SURNAME'] = 'Smith';

template.default_variables['NAME'] = 'Joe'
template.default_variables['SURNAME'] = 'Smith'

Not available
f) Clearing the template

The class offers the clear method to erase all the information stored in a template. The syntax is as follows:

template.clear();
template.Clear();
template.Clear()
template.clear();
template.clear()
Not available

Wrapping up

In this tutorial, we have seen how to manage basic Mustache templates. We have learned the basic constructions handled by PIP.Services and seen examples of each of them. We have also learned how to use default variables and how to clear a MustacheTemplate object.