Heimwerken für Anfänger
Was braucht man alles um so eine Wandlampe anzubauen? Schauen wir uns das Bild genau an:
- Eine Wasserwaage. Ganz klar. Soll ja alles schön gerade werden.
- Ein Hammer. Zum Dübel-Einklobben. Auch wenns in dieser Gipsbetonwand garnicht nötig war, aber ich hab ihn ja und er will genutzt werden.
- Ein Akkubohrer. Sehr wichtig um die 2 (zwei) kleinen Schrauben anzuziehen.
- Ein Bier. Weil zu gerade solls ja auch nicht werden.

Putbusser Park
Nachdem es in den letzten Wochen hier mir doch zu programmier-lastig wurde, ein paar Bilder von "nebenan":
Lightbox für alle (Django Template-Filter)
Seit Jahr und Tag verwende ich das bekannte Lightbox um die Großversion von Vorschaubildern anzuzeigen. Dazu muss lediglich das Attribut rel="lightbox an den Link gesetzt werden. Leider war ich nicht ganz so konsequent in der Nutzung so das einige Bilder in Blogbeiträgen Lightbox unterstützen, bei anderen habe ich es vergessen.
Diesem Umstand habe ich nun mit einem kleinen Template-Filter nachgeholfen:
1 2 3 4 5 6 7 8 9 | import re from django.utils.encoding import smart_unicode r_lightbox = re.compile('<a (?=[^>]*\.(jpg|gif|png))(?![^>]*lightbox)') s_lightbox = '<a rel="lightbox" ' @register.filter def lightbox(content): return r_lightbox.sub(s_lightbox, smart_unicode(content)) |
Der Aufruf in meinem Template schaut dann so aus:
1 | {{ Entry.body_text|markdown|lightbox }} |
Der Filter erkennt, ob ein Link auf eine .jpg, .gif oder .png Datei leitet und fügt – wenn nicht schon vorhanden – das rel="lightbox" Attribut hinzu. Ein kleiner Bug steckt noch drin, so würde z.B. ein Link zu http://www.jpgmag.com/ auch als Bild gewertet werden (da .jpg im String vorkommt), aber damit kann ich leben. ![]()
Woher das Wetter von meiner Seite stammt
Vielleicht ist jemanden schon die Wetterinfo meines Heimatortes oben rechts auf jeder Seite aufgefallen. Im folgenden zeige ich euch, wie ich euch, wie ich diese Daten abfrage und in meinem Django-App speichere.
Der eine oder andere wird sich sicher fragen: "Was interessiert mich das Wetter irgendeines beknackten Dorfes am Rande Deutschlands?" aber das ist hier nun mal meine Homepage und hier bestimme ich.
Die hier vorgestellte Applikation lässt aber beliebig viele Wetterstationen abfragen so dass man theoretisch ein zweites wetter.com|de bauen könnte.
Wetterdienstdaten sind – wenn es nicht irgendeine Flashbox halb gefüllt mit Werbung ist – in der Regel nicht kostenlos, weather.com macht eine Ausnahme und stellt seine Daten über eine REST-Schnittstelle frei zur Verfügung. Einzige Gegenleistung: Ein Link zur Homepage sowie das Logo muss angezeigt werden.
Was man bei Eingabe-Prüfung falsch machen kann (u.a. SQL-Injection)
Ein kurzer Ausflug in die PHP-Programmierung brachte mich heute auf einen Fehler, der mir hoffentlich früher auch nicht unentdeckt blieb. Aufgabe war es, die Einträge des Gästebuchs eines Kunden auf verschiedene Seiten auszugeben – je nach Anzahl der Einträge pro Seite. Der englische Fachausdruck dafür ist Pagination.
Die Seitenzahl (bzw. das daraus errechnete Offset) wird über eine GET-Variable 'page' übergeben. Funktionierte alles wunderbar und schlußendlich wollte ich noch eine zusätzliche Prüfung auf schadhaften Code (SQL-Injection etc.) einbauen. Dieser Code soll prüfen, ob sich in $_GET['page'] auch wirklich nur Ziffern finden.
1 2 3 4 | <?php if(isset($_GET['page']) && !preg_match("/[0-9]+/", $_GET['page'])) die("Die Seitenzahl darf nur aus Ziffern bestehen."); ?> |
Das funktioniert prinzipiell auch wie es sollte, bis ich einige Real-Life-Tests durchführte. Zwar stirbt das Script bei Werten wie '?page=ABC' wie gewünscht ab, sobald sich aber irgendwo eine Ziffer befindet – '?page=AB123' – nicht.
Der Fehler liegt im Detail, der richtige Ausdruck lautet nicht "/[0-9]+/" sondern "/^[0-9]+$/". Das Dach- und Dollar-Symbol stellt sicher, dass sich von Anfang bis Ende auch wirklich nur Ziffern befinden dürfen.
So funktioniert alles wie es sein soll und es gilt wieder einmal: Traue keiner Variable, die du nicht selbst definierst. Darüber hinaus dürfen die Funktionen addslashes, is_numeric respektive is_int und mysql_escape_string nicht unerwähnt bleiben.
