I am stuck in coverting Arduino variable to HTML variable

I am trying to use arduino variable in a HTML code as variable.
But i can't get it done. Hopefully you all can get me on the right road again

For example, i have this variable, which a want to be a variable in html

const char* ssid       = "WiFi-2020";             //Wifi SSID

Tried with an string convert to %ID%, but without luck.
Saw multi other options, where to variable is converted. But can't find info with the this kind of server start

  httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  config.server_port = 80;

This is my arduino part about HTML.

static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>ESP32-cam settings</title>
        <style>
          body{font-family:Arial,Helvetica,sans-serif;background:#181818;color:#EFEFEF;font-size:16px}h2{font-size:18px}section.main{display:flex}#menu,section.main{flex-direction:column}#menu{display:none;flex-wrap:nowrap;min-width:340px;background:#363636;padding:8px;border-radius:4px;margin-top:-10px;margin-right:10px}#content{display:flex;flex-wrap:wrap;align-items:stretch}figure{padding:0;margin:0;-webkit-margin-before:0;margin-block-start:0;-webkit-margin-after:0;margin-block-end:0;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:0;margin-inline-end:0}figure img{display:block;width:100%;height:auto;border-radius:4px;margin-top:8px}@media (min-width: 800px) and (orientation:landscape){#content{display:flex;flex-wrap:nowrap;align-items:stretch}figure img{display:block;max-width:100%;max-height:calc(100vh - 40px);width:auto;height:auto}figure{padding:0;margin:0;-webkit-margin-before:0;margin-block-start:0;-webkit-margin-after:0;margin-block-end:0;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:0;margin-inline-end:0}}section#buttons{display:flex;flex-wrap:nowrap;justify-content:space-between}#nav-toggle{cursor:pointer;display:block}#nav-toggle-cb{outline:0;opacity:0;width:0;height:0}#nav-toggle-cb:checked+#menu{display:flex}.input-group{display:flex;flex-wrap:nowrap;line-height:22px;margin:5px 0}.input-group>label{display:inline-block;padding-right:10px;min-width:47%}.input-group input,.input-group select{flex-grow:1}.range-max,.range-min{display:inline-block;padding:0 5px}button{display:block;margin:5px;padding:0 12px;border:0;line-height:28px;cursor:pointer;color:#fff;background:#ff3034;border-radius:5px;font-size:16px;outline:0}button:hover{background:#ff494d}button:active{background:#f21c21}button.disabled{cursor:default;background:#a0a0a0}input[type=range]{-webkit-appearance:none;width:100%;height:22px;background:#363636;cursor:pointer;margin:0}input[type=range]:focus{outline:0}input[type=range]::-webkit-slider-runnable-track{width:100%;height:2px;cursor:pointer;background:#EFEFEF;border-radius:0;border:0 solid #EFEFEF}input[type=range]::-webkit-slider-thumb{border:1px solid rgba(0,0,30,0);height:22px;width:22px;border-radius:50px;background:#ff3034;cursor:pointer;-webkit-appearance:none;margin-top:-11.5px}input[type=range]:focus::-webkit-slider-runnable-track{background:#EFEFEF}input[type=range]::-moz-range-track{width:100%;height:2px;cursor:pointer;background:#EFEFEF;border-radius:0;border:0 solid #EFEFEF}input[type=range]::-moz-range-thumb{border:1px solid rgba(0,0,30,0);height:22px;width:22px;border-radius:50px;background:#ff3034;cursor:pointer}input[type=range]::-ms-track{width:100%;height:2px;cursor:pointer;background:0 0;border-color:transparent;color:transparent}input[type=range]::-ms-fill-lower{background:#EFEFEF;border:0 solid #EFEFEF;border-radius:0}input[type=range]::-ms-fill-upper{background:#EFEFEF;border:0 solid #EFEFEF;border-radius:0}input[type=range]::-ms-thumb{border:1px solid rgba(0,0,30,0);height:22px;width:22px;border-radius:50px;background:#ff3034;cursor:pointer;height:2px}input[type=range]:focus::-ms-fill-lower{background:#EFEFEF}input[type=range]:focus::-ms-fill-upper{background:#363636}.switch{display:block;position:relative;line-height:22px;font-size:16px;height:22px}.switch input{outline:0;opacity:0;width:0;height:0}.slider{width:50px;height:22px;border-radius:22px;cursor:pointer;background-color:grey}.slider,.slider:before{display:inline-block;transition:.4s}.slider:before{position:relative;content:"";border-radius:50%;height:16px;width:16px;left:4px;top:3px;background-color:#fff}input:checked+.slider{background-color:#ff3034}input:checked+.slider:before{-webkit-transform:translateX(26px);transform:translateX(26px)}select{border:1px solid #363636;font-size:14px;height:22px;outline:0;border-radius:5px}.image-container{position:relative;min-width:160px}.close{position:absolute;right:5px;top:5px;background:#ff3034;width:16px;height:16px;border-radius:100px;color:#fff;text-align:center;line-height:18px;cursor:pointer}.hidden{display:none}
        </style>
    </head>
      <body onload="SetPin()">
         <section class="main">
            <section id="buttons">
                <table>
                <tr><td align="center"><button><a href="/stream">Click on me, for going to camera stream.</a></button></td></tr>
                <tr><td align="center"><button><a href="/capture">Click on me, for capturing camera image.</a></button></td></tr>
                <tr><td align="center"><button><a href="/on">Click on me, to turn on button led.</a></button></td></tr>
                <tr><td align="center"><button><a href="/off">Click on me, to turn off button led.</a></button></td></tr>
                <tr><td align="center"><p id="demo"></p></button></td></tr>
                <tr><td align="center"><p id="demo1"></p></button></td></tr>
                </table>
            </section>         
        </section>
        <script>
   function SetPin() {
      console.log("SetPin start")
      var test = "werkt"
      var test1 = ssid
      document.getElementById("demo").innerHTML = test
      document.getElementById("demo1").innerHTML = test1 
      console.log("if is executing")
    }
</script>
      </body>
    </html>
)rawliteral";


static esp_err_t index_handler(httpd_req_t *req){
    httpd_resp_set_type(req, "text/html");
    return httpd_resp_send(req, (const char *)INDEX_HTML, strlen(INDEX_HTML));
}

This is my arduino part about HTML.

And how do you store that in your sketch ?
How to include the contents of a variable into you Page depends on the method you use to send the information back to the client after it makes a request.

The methode of sending back was shown at the buttom of the html code part

static esp_err_t index_handler(httpd_req_t *req){
    httpd_resp_set_type(req, "text/html");
    return httpd_resp_send(req, (const char *)INDEX_HTML, strlen(INDEX_HTML));
}

static const char PROGMEM INDEX_HTML[] = R"rawliteral(When this is in progmem you can not do anything. Again i have no idea what what board, and what libraries you are using, but a fairly normal way of doing it if you are on an ESP is to first store the page in a String part by part

String s = INDEX_HTML1;
s += ssid; // add the contents of ssid
s += INDEX_HTML2; // add the 2nd part of the page
return httpd_resp_send(req, s, s.length());  // and send that

I normally use the ESP8266webserver.h for handling clients, but the idea is the same.

These are included

#include "esp_camera.h" 
#include <WiFi.h> 
#include "esp_timer.h" 
#include "img_converters.h" 
#include "Arduino.h" 
#include "fb_gfx.h" 
#include "soc/soc.h" //disable brownout problems 
#include "soc/rtc_cntl_reg.h" //disable brownout problems #include "esp_http_server.h" 
#include <HTTPClient.h>

The bord is an esp32-cam
Maybe i have to look over, to modify the webserver part

Deva_Rishi:
static const char PROGMEM INDEX_HTML[] = R"rawliteral(When this is in progmem you can not do anything. Again i have no idea what what board, and what libraries you are using, but a fairly normal way of doing it if you are on an ESP is to first store the page in a String part by part

String s = INDEX_HTML1;

s += ssid; // add the contents of ssid
s += INDEX_HTML2; // add the 2nd part of the page
return httpd_resp_send(req, s, s.length());  // and send that



I normally use the ESP8266webserver.h for handling clients, but the idea is the same.

Do you have an example of the complete script?
Or a hyperlink to somewhere, where a complete code can be found?

I too am wondering what is the best way to build a webserver page and have tried a number of methods including this, which I am not putting forward as a model of how it should be done, rather it is a way that it can be done

    String webBuffer; //*NOTE* the ESP32 webserver library only works with Strings
    //using raw strings
    webBuffer = R"(<html><head>
    <style>table {font-family: arial, sans-serif;border-collapse : collapse;}
    th, td {border: 1px solid black;border-collapse: collapse; padding: 10px;}
    </style>
    <title>ESP32 Web Server</title>
    </head><body><h1>From ESP32</h1>
    <table>
    <tr><td>Count</td><td>)";
    webBuffer += String(data.count); //count as a String
    webBuffer += R"(</td></tr>
    <tr><td>Temperature</td><td>)";
    webBuffer += String(data.temperature); //temperature as a String
    webBuffer += R"(</td></tr>
    <tr><td>Humidity</td><td>)";
    webBuffer += String(data.humidity);  //humidity as a String
    webBuffer += R"(</td></tr>
    </table>
    

    <form action='/update' method='POST'>
    <input type='submit' value='Click to update'> </form>
    <form action='/webList' method='POST'>
    <input type='submit' value='Click to list records'></form>
    <form action='/webCount' method='POST'>
    <input type='submit' value='Click to count records'></form>
    </body></html>)";
    if (debugHTML)
    {
      Serial.println(webBuffer);  //raw text makes it easier to read
    }
    webServer.sendContent(webBuffer);

Please accept my aplogies for any HTML sins that I have commited in the page layout as I am learning that as I go along too

Elsewhere in the sketch I have used this method

  webServer.sendContent("<html><body><head>");
  webServer.sendContent("<style>");
  webServer.sendContent("table {font-family: arial, sans-serif; border-collapse: collapse;}");
  webServer.sendContent("th,td {border: 1px solid black; padding-left: 8px; padding-right: 8px;}");
  webServer.sendContent("td {text-align: center;}");
  webServer.sendContent("tr:nth-child(even) {background-color: #eeeeee;}");
  webServer.sendContent("</style>");
etc, etc

but it creates many more individual transactions so I will probably switch it to using raw text

I am also considering putting the fixed portions of the HTML into files in SPIFFS but as one of pages lists a variable number of records in a table it cannot all be in SPIFFS

Decisions, decision

Do you have an example of the complete script?

Check out the hello server example and specifically how the 'String that gets send in the handleNotFound() function is created and then send in one go using

server.send(404, "text/plain", message);

You can do it in a similar way (though using text/html instead) for your page. To store a page in Progmem is great if you are short on RAM, but honestly on an ESP that is rarely an issue, and if you want to include variable values within your page very unpractical.
here is another example, this is a function i use for my httpUpdate page

const char
*pageheader = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
 *htmlhead = "<html><head><title>SecureWebUpdate</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" ></head>",

    *successresponse = "<META http-equiv=\"refresh\" content=\"15;URL=/\">Update Success! Rebooting...\n",
     *bodystyle = "<body style=\"color: dimgray; background-color: palegoldenrod; font-size: 12pt; font-family: sans-serif;\">",

        *htmlclose = "</body></html>";

void handleUpdate() {
  if (username != NULL && password != NULL && !server.authenticate(username, password))
    return server.requestAuthentication();
  String s = "";
  s += pageheader;
  s += htmlhead;
  s += bodystyle;
  s += "<h1>OTA Firmware Update</h1>";
  s += "<pre>Make sure you choose the proper file !
";
  s += "Choosing the incorrect file will disable over the air updates.
";
  String flashtype = String (ESP.getFlashChipId(), HEX);
  if (flashtype == "14405e") s += "Choose the file with \"8285\" in it's name.";
  else s += "Choose the file with \"generic\" in it's name.";
  s += "</pre>";
  s += "<pre><form method=\"POST\" action=\"\" enctype=\"multipart/form-data\">";
  s += "<input type=\"file\" name=\"update\">";
  s += "           <input type=\"submit\" value=\"  Update  \"></form></pre>";
  s += htmlclose;
  server.send(200, "text/html", s);
}

I have quite a bit of experience with this, so I will describe my method. I have an HTML file, and where I want the variable to be, I have a comment that is structured in a way to reference the position in a known array I use this for drop downs to select options based on current settings etc. In my parsing function, as I am parsing the HTML, when the comment is found, and the variable is found, my code determines what to replace the comment with, which it then parses in it's place.

Perehama:
I have quite a bit of experience with this, so I will describe my method. I have an HTML file, and where I want the variable to be, I have a comment that is structured in a way to reference the position in a known array I use this for drop downs to select options based on current settings etc. In my parsing function, as I am parsing the HTML, when the comment is found, and the variable is found, my code determines what to replace the comment with, which it then parses in it's place.

sorry, i don't understand how you do it, to reproduce it by myself.
Could you please post an example code?

i tried the string option, to get it working. But without luck

My server announcement is;

httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  config.server_port = 80;

On the web, but also the "Hello Server" example a few posts back, don't work with that.
They work with:

WebServer server(80);

That is where i get stuck. Because i use the camera stream on the esp32-cam, i prefer the httpd_config_t to use. Because that script part is done. But than i get the webbrowser not working. When i go with webserver server(80), than the webbrowser works, but my camera stream is broken. And i can't find information how to get a live camera stream with the webserver server(80)

Tried this code Deva_Rishi posted, but i don't get it to work.

String s = INDEX_HTML1;
s += ssid; // add the contents of ssid
s += INDEX_HTML2; // add the 2nd part of the page
return httpd_resp_send(req, s, s.length());  // and send that

Changed it to:

String SendHTML(){
  String s = "<p>ESP32 Web Server</p>";
  s += ssid;
  s +="<p>Using Access Point(AP) Mode</p>";
  return httpd_resp_send(req, s, s.length());     
  }

Than i get this response:

'req' was not declared in this scope

Tried to put this on top

static esp_err_t index_handler(httpd_req_t *req)

Then error another error.

I think i am to stuppid to get this.
Don't know why i can't get this code to work.

On the web, but also the "Hello Server" example a few posts back, don't work with that.
They work with:

So why don't you use that ?

Deva_Rishi:
So why don't you use that ?

When i use that, the live cam-stream script is broken.
Covert that to get it working is not what i prefer.

OK, so let's go back a bit, first of all you understand i don't have a complete code of how to create a webserver the way you do, simply because i don't do it that way, but let's see if we can just work with what you have and how i create the output and convert it all.

static esp_err_t index_handler(httpd_req_t *req){
    httpd_resp_set_type(req, "text/html");
    return httpd_resp_send(req, (const char *)INDEX_HTML, strlen(INDEX_HTML));
}

is what you send in which INDEX_HTML is raw data.
I Create a String and send it, when in this case the function that you use takes a char *, keep in mind i have no way to verify your code as such (i actually don't really want to, i suppose i could but ok..)

static esp_err_t index_handler(httpd_req_t *req){
    httpd_resp_set_type(req, "text/html");   // the first bit can just stay as it is. 

    String s =  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";  // let's put a proper header
    s +=  "<html><head><title>ESP32 Server</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" ></head>";
    s += "<body style=\"color: dimgray; background-color: palegoldenrod; font-size: 12pt; font-family: sans-serif;\">";      // and a proper body style

    s += "<p>ESP32 Web Server</p>";
    s += ssid;
    s +="<p>Using Access Point(AP) Mode</p>";
    s += "</body></html>"; // and close it off properly

    char chp[s.length() + 1];  // convert it to a char array
    s.toCharArray(chp, s.length() + 1);

    return httpd_resp_send(req, (const char *) chp, strlen(chp));  // and now send it as response
}

This is of course a bit bent, we could just create a char array right of the bat, but then we would have to make sure the array is big enough to hold all of the data, like this we don't worry about it, but in effect temporarily use up twice the amount of memory, and it is probably a bit slower. Both resources are not very scarce on an ESP though.
So i haven't checked to see it compiles, but let me know if there are any errors (and what they are !) maybe just typo's maybe something structural i can't tell.
Also, where did you get the example from, is it from any of the 'core' examples ?

The camera stream is a default example which is in ide program.
That i used for a basic start and added things i was looking for. These added things are basic, just an on or Off and sending a http string.

The camera video stream in combination with a webserver which uses the same variables as the code, that is where the problem is.

The webserver idea ook posted, didn't let me go.
I got it working making a still image. But a stream i have to look over it, hoe to get that working. The reson i looked at the webserver idea, is that the submit functions are working far more easy than the https way.

I will try your idea this evening.
Will post back if all went ok, or what the response is.
Thanks for all your effort helping me

Tested the code.
First i got it didn't startup.

But changed a thing in the supply and it started.
Your script does the trick. Now i am trying to add some text in front of the variable.

thanks

Setting up text i front (or back) of the variable worked.
Thanks for all the help.

For now i am going futher with this. When everything is done, i will look over the set it up with the webserver(80)