Im vierten Projekt `webapp4` werden weitere 6 Webseiten als Erweiterung des Projektes `webapp3` auf der Basis der Klasse Webpage erzeugt. Die Webseite mit einem (SQLite-)Datenbank-Report sehen Sie hier:
Abbildung 24.6.2.4.1: (SQLite-)Datenbank-Report (Ausschnitt)
Die Webpage Main.webpage ist auch in diesem Projekt die wichtigste Datei des Templates, denn sie enthält am Anfang einen Gambas-Block für das Auslesen der im Webbrowser gesetzten Sprache sowie der angeforderten Webseite und dann den Head-Bereich mit einem Platzhalter. Danach folgt HTML mit weiteren Platzhaltern für die Layout-Bereiche Header, Navigation, Content und Footer:
[1] <% [2] '-- Variable declaration must come before any HTML [3] Dim sCurSite As String [4] Dim aSiteList As New String[] [5] [6] '-- The browser tells the server which language (locale) it is set to via Request.Language. [7] System.Language = Request.Language ' Example: de_DE.UTF8 [8] '-- Insert a list to filter the pages [9] aSiteList = Main.SiteList [10] [11] If Request.Query Then [12] If aSiteList.Exist(Request.Query) Then [13] sCurSite = Request.Query [14] Endif [15] Else [16] sCurSite = aSiteList[0] [17] Endif [18] %> [19] <!DOCTYPE html> [20] <html lang="de"> [21] <!-- BEGIN SITE-HEAD --> [22] <head> [23] <meta charset="UTF-8"> [24] <!-- Setting for display on mobile devices | MediaQueries --> [25] <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> [26] <!-- The description is used for display in search engines! --> [27] <meta name="description" content="TEMPLATE: WEBPAGE GAMBAS HTML CSS JS"> [28] <!-- The title of the web page is displayed in the browser tab! --> [29] <title><%=sCurSite%></title> <!-- < 30 Zeichen --> [30] <!-- Reference to an icon. The favicon is displayed in the browser tab! --> [31] <link rel="icon" type="image/png" href="./favicon/favicon_blue_32.ico"> [32] <!-- Reference to a central CSS file in the /css folder --> [33] <link rel="stylesheet" type="text/css" href="./css/style.css"> [34] <!-- Reference to a JavaScript file in the /js folder --> [35] <script src="./js/set_time.js"></script> [36] </head> [37] <!-- END SITE-HEAD --> [38] <body onload="JSTimer1();"> [39] <<IncHeader>> [40] <br> [41] <<IncNavigation>> [42] <br> [43] <main> [44] <<IncContent>> [45] </main> [46] <<IncFooter>> [47] </body> [48] </html>
Die Gambas-Klassen-Datei main.class enthält eine erweiterte Liste der aktuell verfügbaren Webseiten, die in der Variablen `SiteList` gespeichert wird:
' Gambas class file Public SiteList As String[] = ["Start", "Umgebung", "Zeit", "Datum", "Multimedia", "DBReport", "Formular", "FPlotter", "Impressum"]
Kommentar
1. <!--BEGIN SITE-HEADER --> 2. <header class="site-header"> 3. <img class="site-logo" src="./icons/logo3_256x256.png" alt="Gambas-Logo"> 4. <p class="site-slogan">Webseiten mit Gambas-Webpage erzeugen</p> 5. </header> 6. <!-- END SITE-HEADER -->
Die Webpage IncContent.webpage enthält u.a. 9 Platzhalter, die in Abhängigkeit von der angeforderten Webseite (Request-Query) durch den Inhalt der einzelnen Webseiten ersetzt werden.
[1] <!-- START: INSERT SELECTED CONTENT --> [2] <%Select Request.Query [3] Case "Umgebung"%> [4] <<IncEnvironment>> [5] <% Case "Zeit"%> [6] <<IncTime>> [7] <%Case "Datum"%> [8] <<IncDate>> [9] <%Case "Multimedia"%> [10] <<IncMultimedia>> [11] <%Case "DBReport"%> [12] <<IncDBReport>> [13] <%Case "Formular"%> [14] <<IncFormular>> [15] <%Case "FPlotter"%> [16] <<IncFPlotter>> [17] <%Case "Impressum"%> [18] <<IncImpressum>> [19] <%Default%> [20] <<IncHome>> [21] <%End Select%> [22] <!-- END: INSERT CONTENT -->
Die Gambas-Klassen-Datei IncContent.class ist leer.
Kommentar
Hinweis:
Der Inhalt der Webpage IncNavigation.webpage ist der gleiche wie im Web-Projekt `webapp3` und wird 1:1 übernommen.
In den folgenden sechs Absätzen wird der HTML-Quelltext für den Bereich 'Content' der Webseiten Zeit, Datum, Multimedia, DBReport, Formular und FPlotter angegeben und kommentiert.
Die Webpage IncTime.webpage enthält u.a. einen Platzhalter (Zeile 5) für die einzufügende aktuelle Uhrzeit:
[1] <!-- INSERT TIME --> [2] <h1>Aktuelle Zeit</h1> [3] <div class="thin-box"> [4] <figure> [5] <h2 id="set_time"></h2> [6] </figure> [7] </div>
Die Gambas-Klassen-Datei IncTime.class ist leer.
Kommentar
Abbildung 24.6.2.4.2: Anzeige der aktuellen Uhrzeit
Die Webpage IncDate.webpage enthält in der Zeile 5 u.a. einen Platzhalter für das einzufügende Datum in einem bestimmten Format:
[1] <!-- INSERT DATE --> [2] <h1>Aktuelles Datum</h1> [3] <div class="thin-box"> [4] <figure> [5] <h2><%=Format(Now, "dddd - d. mmmm yyyy")%></h2> [6] </figure> [7] </div>
Kommentar
Was wäre eine Webseite ohne Bilder und andere multimediale Elemente wie Sound- oder Video? Genau diese drei Elemente werden in die Webseite IncMultimedia.webpage nacheinander eingefügt:
[1] <h1>Multimedia</h1> [2] [3] <!-- INSERT IMAGE --> [4] <div class="thin-box"> [5] <h3>Bilder flexibel einfügen</h3> [6] <hr> [7] <figure> [8] <img src="./images/tom_780x1012.png" alt="Tom" width="343" height="445"> [9] <figcaption>Tom im Rockkonzert in Berlin</figcaption> [10] </figure> [11] </div> [12] <!-- INSERT AUDIO --> [13] <div class="thin-box"> [14] <h3>Audio-Dateien einfügen</h3> [15] <hr> [16] <figure> [17] <!-- Bedienelemente anzeigen und Metadaten laden --> [18] <audio src="./audiovideo/tom.mp3" type="audio/mp3" controls></audio> [19] <figcaption>Sänger: Tom -> Der Berliner</figcaption> [20] </figure> [21] </div> [22] <!-- INSERT VIDEO --> [23] <div class="thin-box"> [24] <h3>Video-Dateien einfügen</h3> [25] <hr> [26] <figure> [27] <video src="./audiovideo/viehscheid.mp4" controls></video> [28] <figcaption>Viehscheid in Gunzesried (Allgäu)</figcaption> [29] </figure> [30] </div>
Kommentar
Abbildung 24.6.2.4.3: Bild-Anzeige
Abbildung 24.6.2.4.4: Bedienelemente Sound
Abbildung 24.6.2.4.5: Bedienelemente Video (und Fußzeile)
Die Gambas-Klassen-Datei IncMultimedia.class ist leer.
Die Webpage IncDBReport.webpage ist nennenswert kurz und enthält einen Platzhalter für den einzufügenden Datenbank-Report:
[1] <% Print DBReport(); %> [2] <br>
Die Erzeugung des (SQLite-)Datenbank-Reports wird in die Gambas-Klassendatei IncDBReport.class ausgelagert:
[1] ' Gambas class file [2] [3] Public rDBResult As Result [4] Public cDBConnection As New Connection [5] [6] Public Function DBReport() As String [7] [8] Dim iRecord, iField As Integer [9] Dim sSQL, sHTML As String [10] Dim aFieldNamesDisplayed As String[] [11] [12] aFieldNamesDisplayed = ["ID", "Vorname", "Nachname", "Wohnort", "PLZ", "Straße", "Geburtstag", "Festnetz", "Mobil", "EMail"] [13] [14] cDBConnection.Type = "sqlite3" [15] cDBConnection.Host = Application.Path &/ ".public/db" [16] cDBConnection.Name = "contacts.sqlite" [17] [18] Try cDBConnection.Open() [19] If Error Then [20] '-- Option: sHTML &= "<h1>A DB connection could not be established!</h1>" [21] CGI.Error("A DB connection could not be established!") [22] Return [23] Endif [24] [25] cDBConnection.Exec("PRAGMA short_column_names = ON") [26] [27] sSQL = "SELECT * FROM contacts" [28] [29] Try rDBResult = cDBConnection.Exec(sSQL) [30] If Error Then [31] Error.Raise("<h1>Error!<br>" & Error.Text & "</h1>") [32] Endif [33] [34] If rDBResult.Count = 0 Then [35] Error.Raise("<h1>The number of selected records is zero!</h1>") [36] Endif [37] [38] '-- Enter the field names in the table header [39] If rDBResult.Available Then [40] sHTML &= "<h1 style=\"margin-bottom:0.6rem;\">" [41] sHTML &= "Datenbank-Report" [42] sHTML &= "</h1>" [43] sHTML &= "<h3 style=\"margin-bottom:1.4rem;\">" [44] sHTML &= Format(Now, "dddd - d. mmmm yyyy") & " - " & Format$(Now, "hh:nn") & " Uhr" [45] sHTML &= "</h3>" [46] sHTML &= "" [47] sHTML &= "<table>" [48] sHTML &= "<tr>" [49] For iField = 0 To rDBResult.Fields.Count - 1 [50] sHTML &= "<th>" & aFieldNamesDisplayed[iField] & "</th>" [51] Next [52] sHTML &= "</tr>" [53] [54] '-- Fill the (HTML)table with the DB data [55] For iRecord = 0 To rDBResult.Count - 1 [56] sHTML &= "<tr>" [57] rDBResult.MoveTo(iRecord) [58] [59] For iField = 0 To rDBResult.Fields.Count - 1 [60] If rDBResult.Fields[iField].Name = "gebdatum" Then [61] sHTML &= "<td>" & Format(rDBResult[iField], "dd.mm.yyyy") & "</td>" [62] Else [63] sHTML &= "<td>" & rDBResult[iField] & "</td>" [64] Endif [65] Next '-- Column [66] sHTML &= "</tr>" [67] Next '-- DB-Record [68] [69] sHTML &= "</table>" [70] sHTML &= gb.Lf [71] [72] Endif [73] [74] '-- Ausgabe des kompletten HTML als HTML-Block [75] Return sHTML [76] [77] Catch [78] Return Error.Text [79] [80] End
Kommentar
Abbildung 24.6.2.4.6: (SQLite-)Datenbank-Report (Ausschnitt)
An dieser Stelle werden nur ein bestimmtes Formular, die Verarbeitung der Formulardaten sowie deren Auswertung beschrieben. Die Struktur von Formularen und die Syntax von (HTML-)Formularen sowie deren Felder sind nicht Gegenstand dieser Beschreibung. Dem interessierten Leser sei die Recherche selbst nahegelegt. Ein guter Startpunkt ist https://wiki.selfhtml.org/wiki/HTML/Tutorials/Formulare/Was_ist_ein_Webformular%3F#Buttons.
Quelltext der Webpage IncFormular.webpage:
[1] <% [2] Dim i As Integer [3] Dim sField, sErrorMessage As String [4] Dim vValue As Variant [5] Dim aRequestFields, aFieldList As New String[] [6] Dim cData, cRadioList As New Collection [7] [8] cData.Add("off", "material") [9] cData.Add("off", "confirmation_gdpr") [10] [11] cRadioList.Add("Ubuntu", "ubuntu") [12] cRadioList.Add("Mint", "mint") [13] cRadioList.Add("Eine andere Distribution", "another") [14] [15] aFieldList = ["token", "firstname", "lastname", "birthday", "email", "material", "os_version", "message", "confirmation_gdpr"] [16] [17] aRequestFields = Request.Post.Fields [18] [19] If Request.Method = "POST" And Request.Post["token"] = "ok" Then [20] For Each sField In aRequestFields [21] Select sField [22] Case "material" [23] cData.Add("on", "material") [24] Case "confirmation_gdpr" [25] cData.Add("on", "confirmation_gdpr") [26] Case "message" [27] If Request.Post[sField] = "" Then [28] cData.Add("empty", "message") [29] Else [30] cData.Add(Request.Post[sField], sField) [31] Endif [32] Default [33] cData.Add(Request.Post[sField], sField) [34] End Select [35] Next [36] [37] For Each vValue In cData [38] Select Case cData.Key [39] Case "confirmation_gdpr" [40] If Html(vValue) = "off" Then [41] sErrormessage = "Ohne Ihre Einwilligung zur Erfassung, Speicherung ... .<br><br>" [42] Endif [43] End Select [44] Next [45] [46] If sErrorMessage = "" Then [47] %> [48] <br> [49] <h3>Anmeldung zum Gambas-Grundkurs</h3> [50] <p>Hallo <%=cData["firstname"]%>!<br><br>Sie haben sich erfolgreich angemeldet. ... .</p> [51] <% [52] Else [53] %> [54] <h3>Hinweis zur Online-Anmeldung zum Gambas-Grundkurs</h3> [55] <% [56] Print sErrorMessage [57] Print "<br>" [58] %> [59] <button onclick=" history.back()">Zurück zum Formular</button> [60] <% [61] Endif [62] Else [63] %> [64] <h1>Anmeldung zum Gambas-Grundkurs</h1> [65] <p></p> [66] [67] <form action=<%=Application.Root%>?Formular method="post" accept-charset="UTF-8"> [68] [69] <fieldset> [70] <legend>Persönliche Daten</legend> [71] <!-- Verstecktes Feld zum Nachweis, dass die Daten aus diesem Formular stammen --> [72] <input type="hidden" id="token" name="token" value="ok"> [73] [74] <label for="firstname">Ihr Vorname</label> [75] <input type="text" id="firstname" name="firstname" required autofocus> [76] [77] <label for="lastname">Ihr Nachname</label> [78] <input type="text" id="lastname" name="lastname" required> [79] [80] <label for="birthday">Ihr Geburtsdatum (optional)</label> [81] <input type="date" id="birthday" name="birthday"> [82] [83] <label for="email">Ihre EMail-Adresse</label> [84] <input type="email" id="email" name="email" required> [85] </fieldset> [86] [87] <fieldset> [88] <legend>Kursmaterial</legend> [89] <input type="checkbox" id="material" name="material"> [90] <label>Soll das Kurs-Material schon vor dem Kurs zugeschickt werden?</label> [91] </fieldset> [92] [93] <fieldset> [94] <legend>Welche Linux-Distribution nutzen Sie aktuell?</legend> [95] <div class="radiobox"> [96] <input type="radio" id="ubuntu" name="os_version" value="ubuntu"> [97] <label>Ubuntu</label> [98] </div> [99] <div class="radiobox"> [100] <input type="radio" id="mint" name="os_version" value="mint" checked="checked"> [101] <label>Mint</label> [102] </div> [103] <div class="radiobox"> [104] <input type="radio" id="another" name="os_version" value="another"> [105] <label>Eine andere Distribution</label> [106] </div> [107] </fieldset> [108] [109] <fieldset> [110] <legend>Grundkurs</legend> [111] <label for="message">Ihre Nachricht an die Kursleitung (optional)</label> [112] <textarea id="message" name="message"></textarea> [113] </fieldset> [114] [115] <fieldset> [116] <legend>DSGVO</legend> [117] <!-- General Data Protection Regulation (gdpr) - Datenschutz-Grundverordnung --> [118] <input type="checkbox" id="confirmation_gdpr" name="confirmation_gdpr" checked> [119] <label>Mit der Nutzung dieses Formulars erklären Sie sich mit der Erfassung, Speicherung und Verarbeitung Ihrer Daten bis zum Abschluss des Kurses einverstanden.</label> [120] </fieldset> [121] [122] <button type="submit">Zum Gambas-Kurs verbindlich anmelden</button> [123] [124] </form> [125] <% [126] Endif [127] %> [128] <br>
Kommentar
Abbildung 24.6.2.4.7: Formular-Quittung
Hinweise
Formular-Felder vom Typ 'radio' und 'checkbox' sind mit besonderer Sorgfalt auszuwerten. Der Grund liegt darin, dass Feldnamen von diesen Typen nicht in das String-Array Request.Post.Fields aufgenommen werden, wenn sie nicht ausgewählt oder markiert wurden! Ein leeres Text-Feld dagegen wird mit dem Feldnamen in das String-Array Request.Post.Fields aufgenommen, aber einem leeren String als Feldwert.
Beispiel:
Das Formular im Projekt `webapp4` hat 9 Formular-Felder – eines davon vom Typ 'hidden' mit dem festen Feldwert 'ok'. Die Formular-Felder `material`, `confirmation_gdpr` (Typ 'checkbox') und `os_version` (Typ 'radio') werden nicht ausgewählt und das (Text-)Feld `message` bleibt leer.
Lassen Sie sich nach dem Abschicken des Formulars die Feldnamen und Feldwerte aller Formularfelder ausgeben:
aRequestFields = Request.Post.Fields If Request.Method = "POST" And Request.Post["token"] = "ok" Then For i = 0 To aRequestFields.Max Print "Field " & (i+1) & " => " & aRequestFields[i] & " ---> Field_Value = " & Html(Request.Post[aRequestFields[i]]) & "<br>" Next ... EndIf
ergibt sich exemplarisch diese Liste mit den Feldnamen und deren Feldwerte:
Field 1 => token ---> Field_Value = ok Field 2 => firstname ---> Field_Value = Klaus Field 3 => lastname ---> Field_Value = Mayer Field 4 => birthday ---> Field_Value = 1999-11-03 Field 5 => email ---> Field_Value = klaus.mayer.99@web.de Field 6 => message ---> Field_Value =
Es fehlen 3 Felder in Request.Post.Fields und damit in der Feldliste! Ein Ansatz, um diesen Mangel zu beheben besteht darin, eine Variable cData vom Typ Collection zu definieren und mit passenden Werten zu initialisieren:
cData.Add("off", "material") cData.Add("off", "confirmation_gdpr")
In einer Kontrollstruktur werden alle Felder in Request.Post.Fields ausgelesen und passende Werte zugewiesen:
aRequestFields = Request.Post.Fields If Request.Method = "POST" And Request.Post["token"] = "ok" Then For Each sField In aRequestFields Select sField Case "material" cData.Add("on", "material") Case "confirmation_gdpr" cData.Add("on", "confirmation_gdpr") Case "message" If Request.Post[sField] = "" Then cData.Add("empty", "message") Else cData.Add(Request.Post[sField], sField) Endif Default cData.Add(Request.Post[sField], sField) End Select Next
Damit besitzt jedes Feld einen Wert. So können Sie sich zur Kontrolle alle 9 Schlüssel-Wert-Paare der Collection `cData` anzeigen lassen:
For Each vValue In cData Print cData.Key & " " & String.Chr(187) & " " & Html(vValue) & "<br>" Next
Ausgabe in der IDE-Konsole:
material » off confirmation_gdpr » off token » ok firstname » Klaus lastname » Mayer birthday » 1999-11-03 email » klaus.mayer.99@web.de os_version » mint message » empty
Für Felder vom Typ 'radio' wird folgender Weg vorgeschlagen: Da Radio-Button eine Gruppe von beschrifteten Button sind, von denen der Anwender genau einen auswählen kann, wird eine bestimmte Auswahl über das checked-Attribut mit checked=„checked“ vorselektiert. Damit wird das Feld 'os_version' stets im String-Array Request.Post.Fields vorhanden sein:
<fieldset> <legend>Welche Linux-Distribution nutzen Sie aktuell?</legend> <div class="radiobox"> <input type="radio" id="ubuntu" name="os_version" value="ubuntu"> <label>Ubuntu</label> </div> <div class="radiobox"> <input type="radio" id="mint" name="os_version" value="mint" checked="checked"> <label>Mint</label> </div> <div class="radiobox"> <input type="radio" id="another" name="os_version" value="another"> <label>Eine andere Distribution</label> </div> </fieldset>
Diese vorgegebene Auswahl kann der Anwender allerdings jederzeit ändern.
Um sicherzustellen, dass alle als verpflichtend ausgewiesenen Felder auch tatsächlich mit einem Wert ausgefüllt wurden, gibt es zwei Strategien. Eine prüft erst nach dem Absenden des Formulars, ob zu dem Feld auch ein Wert existiert und legt dann dem Nutzer das teilweise ausgefüllte Formular so lange mit einem passenden Kommentar vor, bis alle Werte vorliegen. Die andere besteht darin, ausgewählte Formular-Attribute zu verwenden. Pflichtfelder erhalten das required-Attribut:
<input type="text" id="firstname" name="firstname" required autofocus>
Solange die Eingaben nicht valide sind, wird ein Absenden des Formulars verhindert und eine Meldung ausgegeben wie „Bitte füllen Sie dieses Feld aus“.
Zusätzlich können Sie für ausgewählte Felder wie (Text-)Felder die Attribute 'pattern' und 'title' verwenden, wobei für das Attribut 'pattern' in den folgenden zwei Beispielen reguläre Ausdrücke verwendet werden:
pattern="^[A-Za-z]+$" title="Nur Buchstaben sind gültige Zeichen!"
oder bei einem Eingabefeld für eine EMail-Adresse:
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" title="Muster: localpart@domain.tld"
Der Text des Titels erscheint als Tool-Tipp, wenn Sie mit der Maus einen Augenblick über dem Feld bleiben.
Der Funktionsplotter ist eine Adaption des JS-Plotterbeispiels auf der Webseite https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/Funktionsplotter. Angegeben wird der komplette Quelltext für die Erzeugung der Graphen von drei (unterschiedlichen) Funktionen, die Sie frei definieren können oder aus der Liste der vordefinierten Funktionen auswählen:
[1] <!-- Functionality of the plotter --> [2] <script src="./js/pl.cs.js" charset="utf-8"></script> [3] <script src="./js/pl.plot.js" charset="utf-8"></script> [4] <script src="./js/pl.plotter.js" charset="utf-8"></script> [5] [6] <h1>Funktionsplotter</h1> [7] [8] <figure id="plotarea"></figure> [9] <div hidden id="wertetabelle" aria-live="polite"></div> [10] [11] <fieldset id="plotter"> [12] <div aria-live="polite"> [13] <label id="f1">f<sub>1</sub>(x) = <input type="text" id="fkt1" value="sin(x)/x"></label> [14] <label id="f2">f<sub>2</sub>(x) = <input type="text" id="fkt2" value="sin(x)"></label> [15] <label id="f3">f<sub>3</sub>(x) = <input type="text" id="fkt3" value="cos(x)"></label> [16] </div> [17] <div> [18] <label style="padding-left: 1rem">x<sub>min</sub> = <input type="number" step="any" id="idxmin" value="-6.8"></label> [19] <label style="padding-left: 2rem">x<sub>max</sub> = <input type="number" step="any" id="idxmax" value="7.8"></label> [20] <button style="padding-left: 1rem" id="plotbutton">Funktionsschar zeichnen</button> [21] </div> [22] </fieldset> [23] [24] <p id="vdeffkt">Vordefinierte Funktionen:<br> [25] <button>AM</button>, [26] <button>PM</button>, [27] <button>sin(x)/x</button>, [28] <button>sinh</button>, [29] <button>cosh</button>, [30] <button>tanh</button> und [31] <button>Puls</button>. [32] </p> [33] [34] <p id="jsfkt">Javascript unterstützt die folgenden Funktionen:<br> [35] <button>abs</button>, [36] <button>acos</button>, [37] <button>asin</button>, [38] <button>atan</button>, [39] <button>cos</button>, [40] <button>exp</button>, [41] <button>log</button>, [42] <button>pow</button>, [43] <button>sin</button>, [44] <button>sqrt</button> und [45] <button>tan</button>. [46] </p> [47] <p>Bitte den Definitionsbereich der Funktionen beachten!</p> [48] <hr> [49] <p style="font-size: 0.9rem; color: gray;">Der Funktionsplotter ist eine Adaption des JS-Plotterbeispiels auf der Webseite https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/Funktionsplotter</p>
Die komplette Funktionalität des Plotters steckt in drei JavaScript-Skripten. Den Style der Funktionsbilder können geändert werden, wenn Sie die entsprechenden JavaScript-Skripte verändern.
Abbildung 24.6.2.4.8: Funktionsbilder in einem besonderen Style
Die Webseiten des Projektes 4 wurden beim Autor auf seinem Arbeitsplatz-Computer entwickelt. Auf diesem wurde auch der Webserver Lighttpd installiert und konfiguriert. Da die Webseiten auch im Intranet aufgerufen werden sollen, wurde nach einer Möglichkeit gesucht, die ausführbare Gambas-Datei index.gambas als Webserver-Programm sowie die benötigten Ressourcen-Dateien aus dem Projekt-Ordner `webapp4` in den Web-Ordner '/usr/lib/cgi-bin/webapp3' auf dem Arbeitsplatz-Computer zu kopieren:
hans@pc:~/GB3BUCH/24K_NetzwerkN/24.6.2.4_WP4/BuchProjekt/webapp4$ . ├── index.gambas ├── .public │ ├── audiovideo │ ├── css │ ├── db │ ├── favicon │ ├── icons │ ├── images │ └── js ... hans@pc:/usr/lib/cgi-bin/webapp4$ . ├── index.gambas ├── audiovideo ├── css ├── favicon ├── icons ├── images ├── js └── .public └── db
Sie können die erforderlichen Ordner und Dateien mit erhöhten Rechten im Dateimanager kopieren oder nutzen das folgende Bash-Skript:
#!/bin/bash # # -- Definition of colour values in the terminal #-------------------------------------------------------------------------------------- RE="\033[0;31m" # red GR="\033[0;32m" # green BL="\033[0;34m" # blue REB="\033[1;31m" # red bold GRB="\033[1;32m" # green bold BLB="\033[1;34m" # blue bold FGB="\033[1m\033[42m\033[37m" # bold + withe + green background NO="\033[0m" # normal #-------------------------------------------------------------------------------------- if [ -z "$1" ]; then echo "ERROR! The parameter string is an empty string." exit 99 else pass=$1 fi echo webserver="lighttpd" echo "WEBSERVER = ${webserver}" target_basic_path="/usr/lib/cgi-bin" echo "TARGET-BASIC-PATH = ${target_basic_path}" pwd="${PWD##*/}" echo "PWD = ${pwd}" target_site_path=${target_basic_path}/${pwd} echo "TARGET-SITE-PATH = ${target_site_path}" #IP address of the local (web) server ipaddress="192.168.0.4" echo "IP-ADDRESS = ${ipaddress}" source_path=$(pwd) echo "SOURCE-PATH = ${source_path}" output=$(ping -c 1 ${ipaddress}) substring="min/avg/max/mdev" if [[ ${output} =~ ${substring} ]]; then echo echo -e "${BLB}» The web server on the intranet with the IP address '${ipaddress}' can be reached.${NO}" # echo else echo echo -e "${REB}» ERROR\n» The web server in the intranet with IP '${ipaddress}' is not accessible!${NO}" echo exit 99 fi #-------------------------------------------------------------------------------------- echo ${pass} | sudo -S mkdir ${target_site_path} 2>/dev/null echo ${pass} | sudo -S chmod 777 ${target_site_path} echo -e "${BLB}» The directories and files are copied ...${NO}" echo echo ${pass} | sudo -S cp ${source_path}/index.gambas ${target_site_path} cd ${source_path}/.public/audiovideo find . -print | cpio -pdmu ${target_site_path}/audiovideo cd ${source_path}/.public/css find . -print | cpio -pdmu ${target_site_path}/css cd ${source_path}/.public/favicon find . -print | cpio -pdmu ${target_site_path}/favicon cd ${source_path}/.public/icons find . -print | cpio -pdmu ${target_site_path}/icons cd ${source_path}/.public/images find . -print | cpio -pdmu ${target_site_path}/images cd ${source_path}/.public/js find . -print | cpio -pdmu ${target_site_path}/js cd ${source_path}/.public/db find . -print | cpio -pdmu ${target_site_path}/.public/db echo ${pass} | sudo -S chmod 755 ${target_site_path} #-------------------------------------------------------------------------------------- echo echo -e "${REB}Continue with <ENTER>${NO}" read e
Der Aufruf des Bash-Skriptes beim Autor erfolgt im Projektordner in einer Konsole:
hans@pc-a-mint20:~/GB3BUCH/24K_NetzwerkN/24.6.2.4_WP4/BuchProjekt/webapp4$ ./cpwp2server.sh <user.passwort> WEBSERVER = lighttpd TARGET-BASIC-PATH = /usr/lib/cgi-bin PWD = webapp4 TARGET-SITE-PATH = /usr/lib/cgi-bin/webapp4 IP-ADDRESS = 192.168.0.4 SOURCE-PATH = /home/hans/GB3BUCH/24K_NetzwerkN/24.6.2.4_WP4/BuchProjekt/webapp4 » The web server on the intranet with the IP address '192.168.0.4' can be reached. » The directories and files are copied ... 27373 Blöcke 19 Blöcke 11 Blöcke 87 Blöcke 2268 Blöcke 203 Blöcke 44 Blöcke Continue with <ENTER> hans@pc-a-mint20:~/GB3BUCH/24K_NetzwerkN/24.6.2.4_WP4/BuchProjekt/webapp4$
Danach können Sie die Webseiten im Intranet vom Webserver abrufen und in Ihrem Webbrowser anzeigen:
http://192.168.0.4/cgi-bin/webapp4/index.gambas