Waterpipe Template Engine - misonou/codeless-data GitHub Wiki

This is C# port of the JavaScript template engine Waterpipe.

For syntax and built-in function explanation please refer to the original library noted above.

Usage

Waterpipe.Evaluate("The value is {{value}}.", new { value = 1 }); // The value is 1.

The port mimic JavaScript behaviors on data values through the class PipeValue. So that both the templates and extensions work as close as the original engine.

Writing Pipe Function

A pipe function is simply a method registered on the Waterpipe class. The first argument is the piped value; while the remaining arguments are taken from the pipe.

Waterpipe.RegisterFunction("bark", 
    (name, pet) => String.Concat(name, "'s ", pet, " barks!"));

Variadic Pipe Function

A variadic pipe function can take any number of arguments from the pipe.

Waterpipe.RegisterFunction("printargs", (PipeContext pipe) => {
    List<object> output = new List<object>();
    int count = (int)pipe.TakeArgument();
    for (var i = 0; i < count; i++) {
        if (pipe.HasArguments()) {
            output.push(pipe.TakeArgument());
        }
    }
    return String.Join(" ", output);
});

// {{printargs 3 foo bar baz}} -> "foo bar baz"
// {{printargs 3 foo bar baz upper}} -> "FOO BAR BAZ"

A variadic pipe function can also take a function argument by PipeContext.TakeFunction(). If there is no proper set of pipe arguments to form a function argument, it will return null.

Waterpipe.RegisterFunction("dosomething", (PipeContext pipe) => {
    PipeLambda fn = pipe.TakeFunction();
    return fn.Invoke(pipe.Value);
});

// Input:
//     new { value = 1 }
//
// {{value dosomething [ + 1 ]}} -> "2"

Wildcard Pipe Function

If generic shorthand for a pipe function is desired, it can be registered through Waterpipe.RegisterFunctionResolver.

It catches any unresolved pipe function names and returns a pipe function on the fly.

Waterpipe.RegisterFunctionResolver((name, getNext) => {
    if (name[0] == ':') {
        return PipeFunction.Create((PipeValue value) => { /* do your stuff */ });
    }
    return getNext()(name, getNext);
});
⚠️ **GitHub.com Fallback** ⚠️