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 for crow::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.

Tip

If your template needs to include literal {{ (for example a code sample for this very page), escape it with the HTML entities &#123;&#123;.