强大的C++11 Mustache模板库 —— mstch
mstch 是一个全面的 Mustache 模板实现,基于现代C++11设计。它遵循了 规格说明 v1.1.3,包括Lambda模块。
在线试用: 点击此处 在线体验。 版本信息: 查看GitHub版本。 构建状态:
- Linux:
- Windows:
功能特性
mstch 支持了 Mustache 所有的功能特性:
- 使用 Boost.Variant 实现类似JSON的数据结构
- 变量、段落、反向段落
- 部分模板
- 更改分隔符
- C++11 Lambda表达式支持
- C++对象作为视图模型
基本用法
以下是一个简单的示例:
#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", "Chris"}},
mstch::map{{"name", "Mark"}},
mstch::map{{"name", "Scott"}},
}}
};
std::cout << mstch::render(view, context) << std::endl;
return 0;
}
输出结果为:
Hi Chris!
Hi Mark!
Hi Scott!
数据结构
在示例中使用的 mstch::array
和 mstch::map
其实是标准类型别名:
using map = std::map<const std::string, node>;
using array = std::vector<node>;
mstch::node
是一个 boost::variant
,它可以存储 std::string
,int
,double
,bool
,mstch::lambda
或者一个 std::shared_ptr<mstch::object>
(见下文),以及递归的 map 或 array 类型。简单来说,它的工作方式类似于一个JSON对象。
请注意,当值是字符串时,必须显式指定类型,因为 const char*
字符串字面量会隐式转换为 bool
。另外,如果你的编译器支持,也可以使用 C++14 的字符串字面量。
进阶用法
部分模板
部分模板可以通过 std::map
作为 mstch::render
函数的第三个参数传递:
std::string view{"{{#names}}{{> user}}{{/names}}"};
std::string user_view{"<strong>{{name}}</strong>"};
mstch::map context{
{"names", mstch::array{
mstch::map{{"name", "Chris"}},
mstch::map{{"name", "Mark"}},
mstch::map{{"name", "Scott"}},
}}
};
std::cout << mstch::render(view, context, {{"user", user_view}}) << std::endl;
输出:
<strong>Chris</strong>
<strong>Mark</strong>
<strong>Scott</strong>
Lambda表达式
利用C++11的Lambda表达式可以给模板添加逻辑。像 const char*
字符串一样,Lambda表达式可以隐式转换为 bool
,所以它们在 mstch::node
中需要包裹在 mstch::lambda
对象中。Lambda表达式返回的 mstch::node
将会被渲染成字符串,并作为模板进行解析。
Lambda 表达式可以接受零个或一个参数:
std::string view{"Hello {{lambda}}!"};
mstch::map context{
{"lambda", mstch::lambda{[]() -> mstch::node {
return "World";
}}}
};
std::cout << mstch::render(view, context) << std::endl;
输出:
Hello World!
或者接受一个 const std::string&
参数,该参数获取未渲染的文本块:
std::string view{"{{#bold}}{{yay}} :){{/bold}}"};
mstch::map context{
{"yay", "Yay!"},
{"bold", mstch::lambda{[](const std::string& text) -> mstch::node {
return "<b>" + text + "</b>";
}}}
};
std::cout << mstch::render(view, context) << std::endl;
输出:
<b>Yay! :)</b>
对象
自定义对象也可以作为渲染模板的上下文。类必须继承自 mstch::object
,并使用 register_methods
注册导出的方法。导出的方法必须有 mstch::node
返回类型。对象需以 std::shared_ptr
形式创建。
class example: public mstch::object {
public:
example(): m_value(1) {
register_methods(this, {
{"count", &example::count},
{"names", &example::names}
});
}
mstch::node count() {
return m_value++;
}
mstch::node names() {
return mstch::array{
"Chris", "Mark", "Scott"
};
}
private:
int m_value;
};
std::string view{"{{#names}}<b>{{count}}</b>: {{.}}\n{{/names}}"};
const auto context = std::make_shared<example>();
std::cout << mstch::render(view, context) << std::endl;
输出:
<b>1</b>: Chris
<b>2</b>: Mark
<b>3</b>: Scott
自定义转义函数
默认情况下,mstch对输出进行HTML转义,如规范所述。如果输出不是HTML,mstch提供了一种方法来供应自己的转义实现。只需将任何可调用的对象赋值给静态的 mstch::config::escape
,这是一个初始为空的 std::function<std::string(const std::string&)>
。例如,你可以用一个Lambda表达式关闭转义:
mstch::config::escape = [](const std::string& str) -> std::string {
return str;
};
系统要求
- 支持良好C++11的编译器。当前测试过的有:
- GCC 4.7, 4.8, 4.9, 5.1
- clang 3.5, 3.6, 3.7(支持libstdc++和libc++)
- MSVC 2013, 2015
- 必须安装 Boost 1.54+ 以便使用 Boost.Variant
- CMake 3.0+ 用于构建
将mstch加入你的项目
如果你的项目中使用CMake,最简单的方式是在源码树中复制mstch的整个目录,并在CMakeLists.txt中使用 add_subdirectory
。这将设置一个名为 mstch_INCLUDE_DIR
的变量,其中包含了它的头文件路径,并添加了一个名为 mstch
的静态库目标。例如:
add_subdirectory(external/mstch)
include_directories(${mstch_INCLUDE_DIR})
target_link_libraries(your_project mstch)
如果你想全局安装这个库,只需要在源代码根目录执行以下命令:
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make install
安装命令可能需要管理员权限。这样也会安装CMake配置文件,因此你可以在CMakeLists.txt中使用 find_package
:
find_package(mstch)
target_link_libraries(your_project mstch::mstch)
运行单元测试
单元测试使用了 Catch 测试框架和 rapidjson 来解析 Mustache 规范,所有这些都作为git子模块包含在项目中。还需要一些Boost库来构建它们。
不要忘记初始化子模块:
$ git submodule init
$ git submodule update
要构建并运行单元测试:
$ mkdir build
$ cd build
$ cmake -DWITH_UNIT_TESTS=ON ..
$ make
$ make test
许可证
mstch遵循 MIT许可证。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考