[solved] Multiple webpages

Hi all. I'm building a WiFi home automation main lighting system, capable of 255 10watt LED downlights, with a webserver based on the work of PieterP. It all sort of works (still polishing), but now I want to add more pages. This is the part that serves the page from the SPIFFS memory of the WeMos D1 mini.

void startServer() {
  server.onNotFound(handleNotFound); // if non-existing file or page, go to function 'handleNotFound'
  server.begin();
  Serial.println("HTTP server started");
}
void startWebSocket() {
  webSocket.begin();
  webSocket.onEvent(webSocketEvent); // if incomming websocket message, go to function 'webSocketEvent'
  Serial.println("WebSocket server started\n");
}
void handleNotFound() { // see if requested file or page exists
  if (!handleFileRead(server.uri())) { // if so, send it
    server.send(404, "text/plain", "404: File Not Found"); // if not, send 404 error
  }
}
bool handleFileRead(String path) { // send the right file to the client, if it exists
  Serial.println("handleFileRead: " + path);
  if (path.endsWith("/")) path += "main.html"; // if a folder is requested, send the index file
  String contentType = getContentType(path); // get the MIME type
  String pathWithGz = path + ".gz";
  if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { // if the file exists, compressed or normal
    if (SPIFFS.exists(pathWithGz)) path += ".gz"; // use the compressed version if available
    File file = SPIFFS.open(path, "r"); // open the file
    size_t sent = server.streamFile(file, contentType); // send it to the client
    file.close(); // close the file
    Serial.println(String("\tSent file: ") + path);
    return true;
  }
  Serial.println(String("\tFile Not Found: ") + path);
  return false; // if the file doesn't exist
}

I have a question about this line. if (path.endsWith("/")) path += "main.html"; Can I add more pages here. Adding an else if() line or simply editing the "/" (code and browser) does not work. Leo..

You could maybe have some lines up above that line to build a string with the name of the file you want and then have that line be:

if (path.endsWith("/")) path += theStringYouBuilt;

I'm going with "no". It looks like that code is providing a default document name.

For example, if the request is for...

https://www.wawa.net/

That code changes the request to...

https://www.wawa.net/main.html

In most cases "index.htm" or "index.html" is used as a default document name.

...but now I want to add more pages...

-- ? --

Delta_G: You could maybe have some lines up above that line to build a string with the name of the file you want and then have that line be:...

Not sure if I follow you. If I change that string, I also have to change the html folder name. I don't see how I can select different html folders that way with the browser. So the browser has to select the page. I don't know how to read a browser page request. e.g. "lights.local/main" in the browser for the main page, and "lights.local/page1" for a sub page "lights.local" being the mDNS name I gave it, but I also use fixed IP address access for non-mDNS enabled devices.

[quote author=Coding Badly date=1519953657 link=msg=3630017] I'm going with "no".

In most cases "index.htm" or "index.html" is used as a default document name.

-- ? -- [/quote] "No" is not an option. I have made multiple page webservers before. Could be that adding pages in this part of the code is not an option. Like to know which other ways there are to skin this cat.

I know how to link the code file name to the real file name.

--?-- The sub-pages is to give users access to a limited area of the house. A .html sub-set of the main page. Mainly to make operation more simple. Leo..

Wawa: Could be that adding pages in this part of the code is not an option.

That is what I mean by "no". Changing that code is most certainly not going to have the affect you want.

e.g. "lights.local/main" in the browser for the main page, and "lights.local/page1" for a sub page

Do you have a folder named "lights.local" on the device? Does it contain a folder named "main" and a folder named "page1"?

“lights” is the mDNS name I gave the website.
You can access the site with “lights.local” on an mDNS enabled device (fruitphone, but not Android).

I think Win10 has mDNS by default, but for Win7 you need to install the software.
I think it comes with a “Bonjour” printer driver, and other software.

If you don’t have an mDNS, you must use an IP address.
The local IP address the LAN/router gave you (with DHCP).
Downside is that IP address changes after some programmed lease time, so I use a fixed IP address.
Leo…

Sometimes you don't see things that are right in front of you...

if (path.endsWith("/")) path += "main.html"; // original page else if (path.endsWith("/")) path += "page1.html"; // added page

And ofcourse having those two files in the SPIFFS memory.

And requesting "lights.local/page1.html" in the browser, seems to work.

Still have to build the page, but I think it's going to work. Leo..

Wawa: if (path.endsWith("/")) path += "main.html"; // original page else if (path.endsWith("/")) path += "page1.html"; // added page

This...

path += "page1.html";

...is unreachable.

If path ends with "/" then the first if captures the condition so the else-clause is not executed.

The other possibility is that path does not end with "/" then the else-clause is executed but the second if cannot be true.

Don't understand why it works, but it does. With an if(), or with an else if(). the ("/") must be there, and I also have to use the .html file extension. Leo..

I think I solved it. The browser link points ofcourse to a folder tree on the SPIFFS, not to files. So I moved "page1.html" to it's own folder. now I do this in the sketch:

if (path.endsWith("/")) path += "main.html"; // original page in the root of the SPIFFS if (path.endsWith("/page1")) path += "/page1.html"; // added page in a sub folder

In the browser: "lights.local" now selects the main page, and "lights.local/page1" selects the sub page. Leo..

I can see how you could simplify your part (the developer) of that and get the same result. There is a minor side effect but it would not affect you. If you're interested.

Post#9 seems to be a clean way of solving it, but I'm always interrested in new angles. This project is more of a learning exercise than anything else (self-taught coding noob). Keeps the old brain ticking over.

It currently has several 16-channel LED driver slave boards with ESP-12 modules that are controlled with broadcast UDP from a WeMos D1 mini. The slave boards that have the LED/dimming code are mounted in the ceiling cavity.

The WeMos master can be controlled via the LAN/WiFi as well as it's own AP/WiFi, in case the power goes down. (the whole setup can be solar/battery powered) Control is with a block-style dashboard webpage, so the user can select/dim single/groups of lights. Webpages load the current state of the lights, and the page is updated when another user makes changes (websockets). OTA update of the master (main control code) is planned, and maybe e-buttons remotes for a single function. One day, when I'm happy with most of it, I will post the whole project. Leo..

This provides a default document if one is not specified. Keep it.

if (path.endsWith("/")) path += "main.html"; // original page in the root of the SPIFFS

At this point, the old code kept the path intact. Whatever was requested is returned or, if the document does not exist, an error (or default document) is returned.

In your revision, a document is add if just a path is provided. Instead, providing a default extension allows you to eliminate the subdirectory and easily add simple landings.

else
{
  if ( path.indexOf('.') == -1 ) path += ".html"; // page1 becomes page1.html
}

With that change the mapping becomes this...

"lights.local" --> "lights.local/main.html"

"lights.local/page1" --> "lights.local/page1.html"

Adding page2 is trivial: just put page2.html in the same location as main.html and page1.html. No code change is necessary.

Clever solution. Tested with three pages, and works 100%. This also eliminates the need to add new if() statements when new sub pages are added. Permanently added to the code. Thank you. Leo..

Thanks. Glad to know it works for you.

You are welcome.