Vix.cpp v2.7.0 is here Read the blog
Skip to content

Views

Views are the simplest way to render a template from a Vix.cpp application.

A view describes three things:

txt
template name
values passed to the template
optional page metadata

The template engine still does the real rendering. vix::ui::View only gives your application a clean UI-level object to pass around.

Basic route

cpp
#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:

html
<!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:

html
<title>{{ page_title }}</title>

Create a view

cpp
vix::ui::View view("dashboard.html");

Or:

cpp
auto view = vix::ui::View::make("dashboard.html");

You can also create an empty view and set the template later:

cpp
vix::ui::View view;

view.set_template("dashboard.html");

Pass values to a template

Use set() to pass values.

cpp
auto view =
    vix::ui::View("profile.html")
        .set_title("Profile")
        .set("username", "adastra")
        .set("country", "Uganda")
        .set("active", true)
        .set("products", 42);

Template:

html
<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.

cpp
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.

cpp
view.set("bio", "<b>builder</b>");

Template:

html
<p>{{ bio }}</p>

Output:

html
<p>&lt;b&gt;builder&lt;/b&gt;</p>

When the HTML is generated by your application and is trusted, use the template safe filter.

cpp
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:

html
{{ 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.

cpp
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:

cpp
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.

cpp
#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:

txt
Hello Gaspard

View result

Rendering returns a ViewResult.

cpp
const vix::ui::ViewResult result = view.render(engine);

Common fields:

FieldMeaning
successWhether rendering succeeded.
template_nameThe template that was rendered.
outputThe rendered HTML.
from_cacheWhether the template came from cache.
escapedWhether escaping was enabled by the template engine.

Example:

cpp
if (!result.success)
{
  std::cerr << "failed to render view\n";
  return 1;
}

std::cout << result.output << "\n";

Practical dashboard example

cpp
#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:

html
<!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

cpp
app.templates("templates");

Without this, the application may not know where to load template files.

Forgetting safe for trusted UI fragments

Wrong:

html
{{ flash }}

Correct:

html
{{ flash | safe }}

Rendering an empty view

A view needs a template before it can be rendered.

cpp
vix::ui::View view;

view.set_template("home.html");

Putting too much logic in templates

Keep templates focused on presentation.

Prepare data in C++:

cpp
view.set("products_count", 42);
view.set("page_title", "Products");

Then render simple values in HTML:

html
<h1>{{ page_title }}</h1>
<p>{{ products_count }} products</p>

Next step

Continue with HTML helpers.

Open the HTML guide

Released under the MIT License.