Templating (Mustache)
Garvan exposes Crow's mustache implementation. The model is deliberately simple: a template file plus a context object equals rendered HTML.
Components
Every render involves two pieces:
- Page — a file on disk, loaded into a
crow::mustache::template_t. - Context — a
crow::mustache::context(alias forcrow::json::wvalue) carrying the values referenced by the template's tags.
Page
Templates live under a base directory. Set it once at startup:
crow::mustache::set_global_base("public/");
Then load files relative to that base:
auto page = crow::mustache::load("welcome.html");
auto text = crow::mustache::load_text("static_snippet.html"); // no parsing
The loader sanitizes the path; if you absolutely need to bypass that (you usually don't), use load_unsafe.
Context
Build a context with whatever data the page needs:
crow::mustache::context ctx;
ctx["title"] = "Welcome";
ctx["user"] = "Ada";
ctx["items"] = crow::json::wvalue::list({ "one", "two", "three" });
ctx["greet"] = [](std::string) { return std::string("Hello there!"); };
Lambdas are allowed and may themselves return strings containing mustache tags — the engine keeps parsing.
Partials
Reuse fragments with the {{> partial.html }} syntax. The path is again relative to the global base. The docs site you're reading uses partials for the top nav, sidebar, TOC and footer.
<body>
{{> topnav.html }}
<main>{{& content}}</main>
{{> footer.html }}
</body>
Returning a template
Render the page with the context and return the result:
CROW_ROUTE(app, "/welcome/<string>")([](std::string name) {
auto page = crow::mustache::load("welcome.html");
crow::mustache::context ctx;
ctx["user"] = name;
return page.render(ctx);
});
page.render(ctx) returns a crow::returnable with Content-Type set to text/html. Use render_string(ctx) if you'd rather have a plain std::string — for example when you want to embed the result inside another template.
If your template needs to include literal {{ (for example a code sample for this very page), escape it with the HTML entities {{.