Donnerstag, 9. Juni 2011

Bottle und statischer Inhalt - Verwendung von static_file

Der der Verwendung von in Python geschriebenen WSGI-basieren Webapplikationen kommt es immer wieder zu Verwirrungen, wenn dynamisch generierter Inhalt mit statischem (wie Bilder, CSS-Dateien) gemischt werden soll.

Dies oft dadurch bedingt, dass man beim Programmieren noch das "klassische" HTML und die zugrunde liegende Datei- / Verzeichnisstruktur im Kopf hat. Nur: WSGI-Applikation können im Server grundsätzlich an einen beliebigen Pfad ("Route") gebunden werden, der vom Speicherort der Datei(en) auf der Festplatte unabhängig ist.

Um nun statischen Content auszuliefern gibt es zwei Möglichkeiten: entweder man holt diesen von einer anderen URL, die außerhalb der Routen der Applikation liegen oder - geschickter - man definiert eine Route, welche für das Ausliefern zuständig ist.

Verwendet man das Bottle Microframework so kann eine Lösung wie folgt aussehen:

Applikation, "test_static.py":
#!/usr/bin/python
# -*- coding: utf-8 -*-

from bottle import route, static_file, template, run, debug

@route('/test')
def test():
return template('test.tpl')

@route('/test/static/:filename')
def static(filename):
rootpath = '/home/jochen/code/bottle_test/static/'
return static_file(filename,root=rootpath)

if __name__ == "__main__":
debug(True)
run(reloader=True)


Das Template "test.tpl" sieht so aus:
<html>
<head>
<title>Bottle test</title>
<link rel="stylesheet" type="text/css" href="/test/static/format.css">
</head>
<body>
<h1>Hallo Welt</h1>
<p>Wie geht's</p>
<p class="kursiv">Ich hoffe gut!</p>
</p>
</body>
</html>


Und die CSS-Datei "format.css" so:
.kursiv {font-style: italic; color: red; }


So weit, so gut. Prinzipiell sollte sich das Beispiel auch auf andere Framework übertragen lassen.

Zwei Dinge sind dabei essentiell wichtig: Erstens, dass bei der Option "root" von "static_file" der absolute Pfad zu den statischen Dateien im Dateisystem angegeben wird. Zweitens, dass in der Template-Datei die korrekte Route bezogen auf die Applikation angegeben wird. Dann sollte die Applikation auch statische Inhalte problemlos ausliefern können.

Hinweis: getestet mit Python 2.6. und Bottle 0.8.

Keine Kommentare:

Kommentar veröffentlichen