# Stencil/Mustache (String Interpolation) Glaze provides string interpolation for C++ structs through the `stencil` and `mustache` formats. These provide templating mechanisms for formatting structured data into strings, inspired by the Mustache templating language. This enables the generation of dynamic output by combining predefined templates with C++ structs. ## Basic Usage ```cpp struct person { std::string first_name{}; std::string last_name{}; uint32_t age{}; bool hungry{}; bool employed{}; }; // Basic interpolation std::string_view layout = R"({{first_name}} {{last_name}} is {{age}} years old)"; person p{"Henry", "Foster", 34}; auto result = glz::stencil(layout, p); // Result: "Henry Foster is 34 years old" ``` > [!NOTE] > > `result` in these examples is a `std::expected`. Like most functions in Glaze (e.g. `glz::write_json`) you can also pass in your own string buffer as the last argument, in which case the return type is `glz::error_ctx`. ## Template Syntax Specification ### Variable Interpolation - `{{key}}` - Replaces with the value of the specified field from the struct - `{{{key}}}` - Triple braces for unescaped output (mustache format only) ### Boolean Sections - `{{#boolean_key}} CONTENT {{/boolean_key}}` - Shows CONTENT if the boolean field is true - `{{^boolean_key}} CONTENT {{/boolean_key}}` - Shows CONTENT if the boolean field is false (inverted section) ### Container Iteration - `{{#container_key}} TEMPLATE {{/container_key}}` - Iterates over container elements, applying TEMPLATE to each item - `{{^container_key}} CONTENT {{/container_key}}` - Shows CONTENT if the container is empty ### Comments - `{{! This is a comment}}` - Comments are ignored during template processing ## Examples ### Boolean Sections ```cpp std::string_view layout = R"({{first_name}} {{last_name}} {{#employed}}Status: Employed, Age: {{age}}{{/employed}})"; person p{"Carol", "Davis", 30, true, true}; auto result = glz::stencil(layout, p); // Result: "Carol Davis Status: Employed, Age: 30" ``` ### Inverted Sections ```cpp std::string_view layout = R"({{first_name}} {{last_name}} {{^hungry}}I'm not hungry{{/hungry}})"; person p{"Henry", "Foster", 34, false}; // hungry is false auto result = glz::stencil(layout, p); // Result: "Henry Foster I'm not hungry" ``` ### Container Iteration ```cpp struct TodoItem { std::string text; bool completed; std::string priority; size_t id; }; struct TodoList { std::string title; std::vector items; bool has_items; }; std::string_view layout = R"({{title}}: {{#items}}{{text}} ({{priority}}) {{/items}})"; TodoList list{ "My Tasks", {{"Buy milk", false, "normal", 1}, {"Call mom", true, "high", 2}}, true }; auto result = glz::stencil(layout, list); // Result: "My Tasks: Buy milk (normal) Call mom (high) " ``` ### Nested Sections ```cpp std::string_view layout = R"({{#items}}{{text}} {{#completed}}✓{{/completed}}{{^completed}}○{{/completed}} {{/items}})"; TodoList list{"Mixed Tasks", {{"Task 1", false, "high", 1}, {"Task 2", true, "low", 2}}, true}; auto result = glz::stencil(layout, list); // Result: "Task 1 ○Task 2 ✓" ``` ### Empty Container Handling ```cpp std::string_view layout = R"({{title}}{{^items}} - No items found{{/items}})"; TodoList empty_list{"Empty List", {}, false}; auto result = glz::stencil(layout, empty_list); // Result: "Empty List - No items found" ``` ## Mustache Format Glaze provides `glz::mustache` with the same interface as `glz::stencil`, but with HTML escaping behavior: - **Double braces** `{{key}}` - HTML-escaped output (safe for HTML) - **Triple braces** `{{{key}}}` - Unescaped output (raw HTML) ### HTML Escaping Examples ```cpp struct html_content { std::string title; std::string raw_html; }; // Double braces escape HTML std::string_view layout = R"(

{{title}}

)"; html_content content{"My