Aus statisch mach dynamisch
Der folgende Abschnitt hat das Ziel, den Mehrwert dynamischer Webseiten herauszusarbeiten. Im vorangegangenen Beispiel wurde schon deutlich, dass übermittelte Parameter den "Bau" der Website, die an den Browser ausgeliefert wird, beeinflussen können.
Im folgenden Abschnitt werden wir die Ausgangsseite "Secondhandblumen Petersen" zu einer dynamischen Website umbauen.
Vorbereitung
Projektstruktur auf dem RPI anlegen
Wir werden zunächst eine neue Struktur für diesen Arbeitsschritt auf dem Raspberry vorbereiten.
/home/pi/www/secondhandblumen_flask/
├── app.py
└── templates/
Die Datei app.py
kann mit touch app.py
angelegt werden, der Ordner mit mkdir templates
. Er dient dazu, die HTML-"Bauteile" aufzunehmen, aus denen wir im Folgenden dynamisch unsere Website zusammenbauen.
Statische HTML-Dokumente auf den RPI kopieren
Zunächst brauchen wir die HTML-Dokumente aus dem GitLab-Repository https://xldrkp@collaborating.tuhh.de/itbh/secondhandblumen.git. Sie können direkt mit git clone
in den Ordner templates
gezogen werden.
pi@raspberrypi:~/www/secondhandblumen_flask/templates $ cd
pi@raspberrypi:~ $ cd www/secondhandblumen_flask/templates/
pi@raspberrypi:~/www/secondhandblumen_flask/templates $ git clone https://xldrkp@collaborating.tuhh.de/itbh/secondhandblumen.git .
Wichtig ist der Punkt am Ende, denn er sagt, dass die Dateien direkt in dem Verzeichnis abgelegt werden, in dem wir uns befinden.
Die Datei app.py
aufbauen
Bei Flask heißt der Vorgang, HTML-Seiten dynamisch zusammen zu bauen rendern. Daher importieren wir am Anfang unserer Hauptdatei auch ein neues Modul.
#!/usr/bin/env python3
from flask import Flask
from flask import request, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/angebot')
def angebot():
return render_template('angebot.html')
@app.route('/team')
def team():
return render_template('team.html')
if __name__ =='__main__':
app.run(host="0.0.0.0", debug=True)
In der zweiten Zeile kommt render_template
dazu. Es erlaubt uns, mit return
eine Datei zurückzugeben, die das HTML enthält. So können wir HTML und Programmcode sauber voneinander trennen.
Zwischenstand checken
An dieser Stelle starten wir mal den Server, um uns das bisherige Ergebnis im Browser anzusehen.
pi@raspberrypi:~/www/secondhandblumen_flask $ python3 app.py
Ein Aufruf der Seite im Browser mit http://[IP-Adresse des Pi]:5000/ zeigt folgende Ansicht
Woran liegt's?
Offensichtlich kann unsere derzeitige Anwendung noch nicht das CSS sowie die Bilder anzeigen. Gehen wir der Sache auf den Grund.
Ein Blick in die Entwicklertools von Chromium zeigen, dass die Dateien style.css
und das Bild aus img/
nicht geladen werden können: Der Server findet sie dort nicht.
Das Problem ist erklärbar, wenn man weiß, dass man für Flask statische Dateien woanders ablegen muss.
Statische Dateien für Flask verfügbar machen
Dem Dateibaum unseres Projekts fügen wir noch den Ordner static
hinzu und darin zwei weitere Ordner css
und img
.
pi@raspberrypi:~/www/secondhandblumen_flask $ tree
.
├── app.py
├── static
│ ├── css
│ └── img
└── templates
├── angebot.html
├── img
│ ├── background_.jpg
│ ├── man.jpg
│ ├── photocredits.txt
│ ├── stormtrooper.jpg
│ └── withered_flowers.jpg
├── impressum.html
├── index.html
├── kontakt.html
├── LICENSE
├── style.css
└── team.html
5 directories, 13 files
Nun verschieben wir die entsprechenden Dateien aus templates
an die richtigen Stellen.
CSS-Datei verschieben
pi@raspberrypi:~/www/secondhandblumen_flask $ mv templates/style.css static/css/
Bilder verschieben
pi@raspberrypi:~/www/secondhandblumen_flask $ mv templates/img/* static/img/
Anschließend sieht unser Dateibaum wie folgt aus:
pi@raspberrypi:~/www/secondhandblumen_flask $ tree
.
├── app.py
├── static
│ ├── css
│ │ └── style.css
│ └── img
│ ├── background_.jpg
│ ├── man.jpg
│ ├── photocredits.txt
│ ├── stormtrooper.jpg
│ └── withered_flowers.jpg
└── templates
├── angebot.html
├── img
├── impressum.html
├── index.html
├── kontakt.html
├── LICENSE
└── team.html
5 directories, 13 files
Pfadangaben für CSS und Bilder anpassen
Flask weiß, wo sich die statischen Dateien befinden. In den HTML-Dateien ist dies aber noch nicht bekannt. Daher nehmen wir jetzt zwei Änderungen vor.
<!doctype html>
<html lang="de">
<head>
<title>Home | Secondhandblumen Petersen in Hamburg</title>
<meta charset="UTF-8"/>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}"/>
</head>
<body>
<h1><a href="index.html">Secondhandblumen Petersen</a></h1>
<div id="wrapper">
<div id="container">
<div id="navcontainer">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="angebot.html">Angebot</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
</ul>
</div>
<h2>Herzlich Willkommen!</h2>
<img class="align-left" src="{{ url_for('static', filename='img/withered_flowers.jpg') }}" alt="As Beauty Withers by bogenfreund@flickr.com"
title="As Beauty Withers by bogenfreund@flickr.com"/>
In der Zeile, die das CSS einbindet, wird der Pfad auf eine neue und besondere Art angegeben.
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}"/>
Die beiden geschweiften Klammern {{ }}
sind ein Ausgabebefehl. Wir werden später noch sehr viel mehr damit anfangen. An dieser Stelle kontruieren wir einen korrekten Pfad zur CSS-Datei, damit diese auch gefunden wird.
Das gleiche tun wir für das Bild in der Datei index.html
.
<img class="align-left" src="{{ url_for('static', filename='img/withered_flowers.jpg') }}" alt="As Beauty Withers by bogenfreund@flickr.com"
title="As Beauty Withers by bogenfreund@flickr.com"/>
Erneut das Ergebnis betrachten
Bei gestartetem Server kann man nun erneut das Ergebnis im Browser betrachten.
Wie geht's weiter?
Das Potenzial unserer doch recht aufwändigen Umbauaktion ist bei Weitem noch nicht ausgeschöpft. Außerdem haben wir noch nicht alle Probleme gelöst.
Was passiert, wenn wir in der jetztigen Website navigieren?
Das funktioniert noch nicht. Was allerdings funktioniert - jedenfalls ein bisschen - ist die manuelle Eingabe der URLs im Browser: http://134.28.125.132:5000/team zeigt die Team-Seite an, aber schon wieder ohne CSS und ohne Bilder.
Was muss man nun machen, damit wenigstens hier dass CSS sowie die Bilder korrekt angezeigt werden?