ratatwisker(.py)
das (mod_)Python-Web-Application-Framework, mit dem diese Site erstellt wurde
Motivation
2006 begann ich ein Framework mit ähnlicher Struktur in PHP zu erstellen
und kam während der Arbeiten zu dem Schluß, daß PHP sehr ineffizient ist.
(Wenn ich mal viel Zeit habe, schreibe darüber einen Artikel)
Für die Web-Auftritte, die ich neben meiner Arbeit erstelle, benötige ich ein
Framework, das mir einen Großteil der Routinearbeiten abnimmt. Ich habe
einfach nicht die Zeit, immer die gleichen SQL-Queries zu schreiben, um dann
die Daten in Arrays zu kopieren oder aus ihnen, in immer den gleichen
Arbeitsschritten, Objekte zu erzeugen.
Mir fehlt die Geduld, mich durch hunderte Zeilen lange switch/case
if/elseif-Dschungel zu kämpfen. Oder unendlichen include/require_once-Orgien
hinterherzuhecheln.
Ich möchte Lösungen für Aufgaben erstellen.
oder warum ist ratatwisker(.py) das 42. Web-Applications-Framework:
Bevor ich mit den Arbeiten an ratatwisker(.py) begann, habe ich mir die
Platzhirsche angeschaut. Jeder der Hirsch hat seine Stärken,
TurboGears,
Zope,
Ruby on Rails,
Django,
TYPO3
oder
Joomla.
Interessant ist auch
dieser Artikel.
Ja, ich werfe hier Frameworks und CMSe in einen Topf, weil für mich nur
interessant ist, wie groß der Aufwand ist, um zum Ergebnis zu kommen.
Daneben habe ich mir die Systeme, mit denen in meiner beruflichen Praxis
Web-Anwendungen erstellt werden und wurden, angeschaut.
- Keine der in ratatwisker(.py) verwendeten Ideen ist neu
- keine der verwendeten Techniken ist neu
- andere Frameworks erledigen mehr Arbeit automatisch
Neben dieser Vereinfachung der Arbeit ist es mir genauso wichtig, daß das System so flexibel und klar strukturiert ist, daß sich mit ihm auch "Sonder"-Anfertigungen, mit möglichst geringem Aufwand erstellen lassen.
Daß Änderungen an bestehenden Auftritten nicht in Katastrophen enden, ist ein angenehmer Nebeneffekt.
und welche Konzepte machen es zum "idealen" Web-Application-Framework
Konfiguration statt Programmieren
Super, gleich der erste Punkt stiftet Verwirrung!Wenn ich http://de.wikipedia.org/wiki/Ruby_On_Rails lese, dann macht ratatwisker(.py) genau das Gegenteil von "Konfiguration statt Programmieren".
Was dieser Punkt sagen soll, ist: ratatwisker(.py) bietet viele Funktionen, die ich nicht immer neu programmieren muß. Ich kann sie nutzen oder nicht, und entscheide dies über eine Konfiguration.
Über Selbstverständlichkeiten, wie daß man über den Namen des Controllers auf den Namen des Datenmodels schließen kann, habe ich nie nachgedacht. Das ist halt einfach so. ;-)
URL-Mapping
Zwei definierbare Teile des Pfades der URL bestimmen, welche Methode in welcher Klasse / Controller aufgerufen wird.Die restlichen Teile des Pfades werden zu Parametern des Requests gemapt.
Parameterdefinition
In der Konfiguration können alle Parameter definiert und mit Standardwerten versehen werden, so daß Abfragen auf das Vorhandensein eines Parameters nicht notwendig sind und von definierten default-Werten ausgegangen werden kann.Objekt-Relationales Mapping
Um die immer wiederkehrenden SQL-Querys, das immer gleiche Erzeugen von Arrays oder Objekten und den Paradigmenwechsel zu vermeiden.siehe auch ...
MVC-Pattern
Trenne die Aufgabe in ihre Teile auf und vermeide die Ballung von Komplexität.siehe auch ...
Vermeidung von nicht zur Lösung führender Komplexität
ratatwisker(.py) nutzt eine Template-Engine, einen OR-Mapper und einen Web-Server und benötigt in dessen Konfiguration 5 Zeilen.Erfinde das Rad nicht immer wieder neu
und nutze gute und erprobte Tools.Welche Tools nutzt ratatwisker(.py)
- als Objekt-Relationalen-Mapper: SQLObject
- als Template-Engine: Cheetah
- als Programmiersprache: Python
- als Apache-Integration: mod_python
- als Aufwandsvermeidung: den Thomas seine Faulheit
ratatwisker(.py), siteObject, siteData. Die Strukturen des Systems
ratatwisker(.py)
- steuert, zusammen mit dem mod_python-Handler die Abarbeitung des Requests
- mapt den Pfad der URL auf (site)Objekte und Methoden in den (site)Objekten.
- stellt die Anbindung zur Template-Engine her
- liefert einige Komfort-Funktionen
- parst die Templates
siteObject
siteObject stellt, in Zusammenarbeit mit siteData, die Grundfunktionalitäten für eine Administrationsoberfläche zur Verfügung:
- Listendarstellung aller Einträge eines siteObjects (Datensätze)
- Neu erstellen,
- editieren
- und löschen von Einträgen
siteData
siteData benutzt als Basis die ColClasses von SQLObject und stellt Daten-Spalten-Objekte der verschiedenen benötgten Datenarten zur Verfügung, z.B.
- Strings
- Email-Adressen
- Integer- und Float-Zahken
- Zeit- und Datum
- Datei (Uploads)
- Single- und Multiple-Joins auf andere siteData-Objects
- . . .
Auch hier: Standardaufgaben sind entweder ohne oder mit ganz wenigen Zeilen Programmcode erstellt.
Als Beispiel
der Programmcode, der für eine Newsletter-Anmeldung mit Double-Optin notwendig ist:
TODO: aktuelle Umsetzung veröffentlichen ...
Die siteData-Klasse
Hier werden nur die Datenfelder eines Newsletter-Abonnementen definiert.
# coding=utf-8
from sqlobject import *
import sys, os
from datetime import datetime
from time import *
from siteData import *
from siteObject import *
class newsletterUserSiteData(siteData):
anrede = sdfString (defVal = '', defLen=10)
vorname = sdfString (defVal = '', defLen=255)
name = sdfString (defVal = '', defLen=255)
email = sdfEmail (defLen=255, required = True)
ipAnmeldung = sdfString (defVal = '', defLen=20)
datumAnmeldung = sdfInteger()
doubleOptIn = sdfInteger(defVal = 0)
datumDoubleOptIn = sdfInteger()
ipDoubleoptIn = sdfString (defLen = 20)
Die siteObject-Klasse
Die Methode signUp stellt das Anmeldeformular dar
self.objRatat.assignToView ( 'contentInclude', self.objRatat.tpl ( False, 'newsletterUser', 'cont_', signUpFormName))prüft die User-Eingaben
dictError = self.callSiteDataClassMethod('validateInputData', arg)
und schreibt den neuen Abonnementen in die Datenbank
siteDataNewsletterUser = self.newSiteDateInstance() ... siteDataNewsletterUser.setDataFromArg(argNew) siteDataNewsletterUser.sync()