Skip to topic | Skip to bottom
Home
Zope.ZopeLernenr1.17 - 01 Mar 2007 - 07:54 - FrankBurkhardt [Zum Ende]

Start of topic | Direkt zum Menü

Der lange Pfad zum eigenen Zopeserver

Diese Seite befasst soll einen Einstieg in Zope3 bieten. Ein gutes Buch kann er vermutlich aber nicht ersetzen.

Achtung: Der Crashkurs ist noch nicht fertiggestellt.

Vorher durchlesen...

Zope3 kommt mit einer Unmenge an Begriffen daher, die unter ZopeGlossary kanalisiert werden. Ausserdem existiert ein im Aufbau befindliches Kochbuch ( CookBook ), in dem man Probleme nachschlagen sollte, bevor man herrumfragt. Ich lese regelmäßig die Mailingliste und übernehme alle dort beantworteten Fragen ins Kochbuch - insofern ich die Lösung verstanden hab wink . Wer noch nie objektorientiert programmiert hat, sollte vorher dringend ZopeForOopNewbies durchlesen.

Eingabe, Verarbeitung, Ausgabe

Der Zopeserver ist abgesehen von seiner Datenbank zustandslos und arbeitet streng nach dem EVA-Prinzip:

  • Eingabe: Ein ReQuest (z.B. eine HTTP-Anfrage eines Browsers) trifft ein.
  • Verarbeitung: Eine VieW (mehr dazu weiter unten) verarbeitet den ReQuest - benutzt dabei üblicherweise nur Informationen aus ...
    • dem ReQuest (z.B. Benutzernamen, Password, Sitzungsinformationen in Cookies, ...)
    • der ZodB, der Datenbank hinter Zope (wird weiter unten beschrieben)
  • Ausgabe: Die VieW liefert etwas - z.B. eine Webseite - an den Browser zurück.

Wenn man z.B. ein ForMular abruft um beispielsweise einen Telefonbucheintrag auf dem Zope-Server zu verändern, merkt sich der Zopeserver das nicht (zumindest nicht zwangsläufig). Änderungen werden erst durchgeführt, wenn das ForMular ausgefüllt beim Zopeserver eintrifft.

Installation

Unter ZopeInstallation ist beschrieben, wie man einen Zope-Server aufsetzt. Nach der Installation haben wir eine Zope-instanz vor uns - ein kleines Verzeichnis mit Konfigurationsfiles und der zur Instanz gehörenden Datenbank ( ZodB ). Der Zope-Server selbst besteht aus endlos vielen Python-Dateien (Endung .py ) und liegt in einem anderen Verzeichnis, dass nicht beschreibbar sein muss. Auf diese Weise können mehrere ZopeInstances auf einem Server laufen - auch wenn das wegen des hohen Speicherbedarfs nicht immer ratsam ist.

Start der ZopeInstance

Beim Start arbeitet die ZopeInstance eine Konfigurationsdatei etc/zope.conf ab, in der das unscheinbare Statement site-definition $INSTANCE/etc/site.zcml auf eine Datei verweist, die in einer Zope-eigenen XmL-Sprache ZCML geschrieben ist. Diese Datei bildet die Wurzel des ZcmL-Baumes, der bei jedem Start (und nur beim Start!) abgearbeitet wird. Durch verschachtelte Include-Anweisungen wird dabei jedes gewünschte Python-Paket und dessen Unterpakete in Zope registriert und kann Komponenten zur Verfügung stellen.

Das ZmI

Die ZopeInstance lä[t sich idealerweise komplett im Browser verwalten. Dafür ist eine Management-Oberfläche - das ZmI zuständig. Diese Oberfläche ist jedoch nicht in Stein gemeisselt - man kann in dieser praktisch alles auf eigene Bedürfnisse anpassen. Alles, was man im ZmI sieht, sind sog. VieWs (Erklärung siehe weiter unten) und damit abhängig vom ContentObject, das man gerade betrachtet. Für ein ConTainer-Objekt kann das z.B. eine Ansicht der enthaltenen Unterobjekte mit einer Möglichkeit, diese Umzubenennen sein.

An Zope2-Umsteiger:

  • Das ZmI ist nicht für TTW-Entwicklung gedacht. In Zope3 wird aussschliesslich im Filesystem entwickelt. Das ZmI ist nur für das Zusammensetzen entwickelter Komponenten und zum Konfigurieren gut.

Die ZodB

Eine Objektorientierte Datenbank steht Zope zur Seite. In dieser ist eine hierarchische Struktur aus Content-Objekten und anderen Dingen ablegt. Durch TraVersing kann man auf Objekte in den Tiefen der Datenbank zugreifen. TraVersing findet z.B. beim Auswerten einer an die ZopeInstance übergebenen UrL stat.

Content-Objekte

ContentObjects sind die eigentlichen Daten, die eine ZopeInstance verwaltet. Man kann sie mit Objekten in Dateisystemen vergleichen - es gibt Verzeichnisse und Dateien, allerdings keine Links. Ein Unterschied ist jedoch, dass man bei Zope auch direkt in Verzeichnisobjekten Daten ablegen kann und nicht nur in Dateien. ContentObjects in der ZodB kann man als Instanzen von Content-Klassen betrachten.

Eigene ContentObjects entwirft man, indem man...

  • (je nach Anwendungsfall mindestens) ein SchemaInterFace des ContentObjects schreibt
  • eine Klasse für das ContentObject implementiert, die im einfachsten Fall praktisch keinen selbstgeschriebenen Programmcode enthalten muss
  • Die Klasse per ZcmL registriert.

ContentObjects enthalten Attribute, in denen der eigentliche Content lagert, den später der Nutzer im Internet sieht. Diese Attribute können auch Links (sog. KeyReferences) zu anderen ContentObjects enthalten und spannen so den Graph auf, der in der ZodB alle ContentObjects zu etwas sinnvollem (z.B. einem Baum) verbindet.

Mehrsprachiger Content

Man sich im klaren darüber sein, ob Daten in den Objekten mehrsprachig abgespeichert werden sollen und wie man das anstellen will. Im einfachsten Fall könnte man z.B. den Titel als zwei Attribute title_de und title_en speichern (Zweisprachigkeit). MpgSite bietet eine Möglichkeit, mit wenig Aufwand Attribute von Objekten in beliebig vielen Sprachversionen zu speichern: FbI18n.

ConTainer und deren Inhalt

Um die Verwaltung zu erleichtern, macht man unter Zope3 heftigen Gebrauch von ConTainern?. Das sind Objekte, die das Interface IContainer erfüllen und damit ein sog. Python-Mapping zur Verfügung stellen - eine Zuordnung Objektname zu Objektreferenz . Der Zugriff auf ein Unterobjekt erfolgt dann so:

mein_unterobjekt=container_objekt['unterobjektname']

Auf diese Weise entsteht ein Baum, den man sich relativ leicht vorstellen und den man mit dem ZmI leicht verwalten kann.

VieWs - Ansichten und Funktionen von Objekten

ContentObjects selbst haben erst einmal keinerlei Erscheinungsbild - dargestellt werden immer nur sog. VieWs.

VieWs kann man sich als Funktionen vorstellen, die an den Objekten hängen und z.B. über den Browser aufgerufen werden können. Eine Funktion an einem Kalenderobjekt könnte z.B. Wochenansicht sein - diese würde dann z.B. eine HTML-Seite mit einer Wochenansicht des Kalenders zurückliefern.

Was VieWs von richtigen Funktionen unterscheidet, ist, dass sie in Wirklichkeit andere Objekte sind, die sich das anzuzeigende ContentObject vornehmen und damit irgendetwas anstellen. Das Objekt selbst muss von der VieW nichts wissen. Zugeordnet wird die VieW (es handelt sich dabei um einen Objekt-auf-HTML-AdapTer) durch die Komponenteninfrastruktur von Zope3 (mehr dazu weiter unten).

VieWs sind allerdings nicht auf das Zurückliefern von HTML beschränkt - man kann z.B. auch VieWs schreiben, die z.B. in einem Verzeichnis-Objekt ein Unterobjekt entfernen und dann auf eine andere Seite (z.B. die Verzeichnisansicht ) weiterleiten. Dabei wären die zurückgelieferten HTML-Daten uninteressant - nur die Funktionalität (Datei gelöscht) ist von Interesse.

VieWs an einem Objekt haben meist einprägsame Namen (die Namen sind frei wählbar) wie edit.html (ein Edit-ForMular, mehr dazu weiter unten), index.html / view.html - die Standardansicht oder printable.html (Unter MpgSite die Druckansicht) eines ContentObjects.

Genauer: * VieWs hängen nicht an Objekten, sondern werden an sog. InterFaces festgemacht. Sobald ein Objekt das InterFace einer VieW erfüllt, ist diese für das Objekt verfügbar.

Beispiel: Das Objekt /waldbewohner/Eiche erfüllt das InterFace IBaum . Am InterFace IBaum sind für alle HTTP-ReQuests die VieWs giessen.html und abholzen.html festgemacht. Deshalb führt der Pfad /waldbewohner/Eiche/giessen.html zu einer existierenden VieW .

Hinweise:

  • In VieWs werden Daten für den aktuellen Benutzer/Betrachter aufbereiter. Um Daten zu Internationalisieren, muss man bestimmte Regeln einhalten: InterNationalisation.
  • VieWs können selbst auch VieWs haben, was eine weitere Abstraktionsebene erzeugt.
  • Um das bilden von VieWs aus UrLs kümmert sich der TraVersing-Prozess.

Formulare

VieWs können extrem komplex sein - z.B. generieren Formulare eine HTML-Seite entsprechend der im entsprechenden ContentObject abgespeicherten Daten. Der Benutzer kann das ForMular bearbeiten und der Browser schickt es an die selbe VieW zurück. Dabei müssen/dürfen/sollten die Daten des ForMulars nicht bereits beim ersten zurückschicken abgespeichert werden. Das ForMular entnimmt wahlweise die dem ReQuest die vom Benutzer geändertem (und auch die nicht veränderten) Daten und schickt sie wieder an den Benutzer zurück - solange, bis der entsprechende Button zum abspeichern der ForMular -Inhalte gedrückt wurde.

Hinweise:

  • Zope3 kann ForMular -Daten auf die Einhaltung gewisser Regeln überprüfen ( siehe InterFace#ConStraints ) und Pro-Feld-Fehlermeldungen ausgeben.
    Beispiel: Das Textfeld eMail darf keine Sonderzeichen enthalten.
  • Zope3 kann ausserdem Zusammenhänge zwischen Feldern auf korrektheit überprüfen (sog. InVariants ).
    Beispiel: Wenn die Has eMail -Checkbox angecheckt ist, darf das Textfeld eMail nicht leer sein.
  • Zwei ZcmL

WidGets für Formulare

WidGets sind Objekte, die sich um die Darstellung und Verarbeitung von Daten für bestimmte ReQuests kümmern.

Oftmals reicht zur Beschreibung folgende Aussage: WidGet sind Objekte, die sich um die Darstellung von Feldern von ContentObjects in HTML- Formularen kümmern.

Oft hat man nur mit sogenannten InputWidgets zu tun. Das sind WidGet, die zum einen ForMular -felder generieren und auf die vom Browser zurückgelieferten Daten wieder in ein ContentObject speichern können. Anzeigen kann man Daten zwar über sog. DisplayWidgets, jedoch wünscht man meist mehr Einfluss auf z.B. die Form der Einbettung von Daten in HTML-Daten.

PageTemplates

PageTemplates sind HTML-Fragmente (es sind auch komplette HTML-Seiten denkbar, das ist aber nicht üblich). Solche Templates sind das Verbindungsstück zwischen Content und HTML-Seiten und werden intensiv in VieWs genutzt. PageTemplates werden am besten als wohlgeformtes XmL geschrieben und lassen sich deshalb auch mit jedem XmL-Editor bearbeiten. Ausnahmen wie z.B. beim <br> -HTML-Tag sind machbar, aber sollten vermieden werden.

PageTemplates lassen sich leicht Internationalisieren und auch lokalisieren?.

In PageTemplates kommen mehrere XmL-Namensräume zum Einsatz, die für die Umwandlung des Templates in ein fertiges XmL-Dokument entscheident sind - Informationen darüber gibt's unter PageTemplates#NameSpaces .

LayeR und SkiNs

LayeR sind Sammlungen von VieWs, die etwas gemeinsam haben . Üblicherweise realisiert ein LayeR so etwas wie ein einheitliches Thema einer Webseite, das sich durch Umschalten auf einen anderen LayeR. Dabei steht extreme Flexibilität zur Verfügung - man kann z.B. Benutzergruppenspezifisch die Oberfläche anpassen.

Hinter den Kullissen - Zope-Komponenten

Die Komponenteninfrastruktur

Zope3 verfügt über eine mächtige Komponenteninfrastruktur, die alles durchdringt. Das ermöglichte einfachen Austausch, Wiederverwendung und Erweiterung von Programmteilen.

Die Seite ZopeComponents läßt sich darüber genauer aus.

Modularität durch Pakete

Zope3 besteht ausschliesslich aus simplen Python-Paketen - nicht aus speziellen Zope-Produkten wie das bei Zope2 der Fall war. Um ein Paket für Zope3 zu erschliessen, muss es per ZcmL konfiguriert werden - dafür liegt üblicherweise eine Datei configure.zcml im Basisverzeichnis des Paketes und eine weitere ZcmL -Datei, die nur eine Include-Anweisung enthält im ZopeInstance-Verzeichnis etc/package-includes/[Paketname]-configure.zcml . Pakete includen dann wiederum ihre Unterpakete, wodurch ein weit-verzweigter ZcmL-Baum bei jedem Start abgearbeitet wird.

Hinweis:

  • Wo die per ZcmL eingebundenen Pakete liegen ist irrelevant - solange sie in einem Python zugänglichen Pfad liegen (dafür kann man im Zweifelsfall die Umgebungsvariable PYTHONPATH bzw. das Zope-Startscript bin/runzope anpassen)
  • Es ist noch etwas komplizierter - der ZcmL-Baum besteht eigentlich aus 3 Unterbäumen mit bestimmten Funktionen. Mehr dazu unter ZcmL#MultipleTrees .

Das Zope3-Sicherheitssystem

Zope3 macht den Zugriff auf praktisch alles davon abhängig, ob man jeweils die richtige PerMission (Berechtigung) besitzt. Eine solche PerMission ist erstmal nichts weiter, als ein String (z.B. zope.ManageContent für die Berechtigung, ein Objekt zu bearbeiten). Jedem ReQuest wird im Rahmen der Authentifikation (z.B. über das PaU-UtilitY) ein PrinCipal (Benutzerobjekt) zugeordnet. Eine PerMission erhält man, indem im Laufe des TraVersing-Prozesses auf irgendeine Weise dem aktuellen PrinCipal die entsprechende PerMission zugeordnet wird.

SecurityPolicys

Zope3 kennt sog. SecurityPolicys - Objekte, die Möglichkeiten der Zuordnung PrinCipal-zu-PerMission bereitstellen. Die Standard-SecurityPolicy kennt z.B. das Konzept der Rollen (Warum das Rollen genannt wird, ist unklar - es handelt sich um Benutzergruppen), das eine zusätzliche Abstraktionsschicht zwischen PerMissions und PrinCipals aufbaut.

Die SecurityPolicy ist austauschbar, jedoch sollten die meisten mir der Standard-Policy glücklich werden können.

Sicherheit entlang des Pfades

An jedem ContentObject können Sicherheitsregeln (Zuordnungen zwischen PerMissions, Rollen und PrinCipals) hängen. Diese Zuordnungen sind entweder positiv (gewähren Rechte oder Rollenmitgliedschaft) oder negativ (entfernen ein Recht oder eine Rollenmitgliedschaft wieder). Der Unix-Administrator im Author dieses Textes meint, man sollte nur positive Rechte benutzen.

Während die VieW des aktuellen ReQuests nun per TraVersing aus der UrL extrahiert wird, geht die ZopeInstanz? durch den ConTainer-Baum der ZodB und hüllt die gefundenen Objekte jeweils mit SecurityProxys ein, die anhand der ZcmL-Konfiguration der jeweiligen Klasse entscheiden, ob man für genau dieses Objekt das Recht hat, auf bestimmte Attribute zuzugreifen oder nicht.

VieWs werden zusätzlich mit PerMissions ausgestattet, um z.B. festzulegen, dass die edit.html -VieW einer bestimmten Objektklasse nur von privilegierten PrinCipals benutzt werden darf, die Standardansicht index.html jedoch jeder sehen kann.

Ereignisse

Ereignisse werden benutzt, um bei bestimmten Anlässen Aktionen auszulösen. Ein Beispiel ist, dass Objekte beim Anlegen in den Suchindex aufgenommen werden. Das könnte so laufen (in der Zope3-Wirklichkeit liegt noch eine Abstraktionsebene ( das IntId - UtilitY ) dazwischen).

Die Lektüre folgender Wiki-seite ist zu empfehlen: EvenT.

Hinweis: In den CataLog (die Suchmaschine von Zope) werden Objekt eigentlich beim Hinzufügen in einen ConTainer aufgenommen, nicht direkt beim Anlegen. Das ist oft deckungsgleich.

Metadaten

An praktisch alle Persistenten Objekte kann man zusätzliche Informationen anhängen - sog. MetaDaten, die in Zope3 per AnnoTations realisiert sind. Dabei muss man praktisch nichts über die einzelnen Klassen dieser Objekte wissen - sie müssen lediglich ein bestimmtes InterFace ( IAnnotatable ) implementieren.

Die Rauhe Wirklichkeit

In der Hoffnung, dass diese Seite das grundlegende Verständnis für Zope3 gebracht hat, wird hier auf zwei Zope3-Bücher verwiesen. Diese führen durch die Programmierung jeweils einer umfangreichen Webanwendungen in die praktische Umsetzung von Zope3-Projekten ein. Diese Wiki steht helfend mit einem Glossar und einem Kochbuch zur Verfügung, wenn die Zope-Gurus, die die beiden Bücher schrieben mal wieder zuviel Wissen vorraussetzen smile .

Viel Erfolg.
[Zurück zum Start]


Aktuelle Wiki-Seite: Zope > ZopeLernen

[Zurück zum Start]

Alle Inhalte dieses Web dürfen frei kopiert und verändert werden.