mstch/README.md
2015-04-24 15:51:41 +02:00

4.5 KiB

mstch - {{mustache}} templates in C++11

mstch logo

mstch is a complete implementation of {{mustache}} templates using modern C++.

Build Status

Supported features

mstch supports the complete feature set described in the mustache(5) manpage:

  • JSON-like data structure using Boost.Variant
  • variables, sections, inverted sections
  • partials
  • changing the delimiter
  • C++11 lambdas
  • C++ objects as view models

Basic usage

#include <iostream>
#include <mstch/mstch.hpp>

int main() {
  std::string view{"{{#names}}Hi {{name}}!\n{{/names}}"};
  mstch::map context{
    {"names", mstch::array{
      mstch::map{{"name", std::string{"Chris"}}},
      mstch::map{{"name", std::string{"Mark"}}},
      mstch::map{{"name", std::string{"Scott"}}},
    }}
  };
  
  std::cout << mstch::render(view, context) << std::endl;
  
  return 0;
}

The output of this example will be:

Hi Chris!
Hi Mark!
Hi Scott!

Data structure

The types in the example above, mstch::array and mstch::map are actually aliases for standard types:

using map = std::map<const std::string, node>;
using array = std::vector<node>;

mstch::node is a boost::variant that can hold a std::string, int, bool, lambda expression or a std::shared_ptr to a mstch::object (see below), also a map or an array recursively. Essentially it works just like a JSON object.

Note that when using a std::string as value you must explicitly specify the type, since a const char* literal like "foobar" would be implicitly converted to bool. Alternatively you can use C++14 string_literals if your compiler supports it.

Advanced usage

Partials

Partials can be passed in a std::map as the third parameter of the mstch::render function:

std::string view{"{{#names}}{{> user}}{{/names}}"};
std::string user_view{"<strong>{{name}}\n</strong>"};
mstch::map context{
  {"names", mstch::array{
    mstch::map{{"name", std::string{"Chris"}}},
    mstch::map{{"name", std::string{"Mark"}}},
    mstch::map{{"name", std::string{"Scott"}}},
  }}
};
  
std::cout << mstch::render(view, context, {{"user", user_view}}) << std::endl;

The output will be:

<strong>Chris</strong>
<strong>Mark</strong>
<strong>Scott</strong>

Lambdas

C++11 lambda expressions can be used to add logic to your templates. Like a const char* literal, lambdas can be implicitly converted to bool, so they must be wrapped in a mstch::lambda object when used in a mstch::node.

The lambda expression passed to mstch::lambda returns a std::string and accepts either no parameters:

std::string view{"Hello {{lambda}}!"};
mstch::map context{
  {"lambda", mstch::lambda{[]() {
    return std::string{"World"};
  }}}
};

std::cout << mstch::render(view, context) << std::endl;

The output will be:

Hello World!

Or it accepts a const std::string& and a mstch::renderer. The first one is passed the unrendered literal block, the second is a std::function that can be called to render it:

std::string view{"{{#bold}}{{yay}} :){{/bold}}"};
mstch::map context{
  {"yay", std::string{"Yay!"}},
  {"bold", mstch::lambda{[](const std::string& text, mstch::renderer render) {
    return "<b>" + render(text) + "</b>";
  }}}
};

std::cout << mstch::render(view, context) << std::endl;

The output will be:

<b>Yay! :)</b>

Objects

TODO

Requirements

  • A C++ compiler with decent C++11 support. Currently only tested with GCC 4.9.
  • Boost 1.54+ for Boost.Variant
  • CMake 2.8+ for building

Installing

From the root of the source tree:

 $ mkdir build
 $ cd build
 $ cmake ..
 $ make
 $ make install

Running the unit tests

Unit tests are using the Catch framework, included in the repository. Boost.Program_Options and The Boost Algorithm Library are also required to build them.

 $ mkdir build
 $ cd build
 $ cmake -DWITH_UNIT_TESTS=ON ..
 $ make
 $ make test