Skip to content

Latest commit

 

History

History
427 lines (301 loc) · 7.03 KB

File metadata and controls

427 lines (301 loc) · 7.03 KB

HTML helpers

Vix UI provides small HTML helpers for building safe HTML fragments from C++.

Use them when you need to generate a piece of HTML without writing a full template.

They are useful for:

small components
server-rendered fragments
HTML attributes
safe text escaping
dynamic tags
layout helpers
forms and UI primitives

For full pages, prefer templates and vix::ui::View.

Basic example

#include <vix/ui/html/Html.hpp>
#include <vix/ui/html/HtmlAttrs.hpp>

vix::ui::HtmlAttrs attrs;

attrs.set("class", "card");
attrs.set("id", "welcome");

const std::string html =
    vix::ui::Html::tag(
        "section",
        vix::ui::Html::tag("h1", vix::ui::Html::text("Vix UI")) +
            vix::ui::Html::tag(
                "p",
                vix::ui::Html::text("Small HTML fragments from C++.")),
        attrs);

Output:

<section class="card" id="welcome">
  <h1>Vix UI</h1>
  <p>Small HTML fragments from C++.</p>
</section>

Escaped text

Use Html::text() when the value comes from a user, a request, a database, or any untrusted source.

const std::string username = "<script>alert(1)</script>";

const std::string html =
    vix::ui::Html::tag(
        "p",
        vix::ui::Html::text(username));

Output:

<p>&lt;script&gt;alert(1)&lt;/script&gt;</p>

This prevents unsafe HTML from being rendered directly.

Raw HTML

Use Html::raw() only when the HTML is trusted and already generated by your application.

const std::string html =
    vix::ui::Html::tag(
        "div",
        vix::ui::Html::raw("<strong>Ready</strong>"));

Output:

<div><strong>Ready</strong></div>

Do not pass user input to Html::raw().

Attributes

HtmlAttrs stores and renders HTML attributes.

vix::ui::HtmlAttrs attrs;

attrs.set("class", "button");
attrs.set("id", "save-button");
attrs.set("data-action", "save");

const std::string html =
    vix::ui::Html::tag(
        "button",
        vix::ui::Html::text("Save"),
        attrs);

Output:

<button class="button" data-action="save" id="save-button">Save</button>

Attribute values are escaped automatically.

vix::ui::HtmlAttrs attrs;

attrs.set("title", R"(Save "draft" & continue)");

Output:

title="Save &quot;draft&quot; &amp; continue"

Boolean attributes

Use boolean attributes for HTML attributes that do not need a value.

vix::ui::HtmlAttrs attrs;

attrs.boolean("disabled", true);
attrs.boolean("hidden", false);

Only enabled boolean attributes are rendered.

disabled

You can also remove a boolean attribute by setting it to false.

attrs.boolean("disabled", false);

Conditional attributes

Use set_if() when an attribute should only appear in some cases.

const bool active = true;

vix::ui::HtmlAttrs attrs;

attrs.set("class", "nav-link");
attrs.set_if(active, "aria-current", "page");

Output:

class="nav-link" aria-current="page"

Open and close tags

Use open_tag() and close_tag() when you need to build HTML in multiple steps.

vix::ui::HtmlAttrs attrs;

attrs.set("class", "container");

std::string html;

html += vix::ui::Html::open_tag("main", attrs);
html += vix::ui::Html::tag("h1", vix::ui::Html::text("Dashboard"));
html += vix::ui::Html::close_tag("main");

Output:

<main class="container"><h1>Dashboard</h1></main>

Normal tags

Use Html::tag() for tags with opening and closing elements.

const std::string title =
    vix::ui::Html::tag(
        "h1",
        vix::ui::Html::text("Hello Vix"));

Output:

<h1>Hello Vix</h1>

With attributes:

vix::ui::HtmlAttrs attrs;

attrs.set("class", "title");

const std::string title =
    vix::ui::Html::tag(
        "h1",
        vix::ui::Html::text("Hello Vix"),
        attrs);

Output:

<h1 class="title">Hello Vix</h1>

Void tags

Use Html::void_tag() for tags that do not have closing tags.

vix::ui::HtmlAttrs attrs;

attrs.set("charset", "utf-8");

const std::string meta =
    vix::ui::Html::void_tag("meta", attrs);

Output:

<meta charset="utf-8" />

Common void tags include:

meta
link
img
input
br
hr

Doctype

Use Html::doctype() when generating a full HTML document.

const std::string html =
    vix::ui::Html::doctype() +
    "<html lang=\"en\">"
    "<head>"
    "<meta charset=\"utf-8\">"
    "<title>Vix UI</title>"
    "</head>"
    "<body>"
    "<h1>Hello</h1>"
    "</body>"
    "</html>";

Output starts with:

<!doctype html>

Practical card example

#include <vix/core.hpp>
#include <vix/ui.hpp>

int main()
{
  vix::App app;

  app.get("/", [](vix::Request &req, vix::Response &res) {
    (void)req;

    vix::ui::HtmlAttrs card_attrs;
    card_attrs.set("class", "card");

    vix::ui::HtmlAttrs title_attrs;
    title_attrs.set("class", "title");

    const std::string card =
        vix::ui::Html::tag(
            "section",
            vix::ui::Html::tag(
                "h1",
                vix::ui::Html::text("Vix UI HTML"),
                title_attrs) +
                vix::ui::Html::tag(
                    "p",
                    vix::ui::Html::text(
                        "Small HTML fragments generated safely from C++.")),
            card_attrs);

    const std::string html =
        vix::ui::Html::doctype() +
        "<html lang=\"en\">"
        "<head>"
        "<meta charset=\"utf-8\">"
        "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
        "<title>Vix UI HTML</title>"
        "</head>"
        "<body><main>" +
        card +
        "</main></body></html>";

    res.ui(vix::ui::HtmlResponse::html(html));
  });

  app.run(8080);
  return 0;
}

Valid names

Tag names and attribute names are validated.

Valid examples:

div
section
custom-element
svg:path
class
data-id
aria-label
_private

Invalid examples:

1div
bad name
bad/name

Invalid names throw a HtmlError.

try
{
  const std::string html =
      vix::ui::Html::tag("1bad", "content");
}
catch (const vix::ui::HtmlError &)
{
  // invalid tag name
}

Common mistakes

Passing user input as raw HTML

Wrong:

std::string html = vix::ui::Html::raw(user_input);

Correct:

std::string html = vix::ui::Html::text(user_input);

Building full pages only with C++ strings

HTML helpers are good for small fragments.

For full pages, prefer:

vix::ui::View("dashboard.html")

Templates are easier to read and maintain.

Forgetting attributes are escaped

You do not need to escape attribute values manually.

attrs.set("title", R"(Hello "Vix" & C++)");

Vix UI handles the escaping when rendering.

Using HTML helpers as a frontend framework

HTML helpers are not a virtual DOM.

They are small server-side helpers for generating safe HTML.

For pages, use templates.

For small components, use Html, HtmlAttrs, and HtmlEscape.

Next step

Continue with HTML responses.

Open the HTML response guide