TurboGears wird seit 2005 von der Firma Zesty News unter der Leitung von Kevin Dangoor programmiert. Der gesamte Quellcode des Projekts steht offen zur Verfügung und kann, genau wie das Produkt selber, frei verwendet werden. Die grundlegenden Konzepte, wie man in den späteren Absätzen erkennen kann, orientieren sich teilweise stark an Ruby on Rails, TurboGears kann aber nicht als direkter Clone bezeichnet werden, da die Komponenten, aus denen es zusammengesetzt ist, teilweise länger bestehen als Rails.
Aus wirtschaftlichen Gründen hat man sich dazu entschieden, kein komplett neues Web-Framework aufzusetzen, sondern lediglich bereits bestehende Komponenten (nicht-full-stack Frameworks) zu einem großen (full-stack Framework) zusammenzufassen. Dies ist jedoch nicht nur aus wirtschaftlicher Sicht sinnvoll, sondern auch aus der der Entwicklung: Komplexe Komponenten müssen nicht von Grund auf neu erstellt und getestet werden, viel mehr verlässt man sich auf schon länger bestehende und etablierte Teilkomponenten. Diese sind besonders gut für ihre spezifische Aufgabe ausgerichtet, könne mit relativ geringem Aufwand ausgetauscht werden und müssen nur noch verbunden werden.
TurboGears ist aus den folgenden vier grundlegenden nicht-full-stack Framweworks aufgebaut:
SQLObject ist die Model-Komponente von TurboGears, dient also der Haltung der im System vorhandenen Daten. Da Python eine objekt-orientierte Sprache ist, bietet es sich an, die anfallenden Daten auch als Objekte zu hinterlegen. Deshalb fungiert SQLObject als ein so genannter "object relational mapper", oder kurz: ORM. Dieser kann aus Python-Objekten die entsprechenden Datenbank-Tabellen generieren.
SQLObject unterstütz zur Zeit eine große Menge an verschiedenen SQL-Datenbanken und wird ständig um neue Erweitert. Für den Anwender von SQLObject macht es keinen Unterschied, auf welcher hersteller-spezifischen Datenbank gearbeitet wird, da alle Zugriffe intern in die entsprechende Anfrage umgewandelt werden. Weiter muss der Benutzer keine SQL-Anfragen schreiben, dies geschieht implizit über den Zugriff auf hinterlegte Objekte. Um die Auslastung der Datenbank nicht zu hoch zu treiben, können Anfragen automtisch gecached werden.
Wie aus einer Python-Klasse eine Datenbank generiert wird, ist im folgenden Codeabschnitt demonstiert:
In den Zeilen wird das SQLObject-Modul importiert, in Zeile zwei ein Modul zur Zeitverarbeitung. In Zeile vier wird dann eine Klasse "Person" deklariert, welche von der Basis-Klasse "SQLObject" abgeleitet wird. Die Basis-Klass stellt entsprechende Methoden zum Umgang mit der angebundenen Datenbank bereit.
In den folgenden vier Anweisungen werden die Attribute der Klasse festgelegt. Links vom Gleichheitszeichen steht der Name des zu erzeugenden Attributs, auf der rechten Seite wird diesem dann ein Wert zugewiesen. Der Typ einer Variable, bzw. eines Attributs, wird in Python nicht explizit angegeben, sondern ist implizit durch den belegenden Wert gegeben.
In diesem konkreten Fall werden auf der rechten Seite neue Instanzen der Klassen "StringCol" und "DateTimeCol" instanziiert. Diesen können zusätzlich noch Eigenschaften, wie Länge oder default-Belegung, mit übergeben werden. Der SQL-Typ einer Spalte, in denen die einzelnen Attribute einer Klasse gehalten werden, kann nun aus dem Inhalt der Attribute abgelesen werden. Möchte man einen Fremdschlüssel festlegen, n:1- oder m:n Beziehnungen ausdrücken, so kann dies über die Klassen "ForeignKey" und "RelatetJoin" beschrieben werden.
Im folgenden Code-Block ist zu sehen, welcher SQL-Code aus der obenen gegebenen Klasser erzeugt wird:
Es ist deutlich zu erkennen, dass jedes in der Python-Klasse deklariertes Attribut, zu einer entsprechenden Spalte in der Tabelle umgewandelt wurde. Hinzugekommen ist noch eine die Spalte "id", die als Primärschlüssel verwendet wird. Das beispielhafte Erzeugen einer Tabelle under der Zugriff auf diese sind im folgenden Codeblock kurz angerissen:
Wie in der letzten Zeile des obrigen Beispiels zu sehen, ist es ebenfalls möglich Objekte über einen SQL-Ausdruck anzufordern. Ebenfalls ist eine automatische Klassen-Generierung aus einer Datenbank-Tabelle vorgesehen.
Kid ist ein weiterer Bestandteile von TurboGears und stellt aus Sicht des MVC-Konzepts die View-Komponente dar. Bei Kid handelt es sich um eine so genannte "Template-Engine", die verschiedene Template-Sprachen verarbeiten kann. Templates im Bereich der Web-Frameworks dienen der Trennung von Inhalt und Gestaltung einer Seite, bieten also eine Vorlage wie bestimmte Daten in das Layout integriert werden können. Zu diesem Zweck stehen verschiedene Platzhalter in der Template-Sprache zur Verfügung, die durch Inhalt ersetzt, oder durch gestaltende Logik ausgetauscht werden.
Neben der von Kid bereit gestellten Template-Sprache lassen sich auch andere Sprachen verwenden. Dazu gehören beispielsweise Cheetah, XSLT oder aber auch die Zope Page Templates (ZPT). Um einen Eindruck über die mitgelieferte Sprache zu vermitteln, ist im folgenden Code-Abschnitt eine kurzes Beispiel-Template aufgeführt:
Wie man sieht, wird stets wohlgeformtes XML, bzw. XHTML, in den Templates hinterlegt. Nach der Auswertung ist dies aber nicht mehr gewährleistet, da die Daten aus beliebigen Python-Ausdrücken stammen k�nen. In den python-processing-instructions (ersten vier Zeilen), kann beliebiger Python-Code stehen, welcher zur Auswertungszeit des Templates ausgeführt wird. Hier können komplexere Berechnungen durchgeführt werden, aber auch einfache Variablen-Belegungen.
Weiter ist es möglich, den Inhalt von Elementen, bzw. ein komplettes Element durch das Ergebnis eines Python-Ausdrucks zu ersetzen.
Dies wird durch die Attribute py:content, bzw. py:relplace symbolisiert.
Die wichtigsten Attribute, hier ohne vorgestellten Namensraum, werden in der folgenden Tabelle kurz beschrieben:
content | Ersetzen des Inhalts des Elements durch den angegebenen Ausdruck |
replace | Ersetzen des gesamten Elements durch den angegebenen Ausdruck |
if | Prüft, ob der angegebene Ausdruck wahr ist und wertet nur dann die enthaltenen Elemente aus |
attrs | Wert eines Attributs setzen |
for | Über eine, durch den angegebenen Ausdruck zurückgegebene, Liste laufen |
def | Definieren einer Template-Funktion, die mehrmals aufgerufen werden kann. Dies ist dann sinnvoll, wenn ein Objekt beispielsweise mehrfach ausgegeben werden soll (bspw. ein Eintag in einem Gästebuch) |
Neben dem oben genannten Beispiel mit Verwendung eines Namespaces, ist dieses auch ohne diesen möglich:
Aus Sicht des MVC-Konzeptes handelt es sich bei CherryPy um die Controler-Komponente von Turbo-Gears. Die Aufgabe besteht also im Wesentlichen darin, Anfragen vom Client, bzw. von einem Server, anzunehmen und diese durch entsprechende Kombination von Daten(Modellen) und Templates(Views) zu beantworten. Neben diesen beiden Aspekten ermöglicht es, einen eigenen Web-Server aufzusetzen, oder aber auch die Integrationen in einen bereits bestehenden, durch beispielsweise CGI, mod_python oder eine WSGI kompatible Schnittstelle.
Um die folgenden Beispiel zu verstehen, sei noch der wichtige Punkt erwähnt, das CherryPy die Seiten einer Anwendung als Objekte betrachtet. Diese bieten dann die entsprechenden Methoden zum Rendern des HTMLs aus dem Templates und ermöglichen eine beliebige Verschachtelung.
Beispiel: URL-Mapping mit CherryPy
Gegeben sei die URL www.spam.de/eggs/foo/bar?id=42
Diese wird von CherryPy in die folgenden drei Komponenten zerlegt:
Wie eine konkrete Seite aufgebaut wird, kann dem folgenden Code-Beispiel entnommen werden:
Im letzten Teil des Beispiels werden dann Instanzen der einzelnen Seiten erzeugt und in einander verschachtelt. Dies ist auf beliebig komplexe Weise möglich. Im letzten Statement wird noch der Web-Server gestartet, so dass von außen auf die Seiten zugegriffen werden kann.
MochiKit läßt sich nich direkt in das MVC-Konzeptes einordnen, da es nur auf der Client-Seite agiert. Basis für dieses Framework sind Ajax (Asynchronous JavaScript and XML) und JSON. Bei JSON handelt es sich um ein Datenaustauschformat ähnlich zu XML, ist aber wesentlich kompakter, auf der anderen Seite jedoch nicht so allgemeingültig.
Betrachtet man MochiKit etwas genauer, so stellt man fest, dass es im Prinzip nur eine umfangreiche Bibliothek von komplexen Funktionen ist. Dazu gehören beispielsweise die Möglichkeit einer einfachen Definition von durch die Maus beweglichen Objekten, Manipulationen am DOM-Baum oder auch visuelle Effekte. Dies geschieht mit wenigen Anweisungen, so dass eine vernünftig gestaltete Tabelle bereits mit einem Aufruf erzeugt werden kann. Da nicht jede Anwendung Dynamik auf der Seite des Clients benötigt, ist die Verwendung von MochiKit optional.
Das folgende Bild verdeutlich die Zusammenhänge der einzelnen Komponenten von TurboGears: