DEV Community

Cover image for Web Programming in C++ with WFC
Elanat Framework
Elanat Framework

Posted on

Web Programming in C++ with WFC

C++ is one of the most powerful and widely used programming languages in the world. It is well known for high-performance software, system programming, networking, game engines, embedded systems, and infrastructure.

But can C++ also be used to build modern web applications with server-side control over the HTML user interface?

Yes.

WebForms Core (WFC) is a server-side UI manipulation technology created by Elanat. It allows a server application to generate commands that manipulate the HTML interface in the browser.

Instead of creating a completely separate frontend application, the server can define UI operations and behaviors, while WebFormsJS executes those commands in the browser.

The basic architecture is:

C++ Server
    ↓
WebForms Class
    ↓
Action Controls
    ↓
WebFormsJS
    ↓
HTML DOM
Enter fullscreen mode Exit fullscreen mode

This article demonstrates how to use WebForms Core with C++ to build web applications, including a form-based application and an interactive video player.


WebForms Core in C++

For C and C++, there are several package management ecosystems and dependency management approaches. Because of the diversity of these systems, the WebForms Core C++ implementation is provided directly as a header file rather than requiring a specific C++ package manager.

WFC in C++

The C++ WebForms class is available in the WebForms Core GitHub repository:

https://github.com/webforms-core/Web_forms_classes/tree/elanat_framework/cpp

The file required by the application is:

WebForms.h
Enter fullscreen mode Exit fullscreen mode

You can get WebForms.h directly from the cpp directory and place it in your C++ project.

This makes the WebForms Core C++ implementation easy to integrate into projects using different build systems or development environments.

There is no requirement to use a particular C++ package manager for WebForms Core itself.


Using cpp-httplib

For the HTTP server in the examples, we use cpp-httplib, a C++ HTTP server/client library.

The httplib.h file used in these examples is obtained directly from the official GitHub repository:

https://github.com/yhirose/cpp-httplib

Just like WebForms.h, the header can be placed directly into the C++ project.

A simplified project structure can therefore look like this:

C++ Web Project/
├── main.cpp
├── WebForms.h
├── httplib.h
├── api/
│   ├── video.json
│   └── template.html
└── script/
    └── web-forms.js
Enter fullscreen mode Exit fullscreen mode

The two headers have different responsibilities:

#include "httplib.h"
#include "WebForms.h"
Enter fullscreen mode Exit fullscreen mode

cpp-httplib is used to create the HTTP server and handle HTTP requests and responses.

WebForms Core is used to create server-side UI commands.

The architecture is therefore:

C++ Application
       │
       ├── cpp-httplib
       │       │
       │       └── HTTP Server
       │
       └── WebForms Core
               │
               └── UI Commands
                       │
                       ▼
                   WebFormsJS
                       │
                       ▼
                    HTML DOM
Enter fullscreen mode Exit fullscreen mode

This combination is not a dependency relationship between the two libraries. They simply work together in the application: cpp-httplib handles HTTP, while WebForms Core handles server-side UI manipulation.


Building a Web Server with C++

Let's start with a simple web application.

We include the standard C++ libraries together with httplib.h and WebForms.h:

#include <iostream>
#include <string>

#include "httplib.h"
#include "WebForms.h"

using namespace std;
using namespace WebFormsCore;
Enter fullscreen mode Exit fullscreen mode

We can then define an HTML view:

string backEndRender(const string& viewName) {
    if (viewName == "view") {
        return R"(<!DOCTYPE html>
<html>
<head>
  <title>Using WebForms Core</title>
  <script type="module" src="/script/web-forms.js"></script>
</head>
<body>
    <form method="post" action="/">

        <label for="txt_Name">Your Name</label>
        <input name="txt_Name" id="txt_Name" type="text" />
        <br>

        <label for="txt_FontSize">Set Font Size</label>
        <input name="txt_FontSize"
               id="txt_FontSize"
               type="number"
               value="16"
               min="10"
               max="36" />
        <br>

        <label for="txt_BackgroundColor">
            Set Background Color
        </label>

        <input name="txt_BackgroundColor"
               id="txt_BackgroundColor"
               type="text" />
        <br>

        <input name="btn_SetBodyValue"
               type="submit"
               value="Click to send data" />

    </form>
</body>
</html>)";
    }

    return "<h1>View not found</h1>";
}
Enter fullscreen mode Exit fullscreen mode

The HTML is standard HTML. There is no JSX, no frontend component framework, and no special frontend build system required.


Manipulating the UI from C++

Now the C++ server can handle the POST request:

svr.Post("/", [](const httplib::Request& req,
                 httplib::Response& res) {

    if (req.has_param("btn_SetBodyValue")) {

        int fontSize =
            std::stoi(req.get_param_value("txt_FontSize"));

        std::string backgroundColor =
            req.get_param_value("txt_BackgroundColor");

        std::string name =
            req.get_param_value("txt_Name");

        WebForms form;

        form.SetFontSize(
            InputPlace::Tag("form"),
            fontSize
        );

        form.SetBackgroundColor(
            InputPlace::Tag("form"),
            backgroundColor
        );

        form.SetDisabled(
            InputPlace::Tag("btn_SetBodyValue"),
            true
        );

        form.AddTag(
            InputPlace::Tag("form"),
            "h3"
        );

        form.SetText(
            InputPlace::Tag("h3"),
            "Welcome " + name + "!"
        );

        res.set_content(
            form.Response(),
            "text/plain"
        );
    }
    else {
        res.set_content(
            backEndRender("view"),
            "text/html"
        );
    }
});
Enter fullscreen mode Exit fullscreen mode

The important point is that the C++ application is not simply returning data.

It is creating UI commands.

For example:

form.SetFontSize(
    InputPlace::Tag("form"),
    fontSize
);
Enter fullscreen mode Exit fullscreen mode

creates a command that changes the font size of the target element.

Likewise:

form.SetBackgroundColor(
    InputPlace::Tag("form"),
    backgroundColor
);
Enter fullscreen mode Exit fullscreen mode

changes the background color.

And:

form.SetDisabled(
    InputPlace::Tag("btn_SetBodyValue"),
    true
);
Enter fullscreen mode Exit fullscreen mode

disables the submit button.

The server can also create new HTML elements:

form.AddTag(
    InputPlace::Tag("form"),
    "h3"
);

form.SetText(
    InputPlace::Tag("h3"),
    "Welcome " + name + "!"
);
Enter fullscreen mode Exit fullscreen mode

The resulting commands are sent to the browser, where WebFormsJS executes them against the DOM.


Starting the C++ Server

The GET request returns the initial HTML page:

svr.Get("/", [](const httplib::Request&,
                httplib::Response& res) {

    res.set_content(
        backEndRender("view"),
        "text/html"
    );
});
Enter fullscreen mode Exit fullscreen mode

The WebFormsJS file can be served using cpp-httplib:

svr.set_mount_point("/script", "./script");
Enter fullscreen mode Exit fullscreen mode

Finally, the server listens on port 8080:

svr.listen("127.0.0.1", 8080);
Enter fullscreen mode Exit fullscreen mode

The application can then be accessed at:

http://127.0.0.1:8080/
Enter fullscreen mode Exit fullscreen mode

Building a Video Player with C++

WebForms Core is not limited to forms and simple DOM modifications.

It can also be used to build more interactive interfaces.

The second example is a video player that loads a list of videos from a JSON file and creates the video cards dynamically.

The JSON file contains:

[
  {
    "title": "Big Buck Bunny",
    "path": "https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4"
  },
  {
    "title": "Sintel",
    "path": "https://test-videos.co.uk/vids/sintel/mp4/h264/720/Sintel_720_10s_2MB.mp4"
  },
  {
    "title": "Flower",
    "path": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
  },
  {
    "title": "Elephants Dream",
    "path": "https://archive.org/download/ElephantsDream/ed_1024_512kb.mp4"
  }
]
Enter fullscreen mode Exit fullscreen mode

The C++ application exposes the JSON file through an HTTP endpoint:

svr.Get("/api/video.json",
    [](const httplib::Request&,
       httplib::Response& res) {

    string content;

    if (!readFile("./api/video.json", content)) {
        res.status = 500;
        res.set_content(
            "Cannot read api/video.json",
            "text/plain"
        );
        return;
    }

    res.set_content(
        content,
        "application/json"
    );
});
Enter fullscreen mode Exit fullscreen mode

The application also exposes the HTML template:

svr.Get("/api/template.html",
    [](const httplib::Request&,
       httplib::Response& res) {

    string content;

    if (!readFile("./api/template.html", content)) {
        res.status = 500;
        res.set_content(
            "Cannot read api/template.html",
            "text/plain"
        );
        return;
    }

    res.set_content(
        content,
        "text/html"
    );
});
Enter fullscreen mode Exit fullscreen mode

The WebForms Video Interface

We start by creating a WebForms instance:

WebForms form;
Enter fullscreen mode Exit fullscreen mode

The video data is loaded and stored using WebForms Core:

form.NotExist(
    Fetch::Cache("video-data")
);

form.AddCacheValue(
    "video-data",
    Fetch::LoadUrl("/api/video.json")
);
Enter fullscreen mode Exit fullscreen mode

We can then iterate over the JSON data:

form.ForEach(
    "[0]",
    Fetch::Cache("video-data"),
    "foreach-data"
);
Enter fullscreen mode Exit fullscreen mode

Inside the loop, the HTML template is loaded and populated:

form.StartBracket();

    form.AddText(
        "{video-container}",
        Fetch::LoadHtml(
            "/api/template.html",
            "Video"
        )
    );

    form.BindJSONToTemplate(
        "{video-card}-1",
        Fetch::FormatStore("foreach-data"),
        "[0]",
        "{{value}}"
    );

    form.SetCommentEvent(
        "{video-card}-1|<>",
        HtmlEvent::OnClick,
        "play-video"
    );

form.EndBracket();
Enter fullscreen mode Exit fullscreen mode

The template is:

<!DOCTYPE html>

<template id="Video">
    <div class="video-card">
        <b data-path="{{path}}">
            {{title}}
        </b>
    </div>
</template>
Enter fullscreen mode Exit fullscreen mode

The JSON data is therefore transformed into a collection of video cards.

Screenshot of Video Player

WebForms Core in C++


Playing the Selected Video

When the user clicks a video card, the play-video action is executed:

form.StartIndex("play-video");

form.SetAttribute(
    "video",
    HtmlEvent::OnLoadStart,
    "this.play()"
);

form.SetAttribute(
    "video",
    "src",
    Fetch::GetAttribute("$", "data-path")
);

form.SetText(
    "video-name",
    Fetch::GetText("$")
);
Enter fullscreen mode Exit fullscreen mode

The selected video's data-path is used as the source of the HTML <video> element:

form.SetAttribute(
    "video",
    "src",
    Fetch::GetAttribute("$", "data-path")
);
Enter fullscreen mode Exit fullscreen mode

The selected video's title is also displayed:

form.SetText(
    "video-name",
    Fetch::GetText("$")
);
Enter fullscreen mode Exit fullscreen mode

This is an important characteristic of WebForms Core.

The server can define not only the data that should be displayed, but also the UI operations that should take place when the user interacts with the page.


The HTML Interface

The frontend remains standard HTML:

<main>
    <h1>Web Project in C++</h1>

    <h2>
        Building a Video Player with WebForms Core
    </h2>

    <div class="video-container"></div>

    <video id="video"
           controls
           playsinline></video>

    <div id="now-playing">
        <span class="playing-indicator"></span>
        <span class="video-icon">🎬</span>
        <span id="video-name">
            No video selected
        </span>
    </div>
</main>
Enter fullscreen mode Exit fullscreen mode

The WebForms commands are exported into HTML comments:

html += form.ExportToHtmlComment(true);
Enter fullscreen mode Exit fullscreen mode

WebFormsJS detects these commands in the browser and executes them.

This means the server can send an HTML page together with the operations required to manipulate that page.


The Architecture

The complete architecture of the C++ example can be represented as:

                    C++ Application
                           │
             ┌─────────────┴─────────────┐
             │                           │
        cpp-httplib                WebForms Core
             │                           │
             │                    WebForms Class
             │                           │
             │                    Action Controls
             │                           │
             └──────────────┬────────────┘
                            │
                            ▼
                       HTTP Response
                            │
                            ▼
                         Browser
                            │
                            ▼
                       WebFormsJS
                            │
                            ▼
                        HTML DOM
Enter fullscreen mode Exit fullscreen mode

cpp-httplib provides the HTTP server layer.

WebForms Core provides the server-side UI manipulation layer.

WebFormsJS acts as the browser-side executor.

The final target is the HTML DOM.


C++ as a Web Programming Language

C++ is not limited to desktop applications, game engines, or system software.

With an HTTP library such as cpp-httplib, C++ can be used to create web servers. With WebForms Core, the same C++ application can also orchestrate operations on the browser's HTML interface.

The resulting stack is simple:

C++
+
cpp-httplib
+
WebForms Core
+
WebFormsJS
+
HTML
Enter fullscreen mode Exit fullscreen mode

There is no requirement to introduce a separate JavaScript frontend framework.

The application can keep its server-side logic in C++, while the browser receives HTML and WebForms commands.


Direct Header-Based Integration

One of the notable aspects of this C++ implementation is its direct integration model.

For WebForms Core:

WebForms.h
Enter fullscreen mode Exit fullscreen mode

is obtained directly from the WebForms Core C++ source directory.

For the HTTP server:

httplib.h
Enter fullscreen mode Exit fullscreen mode

is obtained directly from the cpp-httplib GitHub repository.

This gives the example a straightforward project structure without requiring a specific C++ package manager:

main.cpp
WebForms.h
httplib.h
Enter fullscreen mode Exit fullscreen mode

Additional files such as HTML templates, JSON data, and web-forms.js can then be added according to the requirements of the application.

This approach can be useful for C++ projects where developers prefer direct header integration or where the project already has its own build and dependency management system.


Conclusion

Web programming in C++ is possible, and WebForms Core provides a way to bring server-side UI manipulation into C++ web applications.

In these examples, cpp-httplib provides the HTTP server while WebForms Core provides the UI command layer.

The server can:

  • Serve standard HTML.
  • Receive HTTP requests.
  • Process form data in C++.
  • Generate UI commands.
  • Manipulate HTML elements.
  • Load JSON data.
  • Bind JSON data to HTML templates.
  • Respond to user interactions.
  • Control an HTML video player.

The resulting architecture keeps the application server-oriented:

C++ Server
    ↓
WebForms
    ↓
Commands
    ↓
WebFormsJS
    ↓
HTML DOM
Enter fullscreen mode Exit fullscreen mode

WebForms Core is developed and maintained by Elanat, and the C++ implementation is available directly through the WebForms Core GitHub repository.

The combination of C++, cpp-httplib, WebForms Core, WebFormsJS, and standard HTML provides another way to build interactive web applications without requiring a separate frontend framework.

Related links

In Elanat:

in GitHub:

Top comments (0)