NetBurner 3.5.6
PDF Version
HTML Processing

HTML Processing

Introduction

The NetBurner Web Server automatically processes all content in your project's html/ folder. Whether you're using HTML examples, the application wizard, or creating a project from scratch, the web server provides powerful tools for serving both static and dynamic content.

Quick Start

  1. Create an html/ folder in your project (if it doesn't exist)
  2. Add your web content (HTML, CSS, JavaScript, images, etc.)
  3. Call StartHttp() or StartHttps() in your application
  4. Build your project - content is automatically compiled and linked

The NetBurner build system automatically compiles web content into your application image, eliminating the need for external file storage (though file system delivery is also supported).

Web Server Initialization

StartHttp(); // Default port 80
StartHttp(2000); // Custom HTTP port
StartHttps(); // Default port 443 (HTTPS only)
StartHttps(527); // Custom HTTPS port
StartHttps(443, 80); // Both HTTPS and HTTP on standard ports
void StartHttps(uint16_t ssl_port, uint16_t http_port)
Start the HTTPS secure web server.
void StartHttp(uint16_t port, bool RunConfigMirror)
Start the HTTP web server. Further documentation in the Initialization section Initialization - Syste...

Content Sources

Web content can be delivered from multiple sources:

Content Sources
v
┌──────────┬───────┴───────┬──────────┬──────────┐
│ │ │ │ │
v v v v v
Compiled Generated EFFS-STD EFFS-FAT Mixed
Into App Runtime (On-chip) (SD Card) Sources

Dynamic Content Overview

Dynamic content is generated at runtime on your NetBurner device, enabling real-time updates, interactive controls, and data visualization.

Dynamic Content Methods

User Request (Browser)
v
┌────────┴────────┐
│ │
│ Web Server │
│ │
└────────┬────────┘
v
Processing
┌────────┬───┴───┬────────┬─────────┬─────────┐
│ │ │ │ │ │
v v v v v v
HTML Callback Variable GET POST WebSocket
Tags Functions Tags Handler Handler Real-time

Available methods:

  1. HTML Tags - Embed dynamic content directly in HTML
  2. Function Callbacks - Execute C/C++ functions during page rendering
  3. Variable Tags - Insert application variable values in real-time
  4. JavaScript - Client-side dynamic behavior
  5. GET Handlers - Intercept and customize page requests
  6. POST Handlers - Process form submissions
  7. WebSockets - Two-way real-time communication

HTML Tags

HTML tags enable real-time dynamic content by embedding directives in your HTML source code. When the web server streams content to the browser, it processes these tags and takes appropriate action.

Tag Overview

Tag Purpose Use Case
CPPCALL Execute C++ function without parameters Display computed data, trigger actions
VARIABLE() Execute C++ function with parameters Parameterized callbacks, complex operations
VARIABLE Insert application variable value Display sensor readings, system state
CONFIGVALUE Display configuration variable Show system settings
CONFIGINPUT Create input field with config value Edit system configuration
CONFIGTABLE Generate configuration table Display hierarchical settings

Tag Syntax

Tags are embedded within HTML comments to avoid interfering with standard HTML processing:

<!--CPPCALL functionName -->
<!--VARIABLE expression -->
<!--VARIABLE functionName(fd, parameters) -->

Important**: Spacing matters!

  • No space between <!-- and tag name
  • Space required before -->
Correct: <!--CPPCALL myFunction -->
Incorrect: <!-- CPPCALL myFunction-->
Incorrect: <!--CPPCALL myFunction-->

The CPPCALL Tag

The CPPCALL tag executes a C++ function when encountered during page rendering. The function receives the socket file descriptor and URL, giving it full control over response generation.

Function Flow

Browser Request
v
Web Server Parsing
v
Encounters <!--CPPCALL funcName -->
v
Calls funcName(socket, url)
v
Function Generates Output
v
Output Sent to Browser

Function Signature

void YourFunctionName(int sock, PCSTR url)
{
// Your code here
// Write to sock to send data to browser
}

Example: Display Client Information

HTML Code:**

<html>
<body>
<h1>Connection Information</h1>
Client Address: <!--CPPCALL webShowClientInfo -->
</body>
</html>

C++ Implementation:**

void webShowClientInfo(int sock, PCSTR url)
{
IPADDR localIP = GetSocketLocalAddr(sock);
uint32_t remotePort = GetSocketRemotePort(sock);
localIP.fdprint(sock); // Write IP address
fdprintf(sock, ":%d<br>\r\n", remotePort); // Write port number
}
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition ipv6_addr.h:41
void fdprint(int fd, bool bCompact=true, bool bShowV4Raw=false) const
Print the IP address to the specified file descriptor.
int fdprintf(int fd, const char *format,...)
Print formatted output to a file descriptor.
IPADDR GetSocketLocalAddr(int fd)
Get the local interface IP address for a socket connection.
Definition tcp.h:9470
uint16_t GetSocketRemotePort(int fd)
Get the remote host port number for a socket connection.

Result:**

Client Address: 192.168.1.100:54321

The VARIABLE Tag

The VARIABLE tag has two distinct uses:

  1. Direct Variable Display - Insert variable or expression value
  2. Parameterized Function Call - Execute function with custom parameters

Use Case 1: Display Variables

HTML Tag: <!--VARIABLE expression -->
v
Build Process Converts To:
v
WriteHtmlVariable(fd, expression);
v
Value Written to Socket

Simple Variable Display:**

<!-- Display system uptime in ticks -->
System Ticks: <!--VARIABLE TimeTick -->
<!-- Display uptime in seconds using expression -->
Uptime: <!--VARIABLE TimeTick/TICKS_PER_SECOND --> seconds

Supported Variable Types

The following types are automatically supported (defined in htmlfiles.h):

void WriteHtmlVariable(int fd, char c);
void WriteHtmlVariable(int fd, int i);
void WriteHtmlVariable(int fd, short i);
void WriteHtmlVariable(int fd, long i);
void WriteHtmlVariable(int fd, uint8_t b);
void WriteHtmlVariable(int fd, uint16_t w);
void WriteHtmlVariable(int fd, unsigned long dw);
void WriteHtmlVariable(int fd, const char *);
void WriteHtmlVariable(int fd, MACADR ma);
void WriteHtmlVariable(int fd, IPADDR ip);
Used to store and manipulate MAC addresses.
Definition nettypes.h:69

Use Case 2: Parameterized Function Calls

When you need to pass parameters to a function (beyond the fixed CPPCALL signature), use VARIABLE():

HTML: <!--VARIABLE MyFunc(fd, param1, param2) -->
v
Converted To: WriteHtmlVariable(fd, MyFunc(fd, param1, param2));
v
MyFunc Executes and Returns Result
v
Result Written to Browser

Header Declaration:**

const char* DisplaySensorData(int fd, int sensorId);

HTML Usage:**

Sensor 1: <!--VARIABLE DisplaySensorData(fd, 1) --><br>
Sensor 2: <!--VARIABLE DisplaySensorData(fd, 2) --><br>

Implementation:**

const char* DisplaySensorData(int fd, int sensorId)
{
int reading = ReadSensor(sensorId);
fdprintf(fd, "Sensor %d: %d units", sensorId, reading);
return ""; // Empty string - output already written to fd
}

The INCLUDE Tag and htmlvar.h

For the build system to resolve variable and function references in HTML tags, it needs access to appropriate headers.

Two Methods for Include Resolution

HTML Processing
v
Need Headers?
┌────────┴────────┐
│ │
v v
Method 1 Method 2
│ │
v v
INCLUDE Tag htmlvar.h File
(In HTML) (In Project)

Method 1: INCLUDE Tag in HTML

Place the include directive directly in your HTML file:

<html>
<body>
<!--INCLUDE myIncludeFile.h -->
Value = <!--VARIABLE MyVar --><br>
</body>
</html>

Method 2: htmlvar.h Header File

Create a file named htmlvar.h in your project. The build system automatically searches for this file:

#ifndef HTMLVARS_H_
#define HTMLVARS_H_
#include <nbrtos.h> // For TimeTick, TICKS_PER_SECOND
extern int gIntVal;
extern char gStrVal[];
// Function with parameters for VARIABLE() tag
const char* DisplayWithParam(int fd, int value);
#endif

Include Resolution Flow

Build System
v
Search for INCLUDE tags in HTML
┌─────────┴─────────┐
│ │
Found Not Found
│ │
v v
Use Specified Search for htmlvar.h
Headers │
v
Use htmlvar.h if found

Extending VARIABLE Tag Support

You can extend the VARIABLE tag to support custom types by overloading WriteHtmlVariable().

Custom Type Example

Define Custom Structure:**

struct SensorData {
int temperature;
int humidity;
char location[80];
uint32_t timestamp;
};
SensorData sensor1;

Add to htmlvar.h:**

void WriteHtmlVariable(int fd, SensorData data);

Use in HTML:**

Sensor Status: <!--VARIABLE sensor1 -->

Implement the Function:**

void WriteHtmlVariable(int fd, SensorData data)
{
fdprintf(fd, "<div class='sensor'>");
fdprintf(fd, " Location: %s<br>", data.location);
fdprintf(fd, " Temperature: %dC<br>", data.temperature);
fdprintf(fd, " Humidity: %d%%<br>", data.humidity);
fdprintf(fd, " Timestamp: %lu", data.timestamp);
fdprintf(fd, "</div>");
}

System Example: MAC Address Display

Here's how the system implements MAC address display:

void WriteHtmlVariable(int fd, MACADR ma)
{
PBYTE lpb = (PBYTE)&ma;
for (int i = 0; i < 5; i++)
{
fd_writehex(fd, lpb[i]);
write(fd, ":", 1);
}
fd_writehex(fd, lpb[5]);
}
int write(int fd, const char *buf, int nbytes)
Write data to the stream associated with a file descriptor (fd). Can be used to write data to stdio,...

Configuration System Tags

The CONFIG tags simplify displaying and modifying system configuration and application variables from the Configuration Record.

Configuration Tag Types

Tag Function Creates
CONFIGVALUE Display value Read-only text
CONFIGINPUT Display + edit HTML input field
CONFIGTABLE Display hierarchy HTML table

Configuration Tree Structure

Configuration Record
v
┌────────┴────────┐
│ │
v v
Sys AppData
(System) (Application)
│ │
v v
NetIf Custom Variables
Application Your Data
Settings

Example: Display Configuration Values

<!-- Display system hostname -->
Hostname: <!--CONFIGVALUE Sys/Application/HostName -->
<!-- Create editable input for application variable -->
Device Name: <!--CONFIGINPUT AppData/DeviceName -->
<!-- Display entire configuration section as table -->
<!--CONFIGTABLE Sys/NetIf -->

Configuration Access Flow

CONFIG Tag in HTML
v
Parse Path (e.g., "Sys/NetIf")
v
Locate in Configuration Tree
v
┌─────────┼─────────┬─────────┐
│ │ │ │
v v v v
VALUE INPUT TABLE
│ │ │
v v v
Display Create Generate
Value Field Table

HTTP GET Request Handler

GET handlers intercept browser requests before normal file serving, enabling URL encoding, custom processing, and dynamic routing.

When to Use GET Handlers

  • URL-encoded parameters: http://device/status?sensor=1
  • Dynamic page generation based on request
  • Stateful applications (session management via URL)
  • API endpoints
  • Custom routing logic

GET Handler Flow

Browser Request: GET /status.html
v
Web Server Receives Request
v
Check for GET Handler Match
┌────────┴────────┐
│ │
Match Found No Match
│ │
v v
Execute Normal File
Handler Processing
v
Custom Processing
v
Generate Response
v
Send to Browser

Creating a GET Handler

Step 1: Define Callback Function**

int callbackGetOddEven(int sock, HTTP_Request &request)
{
// Send HTML header
// Custom processing
printf("GET request from: %I\r\n", request.client_IPaddr);
// Conditional response based on system time
if ((Secs % 2) == 0)
SendFileFragment("even.html", sock);
else
SendFileFragment("odd.html", sock);
return 1; // Indicates request was handled
}
void SendHTMLHeader(int sock)
Send a HTML response header.
int32_t SendFileFragment(char const *name, int32_t fd, PCSTR url=NULL)
Send a file fragment without a header.
HTTP Request Structure.
Definition http.h:87
IPADDR client_IPaddr
IP address of client.
Definition http.h:100

Step 2: Register Handler**

"OddEven.html", // URL to intercept
callbackGetOddEven, // Callback function
tGet, // Request type
0, // Access group (0 = no password)
true // beforeFiles: true = always called
);
Implements the HtmlPageHandler class as a function pointer callback for GET requests.
Definition http.h:326
@ tGet
GET request.
Definition http.h:37

CallBackFunctionPageHandler Parameters

Constructor Parameters
┌────────┬───┴───┬────────┬─────────┬──────────┐
│ │ │ │ │ │
v v v v v v
pURL pFunc reqType access before
Group Files
Parameter Description Example
pURL URL mask to match (supports wildcards) "status.html", "api/*"
pFunction Pointer to callback function myCallback
reqType Request type (tGet, tPost, etc.) tGet
accessGroup Security group (0 = no restriction) 0
beforeFiles When to call: true = always, false = only if file not found true

URL Encoding Example

// Handler for: http://device/sensor?id=5&type=temp
int sensorHandler(int sock, HTTP_Request &request)
{
// Parse URL parameters
const char* id = GetRequestParameter(request, "id");
const char* type = GetRequestParameter(request, "type");
fdprintf(sock, "<html><body>");
fdprintf(sock, "Sensor ID: %s<br>", id);
fdprintf(sock, "Type: %s<br>", type);
// Read and display sensor
int value = ReadSensor(atoi(id));
fdprintf(sock, "Value: %d</body></html>", value);
return 1;
}
CallBackFunctionPageHandler sensorGet("sensor*", sensorHandler, tGet, 0, true);

HTTP Form POST Handler

POST handlers process form submissions, enabling user input, configuration updates, and interactive web applications.

Creating a POST Handler

HTML Form Creation
v
POST Handler Callback
v
Handler Declaration
v
Processing Complete

Step 1: Create HTML Form

<html>
<title>Configuration Form</title>
<body>
<h1>Device Configuration</h1>
<form action="updateconfig" method="post">
Device Name: <input type="text" name="DeviceName" value="Default"><br>
IP Address: <input type="text" name="IPAddress" value="192.168.1.100"><br>
Port: <input type="text" name="Port" value="80"><br>
Enable: <input type="checkbox" name="Enable" checked><br>
<br>
<input type="submit" value="Update Configuration">
</form>
</body>
</html>

Step 2: Create Callback Function

void configPostCallback(int sock, PostEvents event,
const char* pName, const char* pValue)
{
static char deviceName[80];
static char ipAddress[20];
static int port;
static bool enabled;
static bool error = false;
switch(event)
{
case eStartingPost:
// Initialize before processing variables
deviceName[0] = '\0';
ipAddress[0] = '\0';
port = 0;
enabled = false;
error = false;
break;
case eVariable:
// Process each form variable
if (strcmp("DeviceName", pName) == 0)
{
strncpy(deviceName, pValue, 79);
printf("Device Name: %s\r\n", deviceName);
}
else if (strcmp("IPAddress", pName) == 0)
{
strncpy(ipAddress, pValue, 19);
printf("IP Address: %s\r\n", ipAddress);
}
else if (strcmp("Port", pName) == 0)
{
port = atoi(pValue);
printf("Port: %d\r\n", port);
}
else if (strcmp("Enable", pName) == 0)
{
enabled = (strcmp(pValue, "on") == 0);
printf("Enabled: %s\r\n", enabled ? "true" : "false");
}
else
{
printf("Unknown variable: %s\r\n", pName);
error = true;
}
break;
case eFile:
// Handle file upload (if applicable)
break;
case eEndOfPost:
// Processing complete - send response
if (error)
{
RedirectResponse(sock, "error.html");
}
else
{
// Apply configuration
ApplyConfiguration(deviceName, ipAddress, port, enabled);
RedirectResponse(sock, "success.html");
}
break;
}
}
void RedirectResponse(int sock, PCSTR new_page)
Redirect a HTTP request to a different page.

Step 3: Register Handler

"updateconfig*", // URL mask to match
configPostCallback // Callback function
);
Implements the HtmlPostVariableListHandler class as a function pointer callback for HTTP POST submiss...
Definition httppost.h:131

POST Event Flow

Form Submitted by Browser
v
eStartingPost (once)
v
eVariable (per form field)
v
┌────────┼────────┬────────┐
│ │ │ │
Field1 Field2 Field3 Field4
│ │ │ │
└────────┴────────┴────────┘
v
eFile (if file upload)
v
eEndOfPost (once)
v
Send Response

POST Events

Event When Called Purpose
eStartingPost Once at start Initialize variables, clear state
eVariable Once per form field Process each input value
eFile If file uploaded Handle file data
eEndOfPost Once at end Finalize, validate, send response

Multiple Form Handling

You can use wildcards to handle multiple forms with one callback:

void multiFormHandler(int sock, PostEvents event,
const char* pName, const char* pValue)
{
switch(event)
{
case eStartingPost:
// Determine which form based on URL
break;
// ... handle events
}
}
// Handles form1.html, form2.html, form3.html, etc.
HtmlPostVariableListCallback multiPost("form*", multiFormHandler);

Complete Examples

Example 1: System Status Page with Mixed Tags

<!DOCTYPE html>
<html>
<head>
<title>System Status</title>
<!--INCLUDE htmlvar.h -->
</head>
<body>
<h1>NetBurner System Status</h1>
<h2>System Information</h2>
<table border="1">
<tr>
<td>Uptime (seconds):</td>
<td><!--VARIABLE Secs --></td>
</tr>
<tr>
<td>Uptime (ticks):</td>
<td><!--VARIABLE TimeTick --></td>
</tr>
<tr>
<td>MAC Address:</td>
<td><!--VARIABLE GetMacAddress() --></td>
</tr>
<tr>
<td>Client Info:</td>
<td><!--CPPCALL webShowClientInfo --></td>
</tr>
</table>
<h2>Configuration</h2>
Hostname: <!--CONFIGVALUE Sys/Application/HostName --><br>
<h2>Sensor Readings</h2>
Temperature: <!--VARIABLE ReadTemperature(fd) -->C<br>
Pressure: <!--VARIABLE ReadPressure(fd) --> kPa<br>
</body>
</html>

Example 2: Interactive Control Panel

HTML Form:**

<html>
<head><title>Control Panel</title></head>
<body>
<h1>Device Control Panel</h1>
<form action="control" method="post">
<h2>Output Control</h2>
Output 1: <input type="checkbox" name="Out1"><br>
Output 2: <input type="checkbox" name="Out2"><br>
Output 3: <input type="checkbox" name="Out3"><br>
<h2>PWM Settings</h2>
Duty Cycle: <input type="range" name="Duty" min="0" max="100" value="50">
<span id="duty-value">50</span>%<br>
<br>
<input type="submit" value="Apply Settings">
</form>
<script>
// Update duty cycle display
document.querySelector('input[name="Duty"]').oninput = function() {
document.getElementById('duty-value').textContent = this.value;
};
</script>
</body>
</html>

POST Handler:**

void controlPostCallback(int sock, PostEvents event,
const char* pName, const char* pValue)
{
static bool out1 = false, out2 = false, out3 = false;
static int dutyCycle = 0;
switch(event)
{
case eStartingPost:
out1 = out2 = out3 = false;
dutyCycle = 0;
break;
case eVariable:
if (strcmp("Out1", pName) == 0)
out1 = (strcmp(pValue, "on") == 0);
else if (strcmp("Out2", pName) == 0)
out2 = (strcmp(pValue, "on") == 0);
else if (strcmp("Out3", pName) == 0)
out3 = (strcmp(pValue, "on") == 0);
else if (strcmp("Duty", pName) == 0)
dutyCycle = atoi(pValue);
break;
case eEndOfPost:
// Apply settings to hardware
SetOutput(1, out1);
SetOutput(2, out2);
SetOutput(3, out3);
SetPWMDutyCycle(dutyCycle);
printf("Outputs: %d %d %d, Duty: %d%%\r\n",
out1, out2, out3, dutyCycle);
RedirectResponse(sock, "control.html");
break;
}
}
HtmlPostVariableListCallback controlPost("control*", controlPostCallback);

Best Practices

Tag Usage Guidelines

Choose Your Approach
┌─────────┼─────────┬─────────┐
│ │ │ │
v v v v
Simple Parametric Display Config
Display Function Config Data
│ │ │ │
v v v v
VARIABLE VARIABLE() CPPCALL CONFIG
Tag Tag Tag Tags

Use VARIABLE when:**

  • Displaying simple variable values
  • Showing calculated expressions
  • Output is straightforward text/numbers

    Use VARIABLE() when:**

  • Need to pass parameters to function
  • Require conditional formatting
  • Complex data processing needed

    Use CPPCALL when:**

  • Need full control over output
  • Complex HTML generation
  • Multiple operations required

    Use CONFIG tags when:**

  • Working with Configuration Record
  • Simplifying configuration UI
  • Displaying system settings

Performance Considerations

  1. Minimize Function Calls: Each tag invokes processing overhead
  2. Buffer Output: Use efficient I/O operations
  3. Cache Values: Don't recalculate on every request
  4. Use Appropriate Tags: CONFIG tags are optimized for configuration data

Security Guidelines

  1. Validate Input: Always validate POST data
  2. Sanitize Output: Prevent injection attacks
  3. Use Access Groups: Restrict sensitive pages
  4. Implement Timeouts: Prevent resource exhaustion

Code Organization

Project Structure
┌─────────┼─────────┬─────────┬──────────┐
│ │ │ │ │
v v v v v
html/ src/ htmlvar.h makefile
v
┌─────────┼─────────┬─────────┐
│ │ │ │
v v v
main.cpp handlers.cpp utils.cpp

Recommended:**

  • Keep HTML files in html/ folder
  • Centralize handlers in dedicated source files
  • Use htmlvar.h for all HTML-exposed declarations
  • Document callback functions clearly
  • Group related handlers together

Troubleshooting

Common Issues and Solutions

Issue: CPPCALL function not found**

Symptom: Linker error or runtime error
Solution: Verify function signature exactly matches:
void FunctionName(int sock, PCSTR url)

Issue: VARIABLE not displaying**

Symptom: Blank output where variable should appear
Solution:
1. Check htmlvar.h includes proper headers
2. Verify variable is extern declared
3. Ensure WriteHtmlVariable() overload exists for type

Issue: POST variables not received**

Symptom: eVariable not called for form fields
Solution:
1. Verify form action matches handler URL mask
2. Check method="post" in form tag
3. Ensure input fields have name attributes

Issue: Spacing in tags**

Symptom: Tag not processed, appears as comment
Solution: Verify spacing:
Correct: <!--CPPCALL func -->
Incorrect: <!-- CPPCALL func -->
Incorrect: <!--CPPCALL func-->

Debug Checklist

Debug Flow
v
Verify Tag Syntax
v
Check Include Files
v
Validate Function Signatures
v
Test URL Matching
v
Review Serial Console Output
v
Examine Browser Developer Tools
  1. Enable serial console debugging with printf()
  2. Check web browser developer console for errors
  3. Verify HTML is syntactically correct
  4. Test with minimal examples first
  5. Use RedirectResponse() for POST debugging
  6. Monitor socket operations with diagnostic output

Additional Resources

Related Documentation

  • Web Server Examples: \nburn\examples\web
  • Configuration System: NetBurner Configuration Guide
  • WebSockets: WebSocket Programming Guide
  • Security: Authentication and Access Control

Key Header Files

#include <http.h> // HTTP server functions
#include <htmlfiles.h> // WriteHtmlVariable() overloads
#include <nbrtos.h> // Timing, system functions
#include <netinterface.h> // Network interface utilities

Quick Reference

Tag Syntax:**

<!--CPPCALL functionName -->
<!--VARIABLE expression -->
<!--VARIABLE function(fd, params) -->
<!--CONFIGVALUE path/to/variable -->
<!--CONFIGINPUT path/to/variable -->

Function Signatures:**

// CPPCALL
void FunctionName(int sock, PCSTR url);
// VARIABLE()
const char* FunctionName(int fd, int param);
// GET Handler
int HandlerName(int sock, HTTP_Request &request);
// POST Handler
void HandlerName(int sock, PostEvents event,
const char* pName, const char* pValue);

Declaration Templates:**

// GET Handler
CallBackFunctionPageHandler name("url", callback, tGet, 0, true);
// POST Handler
HtmlPostVariableListCallback name("url*", callback);

Summary

NetBurner's HTML processing system provides a comprehensive toolkit for building dynamic web applications on embedded devices:

Core Capabilities:**

  • Seamless integration of C/C++ code with HTML
  • Real-time variable display and function execution
  • Form processing and user input handling
  • Custom request routing and URL encoding
  • Configuration system integration

    Development Workflow:**

    Design HTML Interface
    v
    Add Dynamic Tags
    v
    Implement Callbacks
    v
    Register Handlers
    v
    Build and Deploy
    v
    Test and Iterate

    Key Takeaways:**

  • Start with simple VARIABLE and CPPCALL tags
  • Progress to GET/POST handlers for complex interactions
  • Use CONFIG tags for configuration management
  • Follow best practices for security and performance
  • Leverage examples and documentation

The NetBurner HTML processing system eliminates the complexity of traditional CGI or server-side scripting while providing powerful dynamic content capabilities optimized for embedded systems.