mstch/README.md

185 lines
4.5 KiB
Markdown
Raw Normal View History

2015-04-23 23:35:29 +00:00
# mstch - {{mustache}} templates in C++11
2015-04-24 10:29:58 +00:00
![mstch logo](http://i.imgur.com/XAdHwUs.png)
2015-04-24 10:16:03 +00:00
2015-04-24 12:47:12 +00:00
mstch is a complete implementation of [{{mustache}}](http://mustache.github.io/)
templates using modern C++.
2015-04-23 23:48:42 +00:00
2015-04-23 23:35:29 +00:00
[![Build Status](https://travis-ci.org/no1msd/mstch.svg?branch=master)](https://travis-ci.org/no1msd/mstch)
2015-04-24 10:25:24 +00:00
## Supported features
mstch supports the complete feature set described in the `mustache(5)` [manpage](http://mustache.github.com/mustache.5.html):
- JSON-like data structure using [Boost.Variant](http://www.boost.org/doc/libs/1_57_0/doc/html/variant.html)
- variables, sections, inverted sections
- partials
- changing the delimiter
- C++11 lambdas
- C++ objects as view models
2015-04-23 23:35:29 +00:00
## Basic usage
```c++
#include <iostream>
#include <mstch/mstch.hpp>
int main() {
std::string view{"{{#names}}Hi {{name}}!\n{{/names}}"};
mstch::map context{
{"names", mstch::array{
2015-04-23 23:37:09 +00:00
mstch::map{{"name", std::string{"Chris"}}},
mstch::map{{"name", std::string{"Mark"}}},
mstch::map{{"name", std::string{"Scott"}}},
}}
2015-04-23 23:35:29 +00:00
};
std::cout << mstch::render(view, context) << std::endl;
return 0;
}
```
The output of this example will be:
2015-04-24 13:51:41 +00:00
```html
2015-04-23 23:48:42 +00:00
Hi Chris!
Hi Mark!
Hi Scott!
2015-04-23 23:35:29 +00:00
```
2015-04-24 12:47:12 +00:00
### Data structure
The types in the example above, `mstch::array` and `mstch::map` are actually
aliases for standard types:
```c++
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
2015-04-24 13:51:41 +00:00
converted to `bool`. Alternatively you can use [C++14 string_literals](http://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s)
2015-04-24 12:47:12 +00:00
if your compiler supports it.
## Advanced usage
### Partials
2015-04-24 13:20:49 +00:00
Partials can be passed in a `std::map` as the third parameter of the
`mstch::render` function:
```c++
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:
2015-04-24 13:51:41 +00:00
```html
2015-04-24 13:20:49 +00:00
<strong>Chris</strong>
<strong>Mark</strong>
<strong>Scott</strong>
```
2015-04-24 12:47:12 +00:00
### Lambdas
2015-04-24 13:51:41 +00:00
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:
```c++
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:
```html
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:
```c++
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:
```html
<b>Yay! :)</b>
```
2015-04-24 12:47:12 +00:00
### Objects
TODO
2015-04-23 23:35:29 +00:00
## Requirements
- A C++ compiler with decent C++11 support. Currently only tested with GCC 4.9.
2015-04-24 12:47:12 +00:00
- Boost 1.54+ for [Boost.Variant](http://www.boost.org/doc/libs/1_57_0/doc/html/variant.html)
- CMake 2.8+ for building
2015-04-23 23:35:29 +00:00
2015-04-23 23:48:42 +00:00
## Installing
2015-04-23 23:35:29 +00:00
From the root of the source tree:
```bash
$ mkdir build
$ cd build
$ cmake ..
$ make
2015-04-23 23:48:42 +00:00
$ make install
2015-04-23 23:35:29 +00:00
```
2015-04-24 12:47:12 +00:00
## Running the unit tests
Unit tests are using the [Catch](https://github.com/philsquared/Catch) framework,
included in the repository. [Boost.Program_Options](http://www.boost.org/doc/libs/1_58_0/doc/html/program_options.html)
and [The Boost Algorithm Library](http://www.boost.org/doc/libs/1_57_0/libs/algorithm/doc/html/index.html)
are also required to build them.
2015-04-23 23:35:29 +00:00
```bash
$ mkdir build
$ cd build
$ cmake -DWITH_UNIT_TESTS=ON ..
$ make
$ make test
```