Im Post “Die Anatomie einer Webseite” erklärte ich die verschiedenen Bestandteile einer Webseite. Damit eine Webseite im Internet erreichbar ist, ist allerdings auch immer ein Webserver notwendig, welcher diese Dateien an anfragende Clients ausliefert. Für diese Aufgabe verwendeten wir die Python-Library “Flask”, die zusätzlich Möglichkeiten bereitstellt, die HTML-Dateien dynamisch aus Jinja-Template-HTML-Dateien zusammenzubauen. Der Ablauf für die Anfrage einer Webseite könnte also beispielsweise so aussehen:

Sequenzdiagramm: Anfrage für eine Webseite

app.py

Werfen wir nun einen Blick auf den Python-Code unserer Webseite:

Mittels der Flask-Library von Python definieren wir hier verschiedene “routen” zu bestimmten URLs. Diese Routen definieren, welche HTML-Datei an den Client geliefert wird, wenn er die passende URL aufruft.

Die erste Route ist also für die Startseite:

Die Route für die Startseite

Für die Startseite wird also die HTML-Datei bzw. das Template “index.html” verwendet. Auf die weiteren Argumente in dem render_template-Aufruf können wir innerhalb der HTML-Dateien mittels Jinja-Syntax im Template später zugreifen. Mit anderen Worten: Wenn wir für die Darstellung dieser URL irgendwelche Daten brauchen, können wir sie hier mit übergeben, beispielsweise werden wir im Template “index.html” Zugriff auf MEASUREMENT_TYPES, ein Dictionary, welches Messwerte mit ihrem Namen auflistet, haben.

Das Dict “MEASUREMENT_TYPES”

Die zweite Route wird für die Darstellung des Graphen der jeweiligen Messwerte verwendet:

Die Route für die Messwerte

Das besondere an dieser Route ist, dass sie gleich für mehrere Einzelseiten, nämlich die Graphendarstellung jedes Messwertes, verwendet wird.

Die Route ist definiert über “/view/<measurement_types>” (Zeile 45). Durch die eckigen Klammern speichern wir den Text nach “/view/” in einer Variable namens measurement_type und können diese im weiteren Code verwenden.

Diese Route würde dann aufgerufen, indem man an die Serveradresse “/view/<measurement_type>” anfügt, wobei <measurement_type> durch einen beliebigen Messtyp ersetzt werden sollte, beispielsweise “/view/wetness” um den Graphen für die Luftfeuchtigkeit zu erhalten.

Bevor der Server nun bei einem Aufruf auf diese URL die aus dem Template “view.html” zusammengesetzte HTML-Datei zurückgibt, wird zunächst ein Aufruf der Datenbank durchgeführt, um die Messwerte des entsprechenden Messwertes abzufragen:

Datenbankanfrage für die Messwerte

Aus dem Ergebnis dieser Anfrage werden dann die Messwerte (“values”) und die dazugehörigen Zeitstempel (“labels”) extrahiert und später beim Aufruf der render_template-Methode zum Zugriff im Template zur Verfügung gestellt, zusammen mit dem Dict “MEASUREMENT_TYPES” (siehe oben) und einem neuen Dict “MEASUREMENT_UNITS”, welches die verwendeten Einheiten der Messwerte enthält, sowie dem Namen des gemessenen Wertes “measurement_type”.

Das Dict “MEASUREMENT_UNITS”

Die HTML-Dateien

Wir haben drei verschiedene HTML-Template-Dateien, angefangen mit “base.html”:

base.html

Neben den üblichen HTML-Tags sieht man hier auch die Jinja-Syntax. Jinja baut uns entsprechend der Syntax die HTML-Datei sozusagen zusammen, bevor sie an den Browser gesendet wird. Würde man also versuchen, diese Datei in einem Browser zu öffnen, wird diese spezielle Syntax im besten Fall als Text und im schlimmsten Fall komplett fehlinterpretiert.

Hier zum Beispiel wird vor der Übergabe an den Client der passende Dateipfad für die .css-Datei ermittelt und eingesetzt:

Das geschieht jedoch erst duch die Interpretation des Jinja-Templates. Ein Browser könnte mit einem solchen Dateipfad nichts anfangen.

Bei Ausdrücken folgender Art:

Block-Ausdrücke

handelt es sich um Blöcke, die weitere HTML-Dateien später definieren können, wodurch sich die Webseite erweitern lässt. Beispielsweise wird “base.html” durch “index.html” erweitert.

Sehen wir uns also “index.html” an:

index.html

Zu Anfang teilen wir Jinja mit, dass wir gerne die base.html erweitern möchten. Konkret bedeutet dies, dass beim Rendern der “index.html” alle Inhalte der “base.html” mit übernommen werden. Zusätzlich werden Blöcke, die wir in “index.html” definieren, die gleichnamigen Blöcke in “base.html” ersetzen.

Die “index.html” dient, wie bereits im vorherigen Abschnitt angemerkt, zur Darstellung der Startseite unserer Webseite. Insbesondere müssen dafür also auch die Buttons der Sidebar angezeigt werden. Anstatt jeden Button einzeln zu definieren, nutzen wir hier die Vorzüge von Jinja und erstellen die Buttons automatisch aus der Liste der Messwerte. Im Code sieht dies folgendermaßen aus:

Aufbau der Sidebar

Dieser Codeausschnitt definiert die komplette Sidebar, ein div-Element mit der Klasse “sidebar”.

Hier benutzen wir eine Jinja-For-Schleife. Dabei gehen wir alle Schlüssel aus dem MEASUREMENT_TYPES-Dictionary durch und erstellen ein Link-Element (<a>) für jeden Eintrag. Zusätzlich fügen wir noch das passende Bild und eine Beschreibung hinzu.

In der letzten HTML-Datei, “view.html” wird der gesamten Darstellung noch der ausgewählte Graph hinzugefügt:

view.html

Hierzu benutzen wir die Javascript-Library “chart.js”. In dem kompletten Javascript-Code wird dann eine Chart-Instanz erstellt, welche das Zeichnen des Graphen für uns übernimmt. Es wird lediglich der 2D-Kontext eines Canvas (damit “malt” chart.js) sowie ein Javascript-Objekt mit den Messwerten und einigen Einstellungen für das Aussehen:

Javascript-Code für chart.js

CSS

CSS steht für “Cascading Style Sheets” und dient der Darstellungsanpassung von Webseiten. Ohne die CSS-Datei sieht unsere Webseite nämlich folgendermaßen aus:

Webseite ohne CSS

Wie man sieht, sind z.B. die Icons viel zu groß. In einer CSS-Datei lassen sich Elemente nach Klasse, ID, Typ etc. mittels sogenannter Selektoren auswählen:

Ausschnitt aus der CSS-Datei

Die Regel mit dem “*” zum Beispiel wählt alle Elemente im Dokument aus. In der Regel wird dann das Padding und Margin auf 0 gesetzt, wobei es sich um Abstandhalter zwischen den Elementen handelt. Die Regel “.mainframe” legt dann für den rechten Bildschirmbereich (in dem der Graph später auftaucht) zum Beispiel die Hintergrundfarbe fest.

Die meisten CSS-Regeln dienen zur Positionierung oder Farbgebung der Elemente. Ich werde mich hier auf die interessanteren Regeln für die Animationen der Buttons konzentrieren:

Hierbei handelt es sich um die Regeln, die das Aussehen der Buttons bei Drüberhalten der Maus ändern, erkennbar an dem “:hover”. Diese Regel wird also angewandt, wenn die Maus über dem passenden Element, hier einem nav-Element innerhalb der sidebar, “schwebt”. In diesem Fall wird das Element ein Stück verschoben: calc(-1 * var(–drawersize)) greift auf die Variable drawersize zu und multipliziert sie mit -1.

Die verschachtelten Selektoren sind hier also folgendermaßen zu verstehen:

Der Selektor “.sidebar .nav .description” wählt alle Beschreibungen aus, die in einem nav-Element in der Sidebar sind.

Der Selektor “.sidebar .nav:hover .description” bestimmt das Aussehen, das die Beschreibung im nav-Element der Sidebar hat, wenn der Mauszeiger darüber (über das nav-Element!) gehalten wird. In diesem Fall wird dann die Hintergrundfarbe auf Weiß geändert.

Tags:

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *