Views
Views are the simplest way to render a template from a Vix.cpp application.
A view describes three things:
template name
values passed to the template
optional page metadataThe template engine still does the real rendering. vix::ui::View only gives your application a clean UI-level object to pass around.
Basic route
#include <vix/core.hpp>
#include <vix/ui.hpp>
int main()
{
vix::App app;
app.templates("templates");
app.get("/", [](vix::Request &req, vix::Response &res) {
(void)req;
auto view =
vix::ui::View("home.html")
.set_title("Home")
.set("name", "Gaspard")
.set("status", "online");
res.ui(view);
});
app.run(8080);
return 0;
}Template:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{{ page_title }}</title>
</head>
<body>
<h1>Hello {{ name }}</h1>
<p>Status: {{ status }}</p>
</body>
</html>set_title() automatically stores the value under page_title, so the template can use:
<title>{{ page_title }}</title>Create a view
vix::ui::View view("dashboard.html");Or:
auto view = vix::ui::View::make("dashboard.html");You can also create an empty view and set the template later:
vix::ui::View view;
view.set_template("dashboard.html");Pass values to a template
Use set() to pass values.
auto view =
vix::ui::View("profile.html")
.set_title("Profile")
.set("username", "adastra")
.set("country", "Uganda")
.set("active", true)
.set("products", 42);Template:
<h1>{{ page_title }}</h1>
<p>{{ username }}</p>
<p>{{ country }}</p>
<p>{{ products }} products</p>Merge many values
When values already exist inside a template object, merge them into the view.
vix::template_::Object values;
values["title"] = "Dashboard";
values["users"] = 128;
values["active"] = true;
auto view = vix::ui::View("dashboard.html");
view.merge(values);Render trusted HTML
Template values are escaped by default.
That protects pages from accidentally rendering unsafe HTML.
view.set("bio", "<b>builder</b>");Template:
<p>{{ bio }}</p>Output:
<p><b>builder</b></p>When the HTML is generated by your application and is trusted, use the template safe filter.
const std::string flash =
vix::ui::FlashMessage::success("Profile updated.")
.set_title("Saved")
.render();
auto view =
vix::ui::View("dashboard.html")
.set_title("Dashboard")
.set("flash", flash);Template:
{{ flash | safe }}Use safe only for HTML produced by your own application helpers.
View context
ViewContext is a small container for values that can be converted into a template context.
vix::ui::ViewContext ctx;
ctx.set("name", "Gaspard");
ctx.set("active", true);
if (ctx.has("name"))
{
const auto *name = ctx.get("name");
}You can convert it to the template engine context:
vix::template_::Context template_ctx = ctx.to_template_context();This is useful when you want to prepare values before creating or rendering a view.
Render manually
Most web applications should use res.ui(view) inside a route.
For examples, tests, or custom integrations, you can render a view manually with a template engine.
#include <iostream>
#include <memory>
#include <vix/template/Engine.hpp>
#include <vix/template/StringLoader.hpp>
#include <vix/ui/core/View.hpp>
int main()
{
auto loader = std::make_shared<vix::template_::StringLoader>();
loader->set("home.html", "Hello {{ name }}");
vix::template_::Engine engine(loader);
vix::ui::View view("home.html");
view.set("name", "Gaspard");
const vix::ui::ViewResult result = view.render(engine);
if (!result.success)
{
return 1;
}
std::cout << result.output << "\n";
return 0;
}Output:
Hello GaspardView result
Rendering returns a ViewResult.
const vix::ui::ViewResult result = view.render(engine);Common fields:
| Field | Meaning |
|---|---|
success | Whether rendering succeeded. |
template_name | The template that was rendered. |
output | The rendered HTML. |
from_cache | Whether the template came from cache. |
escaped | Whether escaping was enabled by the template engine. |
Example:
if (!result.success)
{
std::cerr << "failed to render view\n";
return 1;
}
std::cout << result.output << "\n";Practical dashboard example
#include <vix/core.hpp>
#include <vix/ui.hpp>
int main()
{
vix::App app;
app.templates("templates");
app.get("/", [](vix::Request &req, vix::Response &res) {
(void)req;
const std::string flash =
vix::ui::FlashMessage::success("Dashboard loaded.")
.set_title("Ready")
.render();
const std::string stats =
vix::ui::Fragment::make("stats")
.set_html(
"<div class=\"stats\">"
"<article><strong>12</strong><span>Routes</span></article>"
"<article><strong>4</strong><span>Modules</span></article>"
"<article><strong>1</strong><span>UI layer</span></article>"
"</div>")
.render();
auto view =
vix::ui::View("dashboard.html")
.set_title("Dashboard")
.set("framework", "Vix.cpp")
.set("module", "vix::ui")
.set("flash", flash)
.set("stats", stats);
res.ui(view);
});
app.run(8080);
return 0;
}Template:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{{ page_title }}</title>
</head>
<body>
<main>
<h1>{{ page_title }}</h1>
<p>{{ framework }} dashboard powered by {{ module }}.</p>
{{ flash | safe }} {{ stats | safe }}
</main>
</body>
</html>Common mistakes
Forgetting to configure the template directory
app.templates("templates");Without this, the application may not know where to load template files.
Forgetting safe for trusted UI fragments
Wrong:
{{ flash }}Correct:
{{ flash | safe }}Rendering an empty view
A view needs a template before it can be rendered.
vix::ui::View view;
view.set_template("home.html");Putting too much logic in templates
Keep templates focused on presentation.
Prepare data in C++:
view.set("products_count", 42);
view.set("page_title", "Products");Then render simple values in HTML:
<h1>{{ page_title }}</h1>
<p>{{ products_count }} products</p>Next step
Continue with HTML helpers.