In dem Wissen, dass im Prinzip alles in Zope als Objekt dargestellt wird, ist es relativ leicht, eine einfache Website zu erzeugen. Auch wenn sie nicht direkt im Dateisystem abgelegt werden, kreiert man Ordner, die wiederum Unterordner und andere Objekte enthalten können und so weiter. Mittels DTML-Methoden können leicht verschachtelte Templates erzeugt werden, die neben normalem Text, bzw. HTML- oder XML-Tags DTML-Tags enthalten. So lassen sich zum Beispiel die Navigation oder ähnliches zentral modifizieren und immer wieder verwenden.
In [ZOPE05] gibt es ein einführendes Beispiel in die Verwaltung einer Website mit Unterseiten, einem Bereich für den Download von Dateien und einem einfachen Gästebuch. All dies lässt sich leicht in wenigen Minuten realisieren, sofern man mit der Syntax von DTML und Python vertraut ist. Auch wenn dies noch nicht besonders anspruchsvolle Anwendungen sind, so lassen sie schon Rückschlüsse auf die Komplexität bei der Erzeugung eines "richtigen" CMS zu.
Im Folgenden soll weiter auf die für Content Management benötigte Funktionalität eingegangen werden, die Zope bereits zur Verfügung stellt.
Zope lässt sich nachdem der Daemon oder Service gestartet wurde komplett über die integrierte Oberfläche verwalten. Nach der Installation und der Angabe von Benutzernamen und Kennwort hat der Administrator hier Zugriff auf das gesamte Zope-System. Es ist kein weiterer Zugriff auf den Server (etwa FTP o.ä.) notwendig.
Im Großen und Ganzen ist die Oberfläche mit einem Standard-Dateimanger wie dem Konqueror oder Windows-Explorer vergleichbar. Auf der linken Seite ist die Hierarchie von Objekten (Verzeichnissen) zu sehen, die wie gewohnt auf und zugeklappt werden können. Auf der rechten Seite wird das Objekt angezeigt, welches gerade bearbeitet wird. In diesem Fall ist das der root-Folder, dessen Inhalt zu sehen ist. Über der Liste mit dem Inhalt befindet sich eine Auswahlbox, aus welcher ein Objekt gewählt werden kann, welches dem aktuellen hinzugefügt werden soll. Daneben ist der entsprechende "Add"-Button zu finden.
Der Zugriffspfad zu Objekten spiegelt sich normalerweise in der URL wider, die in der Adresszeile
des Browsers angegeben werden kann. Die URL zur Anzeige einer Veranstaltung könnte demnach so
aussehen: http://localhost:8080/kalender/veranstaltung
. Wenn dieses Objekt bearbeitet
werden soll, so reicht der Zusatz /manage
.
Das Erzeugen und weitere Verwalten der vordefinierten Objekte ist durch das Interface leicht zu bewerkstelligen, deshalb soll hier nicht weiter darauf eingegangen werden. Welche Arbeit Zope einem Entwickler abnimmt, lässt sich gut am Beispiel der Undo-Funktion und der Sicherheitseinstellungen sehen. Über die Reiter "Security" bzw "Undo" wird für das aktuelle Objekt die entsprechende Detailansicht aufgerufen.
Mit der Undo-Funktion können im Prinzip beliebig viele Vorgänge rüchkgängig gemacht werden. Selbst Zwischenschritte, die nicht direkt von einander abhängen, können erhalten bleiben. Entscheidend ist die Abhängigkeit der Schritte voneinander, nicht ihre Reihenfolge.
Wie die Überschrift bereits vermuten lässt, basiert die Zugriffskontrolle in Zope auf dem Konzept von Benutzern, Rollen und Rechten. Für jedes Order-Objekt kann eine eigenständige Benutzer-Datenbank angelegt werden, das heißt, dass die Berechtigungen sich je nach Bereich einer Website unterscheiden können. Ist in einem Ordner kein User-Ordner enthalten, so wird dieser von seinen Eltern übernommen, wie bei allen anderen Zope Objekten auch. Bei der Erstellung eines Benutzers wird diesem eine Rolle zugewiesen. Dieser Rolle entsprechend hat der Benutzer dann in dem jeweiligen Kontext bestimmte Rechte, von denen er Gebrauch machen kann, wie zum Beispiel das Löschen eines Objektes. Für jedes Objekt kann wiederum in den Sicherheitseinstellungen extra angegeben werden, welche Rolle berechtigt ist, welche Aktion an diesem Objekt durchzuführen.
Die Sicherheitseinstellungen in Zope verhalten sich wie die meisten anderen Objekte auch. Ist ihnen eine Eigenschaft nicht zugewiesen, übernimmt es die vom übergeordneten Objekt. In der obigen Abbildung ist dies mit dem Haken bei Aquire zu sehen. Für jedes Objekt kann der Administrator detailiert angeben, welche Rolle ein Benutzer haben muss, um bestimmte Aktionen auszuführen.
Sollte es - aus welchen Gründen auch immer - notwendig sein, Daten in einer relationalen Datenbank zu verwalten, unterstützt Zope eine Reihe von relationalen Datenbanksystemen:
Wenn das verwendete DBMS Transaktionen unterstützt, koppelt Zope es an seine eigenen Transaktionen, um Integrität zwischen beiden, Zope und dem DBMS sicherzustellen. Sollte also eine Datenbankanfrage einer ZSQL-Methode scheitern, so wird sichergestellt, dass auch die anderen Queries der Methode nicht zum tragen kommen.
Zope kann durch neue Arten von Objekten erweitert werden, die als Produkte bezeichnet werden. Produkte können auf zwei unterschiedliche Weisen entwickelt werden: Im ZMI mit Hilfe von ZClasses, oder in Python.
Die Produkte, die mit Hilfe des ZMI erzeugt werden enhalten Fabriken, die die Parameter des Benutzers bei der Erzeugung eines neuen Objektes dieses Typs verarbeiten. Entsprechend sollten die kreierten Objekte die vom Benutzer angegebene Id haben und eventuell andere Werte aus den Parametern übernehmen bzw. verarbeiten. Im Grunde genommen ist die Entwicklung im ZMI die Erstellung von Makros, welche Objekte erzeugt werden sollen und wie diese sich untereinander verhalten.
Ein schönes Beispiel für die Erzeugung eines Skriptes, welches mit den Eigenschaften von
Objekten arbeitet ist in [ZOPE05] ist die Implementierung eines einfachen Workflow. Hier geht es
nur darum, Objekte nach einem Attribut status
zu filtern und in einer Ergebnisliste
anzuzeigen.
## Script (Python) "objectsForStatus"
##parameters=status
##
"""
Returns all sub-objects that have a given status
property.
"""
results=[]
for object in context.objectValues():
if object.getProperty('status') == status:
results.append(object)
return results
Dieses Skript iteriert über alle Subobjekte eines Objekts und gibt alle Objekte zurück,
deren Attribut status
den Wert des Parameters status
enthält.
Anschließend kann das folgende DTML-Skript Reports per Email verschicken:
<dtml-sendmail>
To: <dtml-var ResponsiblePerson>
Subject: Pending Objects
These objects are pending and need attention.
<dtml-in expr="objectsForStatus('Pending')">
<dtml-var title_or_id> (<dtml-var absolute_url>)
</dtml-in>
</dtml-sendmail>
Hier ist gut zu sehen, dass DTML für die Formatierung benutzt wird, während das Python-Skript die eigentliche Programmlogik enthält. Das ist die meistverwendete Anwendung und Arbeitsteilung dieser Skriptmöglichkeiten.
Wenn die Menge der Anfragen an einen Server zu groß wird, liegt es nah, die Last auf mehrere Server zu verteilen. Diese einfache Lösung hat jedoch einen Haken: Wie soll sichergestellt werden, dass alle Server mit der gleichen Information arbeiten? Im Fall Zopes ist der Knackpunkt die Objektdatenbank. Normalerweise wird die Datei, in der die Datenbank enthalten ist gesperrt, so dass nur ein Server darauf zugreifen kann. Es ist also nicht möglich, dass sich mehrere Server die Datenbank eines Servers teilen.
Um dieses Problem zu lösen wurden die Zope Enterprise Objects (ZEO) eingeführt, eine Client-/Server-Architektur, die es gestattet, dass mehrere Zopes sich eine Datenbank teilen. Die "normalen" Zope-Instanzen (ZEO-Clients) agieren weiterhin als Webserver, werden aber zu Clients des ZEO-Servers, der die Datenbank enthält. Da ZEO-Clients und -Server über Standard-Internetprotokolle miteinander kommunizieren, können die Maschinen sich im gleichen Raum oder über den Erdball vertstreut befinden.
ZEO sind geeignet, um verschiedene Aufgaben zu übernehmen:
Den kritischen Schwachpunkt einer ZEO Installation stellt natürlich der Server dar, da bei seinem Ausfall auch die Clients nicht mehr in der Lage wären, Anfragen zu beantworten. Hier kann eine relativ teure "High-End"-Server-Lösung Abhilfe schaffen, die intern mit entsprechenden Redundanzen arbeitet. Dieser Aufwand ist bei den Clients in der Form nicht notwendig, da beim Ausfall eines Clients, andere dessen Aufgaben mit übernehmen können.