Deutsche Zope User Group
Gast 2 Benutzer online
DZUG-News

Zopebuch: Inhaltsverzeichnis 

Kapitel 10: Zope-Scripting f�r Fortgeschrittene

Zope verwaltet ihre Pr�sentation, Logik und Daten durch Objekte. Bis hierher haben Sie gesehen, wie Zope Pr�sentation �ber DTML und Daten �ber Dateien und Bilder verwalten kann. Dieses Kapitel zeigt Ihnen, wie Sie Skript-Objekte hinzuf�gen k�nnen, was Ihnen erlaubt, mit ihrem Browser Skripte in Python und Perl zu schreiben.

Was ist Logik und wie unterscheidet sie sich von der Pr�sentation? Logik liefert die Aktionen, die Objekte �ndern, Nachrichten senden, Bedingungen pr�fen und auf Ereignisse antworten, w�hrend die Pr�sentation Informationen und Meldungen anzeigt und formatiert. Typischerweise werden Sie DTML benutzen, um ihre Pr�sention zu bearbeiten und Zope-Skripting mit Python und Perl, um Logik zu bearbeiten.

Zope-Skripte

Zope-Skript-Objekte sind Objekte, die ein kleines bi�chen Code enthalten, der in einer Programmiersprache geschrieben ist. Gegenw�rtig bietet Zope Python-basierte Skripte, die in der Programmiersprache Python geschrieben sind, und Perl-Skripte, die in der Programmiersprache Perl geschrieben sind. Skript-Objekte sind seit Zope 2.3 eingef�hrt worden und stellen die bevorzugte Weise dar, Programm-Logik in Zope zu schreiben.

Bisher haben sie in diesem Buch starken Gebrauch von DTML-Skripten und -Dokumenten gemacht, um einfache Anwendungen in Zope herzustellen. DTML erlaubt Ihnen, einfache Skript-Operationen wie String-Auswertungen durchzuf�hren. DTML-Skripte sollten jedoch haupts�chlich zur Pr�sentation angewendet werden. In Kapitel 4 (Dynamische Inhalte mit DTML) und Kapitel 8 (Variablen und fortgeschrittenes DTML) werden DTML-Skripte erkl�rt.

Es folgt ein �berblick �ber die Skripte von Zope:

Python-basierte Skripte
Sie k�nnen Python - eine Allzweck-Skriptsprache - benutzen, um Zope-Objekte zu kontrollieren und andere Aufgaben durchzuf�hren. Diese Skripte geben Ihnen universelle Programmierungsm�glichkeiten innerhalb von Zope.
Perl-basierte Skripte
Sie k�nnen Perl - eine m�chtige textverarbeitende Programmiersprache - benutzen, um Zope-Objekte zu verarbeiten und Perl-Bibliotheken einzubinden. Diese Skripte bieten �hnliche Vorteile wie Python-basierte Skripte, m�gen aber f�r Leute angenehmer sein, die mit Perl eher vertraut sind als mit Python oder die Perl-Bibliotheken verwenden wollen, f�r die es kein Python-Pendant gibt.

Sie k�nnen diese Skripte ihrer Zope-Anwendung genau wie jedes andere Objekt hinzuf�gen.

Skripte aufrufen

Zope-Skripte werden �ber das Web oder andere Skripte oder Objekte aufgerufen. Fast jede Art von Skript kann von jeder anderen Objekt-Art aufgerufen werden; Sie k�nnen ein Python-basiertes Skript von einem DTML-Skript oder ein eingebautes Skript von einem Perl-basierten Skript aufrufen lassen. Tats�chlich k�nnen Skripte wiederum Skripte aufrufen, die wieder andere Skripte aufrufen und so weiter. Wie Sie in Kapitel 4 (Dynamische Inhalte mit DTML) gesehen haben, k�nnen sie ohne weiteres ein Skript durch ein Skript ersetzen, das in einer anderen Programmiersprache geschrieben ist. Wenn Sie beispielsweise Perl benutzen, um eine Aufgabe auszuf�hren, sich aber sp�ter entschlie�en, da� dasselbe besser in Python getan werden sollte, k�nnen Sie normalerweise das Skript mit einem Python-basierten Skript mit derselben id ersetzen.

Wenn Sie ein Skript aufrufen, �bergibt die Weise, auf die Sie es aufrufen, den Kontext, in dem es ausgef�hrt werden soll. Der Kontext eines Skriptes ist wichtig. Wenn Sie zum Beispiel ein Skript aufrufen, gibt es gew�hnlich ein bestimmtes Objekt, welches das Zentrum der Aufgabe des Skripts ist. Das bedeutet, Sie rufen das Skript im Kontext des Objekts auf, an dem Sie die Aufgabe ausf�hren wollen. Wir sagen vereinfacht, da� wir das Skript auf dem Objekt aufrufen.

Skripte aus dem Web aufrufen

Sie k�nnen ein Skript direkt aus dem Web aufrufen, indem Sie seinen URL aufrufen. Sie k�nnen ein einziges Skript �ber verschiedene Objekte aufrufen, indem Sie verschiedene URLs benutzen. Das funktioniert, weil Sie �ber die Benutzung verschiedener URLs dem Skript verschiedene Kontexte �bergeben und Skripte kontextabh�ngig unterschiedlich operieren k�nnen. Das ist eine m�chtige M�glichkeit, die ihnen Gelegenheit gibt, Logik auf Objekte wie Dokumente oder Ordner anzuwenden, ohne da� Sie den Code dazu im Objekt einbetten m�ssen.

Um ein Skript auf einem Objekt aus dem Web aufzurufen, besuchen Sei einfach den URL des Objekts, gefolgt vom Namen des Skripts. Das setzt das Skript in den Kontext des Objekts. Nehmen Sie beispielsweise an, Sie h�tten eine Sammlung von Objekten und Skripten wie in Abbildung 8.1 dargestellt.

Eine Sammlung von Objekten und Skripten.

Abbildung 8.1 Eine Sammlung von Objekten und Skripten

Um das Skript fuettern auf dem Objekt Nilpferd aufzurufen, w�rden Sie den URL Zoo/GrosseTiere/Nilpferd/fuettern besuchen. Um das Skript fuettern auf dem Objekt Springmaus aufzurufen, k�nnen Sie den URL Zoo/KleineTiere/Springmaus/fuettern besuchen. Diese URLs bringen das Skript fuettern in den Kontext der Objekte Nilpferd oder Springmaus.

Zope benutzt den URL als eine Landkarte, um herauszufinden, welches Objekt und welches Skript Sie aufrufen wollen.

Zope zerlegt den URL und vergleicht ihn mit der Objekthierarchie, indem es sich r�ckw�rts durcharbeitet, bis es eine �bereinstimmung f�r jeden Teil findet. Dieser Proze� wird URL-Traverse (URL traversal) genannt. Wenn Sie Zope zum Beispiel den URL Zoo/GrosseTiere/Nilpferd/fuettern angeben, beginnt es beim Root-Ordner und schaut nach einem Objekt namens Zoo. Dann bewegt es sich zum Order Zoo und schaut dann nach einem Objekt namens GrosseTiere. Es bewegt sich zum Ordner GrosseTiere und sucht nach einem Objekt, das Nilpferd hei�t. Es geht zum Objekt Nilpferd und sucht ein Objekt namens fuettern. Das Skript fuettern kann im Objekt Nilpferd nicht gefunden werden, aber Zope findet es aufgrund eines Vorgangs, der Erwerbung (acquisition) hei�t, im Ordner Zoo.

"Erwerbung" tut zwei Dinge. Zuerst versucht es, das gesuchte Objekt in den Ordnern des aktuell aufgerufenen Objekts zu finden. Wenn das nicht klappt, zieht es sich entlang des URL-Pfades zur�ck und versucht es w�hrenddessen weiter. In diesem Beispiel sucht Zope zun�chst in Nilpferd nach dem Objekt fuettern, dann geht es zum ersten Ordner, GrosseTiere, und dann zum n�chsten Ordner, Zoo, wo schlie�lich fuettern gefunden wird.

Nun hat Zope das Ende des URLs erreicht. Es ruft das letzte gefundene Objekt auf: fuettern. Das Skript fuettern handelt in seinem Kontext, der auf dem vorletzten gefundenen Objekt beruht, dem Objekt Nilpferd. So wird das Skript fuettern auf dem Objekt Nilpferd aufgerufen.

Genauso k�nnen Sie das Skript waschen mit dem URL Zoo/GrosseTiere/Nilpferd/waschen auf dem Objekt Nilpferd aufrufen. In diesem Fall erwirbt Zope das Skript waschen aus dem Ordner GrosseTiere.

Es sind auch komplexere Anordnungen m�glich. Angenommen, Sie wollen das Skript impfen auf dem Objekt Nilpferd aufrufen. Welchen URL k�nnen Sie benutzen? Wenn Sie �ber den URL Zoo/GrosseTiere/impfen vorgehen, wird Zope das Skript impfen nicht finden k�nnen, weil es sich in keinem von Nilpferds Beh�ltern befindet.

Die L�sung besteht darin, den Pfad zum Skript als Teil des URL einzugeben. So wird Zope das richtige Skript finden, wenn es Erwerbung benutzt, um das Skript zu finden, w�hrend es den URL zur�ckverfolgt. Der URL zur Impfung des Nilpferds ist Zoo/Tierarzt/GrosseTiere/Nilpferd/impfen. Genauso sollten Sie den URL Zoo/Tierarzt/KleineTiere/Springmaus/impfen benutzen, wenn Sie das Skript impfen auf die Springmaus anwenden wollen.

Lassen Sie uns mitverfolgen, wie Zope den URL Zoo/Tierarzt/GrosseTiere/Nilpferd/impfen durchl�uft. Zope beginnt im Root-Ordner und sucht nach einem Objekt namens Zoo. Es bewegt sich zum Ordner Zoo und schaut nach einem Objekt, das Tierarzt hei�t. Es geht zum Ordner Tierarzt und sucht nach einem Objekt namens GrosseTiere. Der Ordner Tierarzt enth�lt kein Objekt mit diesem Namen, aber es kann den Ordner GrosseTiere �ber den Beh�lter Zoo ansprechen. Also bewegt es sich zum Ordner GrosseTiere und schaut nach einem Objekt Nilpferd. Dann geht es zum Objekt Nilpferd und sucht dort nach dem Objekt impfen. Weil weder das Objekt Nilpferd noch einer seiner Beh�lter ein Objekt namens impfen enth�lt, geht Zope den Pfad zur�ck und versucht dabei, das Objekt impfen zu finden. Zuerst zieht es sich zum Ordner GrosseTiere zur�ck, wo impfen immer noch nicht gefunden werden kann. Dann geht es zur�ck zum Ordner Tierarzt. Hier findet es das Skript impfen. Weil Zope nun zum Ende des aufgerufenen URL gekommen ist, wendet es das Skript impfen im Kontext des Objekts Nilpferd an.

Wenn Zope w�hrend einer URL-Traverse nach einem Sub-Objekt sucht, schaut es zuerst im aktuellen Objekt nach dem Sub-Objekt. Wenn es im aktuellen Objekt das Sub-Objekt nicht finden kann, schaut es in den Beh�ltern des aktuellen Objekts. Wenn es das Sub-Objekt dann immer noch nicht finden kann, zieht es sich entlang des URL-Pfades zur�ck und sucht erneut. Es verfolgt diesen Proze�, bis es entweder das Objekt findet oder einen Fehler meldet, wenn es nicht gefunden werden kann.

Das ist ein sehr n�tzlicher Mechanismus und er erlaubt Ihnen, recht ausdrucksvoll zu sein, wenn Sie URLs zusammenstellen. Der Pfad, den Sie Zope mitteilen, damit es seinen Weg zu einem Objekt findet, wird bestimmen, wie es Erwerbung benutzt, um die Skripte f�r das Objekt zu finden.

Skripte von anderen Objekten aufrufen

Sie k�nnen Skripte anderer Objekte aufrufen. Zum Beispiel ist es �blich, Skripte von DTML-Skripten aufzurufen.

Wie Sie in Kapitel 8 (Variablen und fortgeschrittenes DTML) gesehen haben, k�nnen Sie Zope-Skripte von DTML mit dem call-Tag aufrufen. Zum Beispiel:

      

DTML wird das Skript aktualisiereInfo aufrufen. Sie brauchen nicht zu spezifizieren, ob das Skript in Perl, Python oder irgendeiner anderen Programmiersprache implementiert ist (Sie k�nnen genausogut andere DTML-Objekte oder SQL-Skripte auf diese Art aufrufen).

Wenn das Skript aktualisiereInfo Parameter braucht, m�ssen Sie entweder einen Namen f�r die DTML-Namensraum-Bindung (siehe unten: Bindende Variablen) ausw�hlen, damit die Parameter im Namensraum nachgeschlagen werden k�nnen oder die Parameter in einem Ausdruck �bergeben, wie hier:

      

Skripte von Python oder von Perl aus aufzurufen, funktioniert auf dieselbe Art, nur da� Sie immer Skript-Parameter �bergeben m�ssen, wenn Sie ein Python- oder Perl-Skript aufrufen. Hier ist ein Beispiel, wie Sie das Skript aktualisiereInfo aus Python aufrufen m�gen:

      context.aktualisiereInfo(farbe='braun',
                         muster='gefleckt')

Aus Perl k�nnten Sie dasselbe tun, indem Sie Standard-Perl-Semantik zum Aufrufen von Skripten benutzen:

      $self->aktualisiereInfo(farbe => 'braun',
                          muster => 'gefleckt');

Jede Skript-Sprache hat ihre eigene Art, Skripte aufzurufen, es spielt aber keine Rolle, in welcher Sprache das aufgerufene Skript geschrieben ist, solange man die passenden Parameter �bergibt.

Wenn ein Skript aufgerufen wird, wird es in wie beim Aufruf �ber das Web durch Erwerbung gesucht. Kehren wir zu unserem Nilpferd-fuettern-Beispiel aus dem letzten Absatz zur�ck und lassen Sie uns sehen, wie ein Nilpferd von Python oder Perl aus geimpft werden kann. Abbildung 8.2 zeigt eine leicht ver�nderte Objekthierarchie, die zwei Skripte enth�lt, impfeNilpferd.py und impfeNilpferd.pl.

Eine Sammlung von Objekten und Skripten

Figure 8-2 Eine Sammlung von Objekten und Skripten

Stellen sie sich vor, da� impfeNilpferd.py ein Python-Skript ist. Hier sehen Sie, wie Sie das Skript impfen auf dem Objekt Nilpferd von Python aus aufrufen:

      context.Tierarzt.GrosseTiere.Nilpferd.impfen()

In anderen Worten: Sie greifen auf das Objekt zu, indem Sie denselben Erwerbungs-Pfad nutzen, den Sie gebrauchen w�rden, wenn Sie ihn vom Web aus aufrufen w�rden. Genauso k�nnten Sie in Perl sagen:

      $self->Tierarzt->GrosseTiere->Nilpferd->impfen();

Skripte von anderen Skripten aus zu benutzen, ist dem Aufrufen von Skripten aus dem Web sehr �hnlich. Die Semantik ist etwas anders, aber die Erwerbungs-Regeln bleiben die gleichen. Sp�ter in diesem Kapitel werden Sie mehr Beispiele sehen, wie Skripte in Perl oder Python funktionieren.

Parameter an Skripte �bergeben

Alle Skripte k�nnen Parameter �bergeben bekommen. Ein Parameter gibt einem Skript mehr Informationen dar�ber, was es tun soll. Wenn Sie ein Skript vom Web aus aufrufen, wird Zope versuchen, die Parameter f�r das Skript in der Web-Anfrage zu finden und sie an ihr Skript zu �bergeben. Wenn Sie zum Beispiel ein Skript mit den Parametern Delphin und REQUEST haben, wird Zope in der Web-Anfrage nach Delphin suchen, und die Anfrage selbst als REQUEST-Parameter �bergeben. Damit wird Formularverarbeitung in Skripten vereinfacht. Schauen Sie sich das folgende Formular an:

      
Name
Alter

Ohne weitere Arbeit k�nnen Sie dieses Formular mit einem Skript namens aktionsSkript verarbeiten, das in seiner Parameter-Liste name and alter enth�lt:

      ## Script (Python) "aktionsSkript"
      ##parameters=name, alter
      ##
      "Verarbeite Formular"
      context.verarbeiteName(name)
      context.verarbeiteAlter(alter)
      return context.rueckmeldeNachricht()

Das erspart Ihnen, Werte explizit aus dem Formular zu nehmen. Im Beispiel werden die Formularelemente �brigens als Strings �bergeben. Falls das Formular Check-Boxen enth�lt, oder Multiple-Selection Eingaben erlaubt, werden String-Listen erzeugt.

Zus�tzlich zu den Formular-Variablen k�nnen Sie jede Anfrage-Varaible als Skript-Parameter festlegen. Um zum Beispiel auf die Anfrage- und Antwort-Objekte zuzugreifen, schlie�en Sie einfach REQUEST und RESPONSE in ihre Parameter-Liste ein. Anfrage-Variablen sind genauer beschrieben in Anhang B.

Eine bemerkenswerte Sache ist, da� die Variable context sich auf das Objekt bezieht, auf dem das Skript aufgerufen wurde. Das funktioniert in Perl-basierten Skripten �hnlich, zum Beispiel:

      my $self = shift;
      $self->verarbeiteName($name);
      $self->verarbeiteAlter($alter);
      return $context->rueckmeldeNachricht();

In der Python-Version des Beispiels gibt es ein subtiles Problem. Sie erwarten vielleicht eher einen Integer-Wert als einen String f�r das Alter. Sie k�nnten mit hilfe der in Python eingebauten int Methode den String manuell in ein Integer konvertieren:

      alter=int(alter) # konvertiere einen String zu einem Integer

Aber diese manuelle Konvertierung k�nnte unbequem sein. Zope bietet Ihnen einen Weg, Formular-Eingabetypen im Formular selbst festzulegen, anstatt im verarbeitenden Skript. Statt die Variable alter im verarbeitenden Skript zu einem Integer zu konvertieren, k�nnen Sie im Formular bestimmen, da� es ein Integer ist:

      Age 

Der Anhang :int am Namen des Formular-Inputs tr�gt Zope auf, den Formular-Input automatisch in einen Integer zu konvertieren. Wenn der Benutzer ihres Formulars etwas eingibt, das nicht in einen Integer konvertiert werden kann (etwas wie "22, werde bald 23"), wird Zope - wie in Abbildung 8.3 - einen Fehler melden.

Parameter-Konvertierungsfehler

Figure 8.3 Parameter-Konvertierungsfehler

Es ist praktisch, da� Zope Konvertierungsfehler abf�ngt, aber vielleicht m�gen Sie Zopes Fehlermeldungen nicht. Sie sollten die Benutzung von Zopes Konverter vermeiden, wenn Sie ihre eigenen Fehlermeldungen bereitstellen wollen.

Zope kann viele Parameter-Konvertierungen durchf�hren. Hier ist eine Liste von Zopes grundlegenden Parameter-Konvertern:

boolean
Konvertiert eine Variablen nach wahr oder unwahr. Variablen, die 0, None, ein leerer String oder eine leere Sequenz sind, gelten als unwahr, alle anderen gelten als wahr.
int
Konvertiert eine Variable zu einem Integer.
long
Konvertiert eine Variable zu einem Langen Integer.
float
Konvertiert eine Variable zu einer Flie�kommazahl.
string
Konvertiert eine Variable zu einem String. Die meisten Variablen sind schon Strings, daher wird dieser Konverter selten benutzt.
text
Konvertiert eine Variable zu einem String mit normalisierten Zeilenumbr�chen. Verschiedene Browser auf verschiedenen Plattformen kodieren Zeilenenden auf verschiedene Weise, daher stellt dieses Skript sicher, da� die Zeilenenden konsistent sind, unabh�ngig davon, wie sie im Browser kodiert werden.
list
Konvertiert eine Variable zu einer Python-Liste.
tuple
Konvertiert eine Variable zu einem Python-Tupel. Ein Tupel ist wie eine Liste, kann aber nicht ver�ndert werden.
tokens
Konvertiert einen String zu einer Liste, indem die Leerzeichen als Trennzeichen angesehen werden
lines
Konvertiert einen String zu einer Liste, indem die Zeilenumbr�che als Trennzeichen angesehen werden.
date
Konvertiert einen String zu einem DateTime-Objekt. Die akzeptierten Formate sind ziemlich flexibel, zum Beispiel 10/16/2000, 12:01:13 pm.
required
Gibt einen Fehler aus, wenn die Variable nicht gef�llt ist.
ignore_empty
Schlie�t die Variable aus der Anfrage aus, wenn die Variable ein leerer String ist.

Diese Konverter arbeiten alle mehr oder weniger auf dieselbe Art, indem sie eine Variable in Gestalt eines Strings zu einem spezifischen Typ verarbeiten. Sie m�gen diese Konverter aus dem Kapitel 3 (Grundlegende Zope-Objekte benutzen) wiedererkennen, wo wir Eigenschaften diskutiert haben. Diese Konverter werden von Zopes Eigenschafts-Anlagen benutzt, um Eigenschaften zum richtigen Typ zu konvertieren.

Die Konverter list und tuple k�nnen in Kombination mit anderen Konvertern benutzt werden. Das erlaubt Ihnen, jedem Element der Liste oder des Tupels zus�tzliche Konverter zuzuweisen. Sehen Sie sich dieses Formular an:

      

Ich w�rde es vorziehen, zu den folgenden Zeiten nicht gest�rt zu werden:

Mitternachts
1:00 morgens
2:00 morgens
3:00 morgens
4:00 morgens

Wenn man die Konverter list und date gemeinsam benutzt, wird Zope jede ausgew�hlte Zeit in ein Datum konvertieren und dann alle ausgew�hlten Daten in einer Liste namens disturb_times kombinieren.

Eine komplexere Art der Konvertierung von Formularen ist, eine Serie von Eingaben zu Berichten (records) zu konvertieren. Berichte sind Strukturen, die Attribute haben. Bei der Benutzung von Berichten k�nnen Sie eine Anzahl von Formulareingaben in einer Variablen mit Attributen zusammenfassen. Die verf�gbaren Berichts-Konverter sind:

record
Konvertiert eine Variable zu einem Berichtsattribut.
records
Konvertiert eine Variable zu einem Berichtsattribut in einer Liste von Berichten.
default
Setzt einen voreingestellten Wert als Berichtsattribut ein, falls die Variable leer ist.
ignore_empty
Ignoriert ein Berichtsattribut, wenn die Variable leer ist.

Hier sind einige Beispiele f�r die Anwendung dieser Konverter:

      
Vorname
Nachname
Alter

Dieses Formular ruft das Skript verarbeitePerson mit einem Parameter person auf. Die Variable person wird die Attribute vname, nname and alter haben. Hier ist ein Beispiel daf�r, wie Sie die Variable person in ihrem Skript verarbeitePerson verwenden k�nnen:

      ## Skript (Python) "verarbeitePerson"
      ##parameters=person
      ##
      " einen Personen-Bericht verarbeiten "
      voller_name="%s %s" % (person.vname, person.nname)
      if person.alter < 21:
          return "Schade, %s. Sie sind nicht alt genug, um ein Erdferkel zu adoptieren.
          " % full_name
      return "Danke, %s. Ihr Erdferkel ist auf dem Weg." % voller_name

Der Konverter records arbeitet wie der Konverter record, nur produziert er eine Liste von Berichten, nicht nur einen. Hier ist ein Beispielformular:

      

Bitte geben Sie Informationen �ber einen oder mehrere ihrer n�chsten Verwandten ein.

Vorname Nachname

Vorame Nachname

Vorame Nachname

Dieses Formular wird das Skript verarbeiteMenschen mit einer Variablen namens people aufrufen, die eine Liste von Berichten ist. Jeder Bericht wird die Attribute vname und nname haben.

Eine andere n�tzliche Parameter-Konvertierung benutzt Formularvariablen, um die Aktion des Formulars neu zu schreiben. Das erlaubt Ihnen, ein Formular - abh�ngig von den Eingaben - an verschiedene Skripte zu �bertragen. Das ist besonders n�tzlich, falls ein Formular mehrere �bertragungsbuttons enth�lt. Zopes Aktions-Konverter sind:

action
�ndert die Aktion des Formulars. Das ist besonders n�tzlich, falls Sie mehrere �bertragungsbuttons in einem Formular haben. Jeder Button kann einem Skript zugeordnet werden, das aufgerufen wird, wenn der Button angeklickt wird, um das Formular zu �bertragen.
default_action
�ndert das Aktions-Skript des Formulars, wenn kein anderer method-Konverter gefunden wird.

Hier ist ein Beispiel-Formular, das Aktions-Konverter benutzt:

      

W�hlen Sie einen oder mehrere Angestellte aus:

Larry
Simon
Rene

Dieses Formular wird entweder das Skript feuereAngestellte oder befoerdereAngestellte aufrufen, abh�ngig davon, welcher der beiden �bertragungsbuttons benutzt wird. Beachten Sie auch, wie es mit dem Konverter list eine Liste der Angestellten aufbaut. Formular-Konverter k�nnen beim Design von Zope-Anwendungen sehr n�tzlich sein.

Skript-Sicherheit

Alle Skripte, die durch das Web bearbeitet werden k�nnen, sind Gegenstand von Zopes Standard-Sicherheitsregeln. Die einzigen Skripte, die nicht Gegenstand dieser Sicherheitsregeln sind, sind diejenigen, die durch das Dateisystem bearbeitet werden m�ssen. Diese uneingeschr�nkten Skripte schlie�en die Externen Skripte von Python und Perl ein.

Kapitel 7 (Benutzer und Sicherheit) deckt Sicherheitsaspekte detaillierter ab. Sie sollten f�r mehr Informationen dar�ber, wie Skripte von Zopes Sicherheitszw�ngen eingeschr�nkt werden, in den Abschnitten Rollen ausf�hrbarer Objekte und Proxy-Rollen nachschlagen.

Das Zope-API

Der bequeme Zugang zum Zope-API (Application Programmer Interface; Anwendungsprogrammierer-Schnittstelle)ist einer der Hauptgr�nde, mit Skripten an Zope zu arbeiten. Das Zope-API beschreibt eingebaute Aktionen, die auf Zope-Objekten aufgerufen werden k�nnen. Sie k�nnen das Zope-API im Hilfe-System untersuchen, wie in Abbildung 8.4 gezeigt.

Dokumentation des Zope-APIs

Abbildung 8.4 Dokumentation des Zope-APIs

Angenommen, Sie m�chten ein Skript haben, das aus einer Datei, die Sie �ber ein Formular hochgeladen haben, ein Zope-Objekt in einem Ordner macht. Um das zu tun, m�ssen Sie eine Anzahl von Zope-API-Aktionen kennen. Es ist leicht genug, Dateien in Python oder Perl zu lesen, aber wenn Sie erst die Datei haben, m�ssen sie wissen, welche Aktionen aufgerufen werden m�ssen, um ein neues Datei-Objekt in einem Ordner anzulegen.

Es gibt viele andere Dinge, die Sie gern �ber ein Skript im Zope-API durchf�hren m�gen. Jede Verwaltungsaufgabe, die �ber das Web ausgef�hrt werden kann, kann auch �ber ein Skript im Zope-API getan werden. Das schlie�t das Anlegen, Ver�ndern und L�schen von Zope-Objekten ein. Sie k�nnen sogar Wartungsaufgaben wie einen Neustart von Zope oder das Packen der Zope-Datenbank durchf�hren.

Das Zope-API ist sowohl in Anhang B (API-Referenz) dokumentiert als auch in der online-Hilfe von Zope. Die API-Dokumentation zeigt Ihnen, welche Klassen von welchen anderen Klassen erworben werden. Zum Beispiel ererbt ein Ordner (Folder) vom ObjectManager. Das bedeutet, da� Ordner-Objekten alle Aktionen zur Verf�gung stehen, die im Abschnitt ObjectManager der API-Referenz aufgelistet sind.

Python-basierte Skripte benutzen

Oben in diesem Kapitel haben Sie einige Beispiele f�r Skripte gesehen. Lassen Sie uns nun einen genaueren Blick auf Skripte werfen.

Die Programiersprache Python

Python ist eine hochentwickelte, objektorientierte Programmiersprache. Das meiste von Zope ist in Python geschrieben. Viele Leute m�gen Python wegen seiner Klarheit, Einfachheit und seiner F�higkeit, gro�e Projekte zu strukturieren.

Es stehen viele Ressourcen zur Verf�gung, um Python zu erlernen. Die Website der python.org bietet eine Menge Dokumentationen einschlie�lich eines Tutorials von Pythons "Erfinder", Guido van Rossum.

Python verf�gt �ber eine reiche Auswahl an Modulen und Zus�tzen. Sie k�nnen mehr erfahren �ber die Python standard library (englisch) auf der Website der python.org.

Eine andere sehr respektierte Quelle f�r Referenzmaterial ist die Python Essential Reference (englisch) von David Beazley, ver�ffentlich von New Riders.

Python-basierte Skripte anlegen

Um ein Python-basiertes Skript anzulegen, w�hlen Sie in der "Product add list" den Punkt Script (Python) aus. Nennen Sie das Skript hallo und klicken Sie auf den Add and Edit-Button. Sie sollten jetzt die Ansicht Editihres Skriptes sehen wie in Abbildung 8.5.

Skriptbearbeitungs-Ansicht

Abbildung 8.5 Skriptbearbeitungs-Ansicht

Auf diesem Bildschirm k�nnen Sie die Parameter und Inhalte ihres Skriptes kontrollieren. Sie k�nnen Parameter f�r ihr Skript im Feld parameter list eingeben. Tippen Sie den Inhalt ihres Skriptes in das Textfeld am Fu� des Bildschirms.

Geben Sie name="Welt" im Feld parameter list ein und schreiben Sie:�

      return "Hallo %s." % name

in den Inhalt des Skripts. Das entspricht dem Folgenden in der Python-Syntax:

      def hallo(name="Welt"):
          return "Hallo %s." % name

Sie k�nnen dieses Skript nun pr�fen, indem Sie die Registerkarte Test aufrufen wie in Abbildung 8.6 gezeigt.

Ein Skript testen

Abbildung 8.6 Ein Skript testen

Lassenn sie das Feld name leer und klicken Sie auf den Button Run Script. Zope sollte "Hallo Welt" zur�ckgeben. Nun gehen Sie zur�ck und versuchen, ihren Namen in das Feld Value einzugeben und dann den Button Run Script zu klicken. Zope sollte nun "Hallo" zu Ihnen sagen.

Wenn unter Zope Skripte aufgerufen werden, bekommen Sie �ber die Variable context Zugang zu Zope-Objekten. Zum Beispiel gibt dieses Skript die Zahl der Objekte zur�ck, die in einem bestimmten Zope-Objekt enthalten sind:

      ## Script (Python) "numberOfObjects
      ##
      return len(context.objectIds())

Das Skript ruft context.objectIds() auf, um die Zahl der enthaltenen Objekte herauszufinden. Wenn Sie dieses Skript auf einem bestimmten Zope-Objekt aufrufen, wird die Kontext-Variable an den Objekt-Kontext gebunden. Wenn Sie also dieses Skript beim Besuch des URL OrdnerA/OrdnerB/numberOfObjects dieses Skript aufrufen, w�rden die Kontext-Parameter auf das Objekt OrdnerB verweisen.

Wenn Sie Logik in Python schreiben, werden Sie typischerweise Zope-Objekte suchzen wollen, andere Skripte aufrufen und Berichte zur�ckgeben. Nehemen Sie zum Beispiel an,. Sie wollen ein Arbeitsproze�-System einrichten, in dem verschiedene Zope-Objekte mit Eigenschaften belegt sind, die ihren Status anzeigen. Sie m�gen Berichte erstellen wollen, die zusammenfassen, welche Objekte sich in welchem Status befinden. Sie k�nnen Python benutzen, um Objekte zu suchen und ihre Eigenschaften abzufragen. Hier istr zumn Beispiel ein Skript, das objectsForStatus hei�t und einen Parameter namens status hat:

      ## Skript (Python) "objectsForStatus"
      ##parameters=status
      ##
      """
      Gibt alle Objekte zur�ck, die eine bestimmte Status-Eigenschaft haben.
      """
      results=[]
      for object in context.objectValues():
          if object.getProperty('status') == status:
              results.append(object)
      return results

Dieses Skript kreist durch die Sub-Objekte eines Objekts und gibt alle Sub-Objekte zur�ck, die die Eigenschaft status mit einem bestimmten Wert haben.

Sie k�nnen dieses Skript benutzen, um �ber DTML eMails zu senden. Zum Beispiel:

      

      To: 
      Subject: Objekte in Warteschleife

      Diese Objekte befinden sich in der Warteschleife und ben�tigen ihre Aufmerksamkeit:
      
         ()
      

      

Dieses Beispiel zeigt, wie Sie DTML zur Pr�sentation oder Formatierung von Berichten verwenden k�nnen, w�hrend Python die Logik durchf�hrt. Das ist ein sehr wichtiges Muster, das Sie in Zope immer wiederfinden werden.

Verarbeitung von Strings

Eine gebr�uchliche Anwendung f�r Skripte ist die Verarbeitung von Strings. Python hat eine Anzahl von Standard-Modulen f�r die String-Verarbeitung. Sie k�nnen keine gew�hnliche Ausdrucksverarbeitung mit Python-basierten Skripten machen, aber Sie haben Zugang zum Modul string. Sie haben auch von DTML aus Zugang zum Modul string, aber es ist so viel einfacher von Python aus zu benutzen. Angenommen, Sie wollen alle Erscheinungen eines bestimmten Wortes in einem DTML-Dokument �ndern. Hier ist ein Skript, ersetzeWort, das zwei Argumente akzeptiert, n�mlich Wort und Ersatz. Es wird alle Erscheinungen eines bestimmten Wortes in einem DTML-Dokument �ndern:

      ## Script (Python) "ersetzeWort"
      ##parameters=wort, ersatz
      ##
      """
      Ersetzt alle Erscheinungen eines Wortes im Quelltext eines DTML-Dokuments mit einem
      Ersatz-Wort. Rufen Sie dieses Skript auf einem DTML-Dokument auf, um es zu benutzen.
      Beachten Sie: Sie brauchen die Berechtigung "edit", um dieses Skript wirksam auf einem
      Dokument auszuf�hren.
      """
      import string
      text=context.document_src()
      text=string.replace(text, wort, ersatz)
      context.manage_edit(text, context.title)

Sie k�nnen dieses Skript aus dem Web auf einem DTML-Dokument aufrufen, um den Quelltext des Dokuments zu bearbeiten. Der URL Sumpf/ersetzeWort?wort=Alligator&ersatz=Krokodil w�rde das Skript ersetzeWort auf einem Dokument namens Sumpf aufrufen und alle Erscheinungen des Wortes Alligator mit Krokodil ersetzen.

Das Modul string, auf das Sie �ber Skripte zugreifen k�nnen, hat nicht alle M�glichkeiten, die im Standard-String-Modul vopn Python verf�gbar sind. Diese Begrenzungen wurden aus Sicherheitsgr�nden eingef�hrt. Siehe mehr Informationen zum Modul string im Anhang A.

Eine Sache, die Sie mit Skripten zu tun versucht sein k�nnten, ist, Python nach Objekten suchen zu lassen, die im Text oder den Eigenschaften ein bestimmtes Wort enthalten. Das k�nnen Sie machen, aber Zope hat ein viel besseres Instrument f�r diese Arbeit, den Catalog. Siehe Kapitel 11 (Inhalte durchsuchen und kategorisieren) f�r mehr Informationen �ber das Suchen mit Katalogen.

Mathe machen

Eine andere verbreuitete Anwendung von Skripten ist die Durchf�hrung mathematischer Berechnungen, die f�r DTML unm�glich sind. Die Module math und random geben Ihnen �ber Python Zugang zu vielen mathematischen Funktionen. Diese Module sind Standard-Python-Dienste, wie auf der Website der Python.org beschrieben.

math
Mathematischre Funktionen wie sin und cos.
random
Funktionen zur Pseudo-Zufallszahlen-Generation.

Eine interessante Funktion des Moduls random ist die Funktion choice, die eine Zufallsauswahl einer Folge von Objekten zur�ckgibt. Hier ist ein Beispiel daf�r, wie diese Funktion in einem Skript namens randomImage benutzt wird:

      ## Script (Python) "randomImage"
      ##
      """
      Sobald dieses Skript auf einem Ordner aufgerufen wird, der Bilder enth�lt,
      gibt es ein Zufallsbild zur�ck.
      """
      import random
      return random.choice(context.objectValues('Image'))

Nehmen Sie an, Sie h�tten einen Ordner Bilder, der eine Anzahl von Bildern enthielte. Sie k�nnten ein Zufallsbild aus dem Ordner auf folgende Weise in DTML anzeigen lassen:

      
        
      

Dieses DTML ruft das Skript randomImage auf dem Ordner Bilder auf. Das Ergebnis ist ein HTML-IMG-Tag, da� auf ein Zufallsbild im Ordner Bilder verweis.

Bindungsvariablen

Ein Satz spezieller Variablen wird immer dann angelegt, wenn ein Python-basiertes Skript aufgreufen wird. Diese Variablen, definiert in der Ansicht Bindings, werden von ihrem Skript benutzt, um auf andere Zope-Objekte und -Skripte zuzugreifen.

Als Voreinstellung sind die Namen jener Bindungsvariablen auf zuverl�ssige Werte gesetzt und Sie sollten sie nicht zu �ndern brauchen. Sie sind hier erl�utert, damit Sie wissen, wie jede spezielle Variable funktioniert und wie Sie diese Variablen in ihremn Skripten benutzen k�nnen.

Kontext (context)
Die Kontext-Bindung hat den Grundnamen context. Diese Variable bezieht sich auf das Objekt, auf dem das Skript aufgerufen wird.
Beh�lter (container)
Die Beh�lter-Bindung hat den Grundnamen container. Diese Variable bezieht sich auf den Ordner, in dem das Skript definiert ist.
Skript (script)
Die Skript-Bindung hat den Grundnamen script. Diese Variable bezieht sich auf das Skript selbst.
Namensraum
Die Namensraum-Bindung ist als Voreinstellung leer. Dies ist einje fortgeschrittene Variable, die Sie f�r keins der Beispiele aus diesem Buch brauchen werden. Wenn iohr Skript von einem DTML-Skript aufgerufen wird und Sie einen Namen f�r diese Bindung festgelegt haben, dann enth�lt die benannte Variable den DTML-Namensraum wie in Kapitel 8 (Variablen und fortgeschrittenes DTML) beschrieben. Wenn diese Bindung gesetzt ist, wird das Skript auch nach den Parametern im DTML-Namensraum suchen, wenn es von DTML aufgerufen wird, ohne explizit irgendwelche Argumente zu �bergeben.
Sub-Pfad
Die Sub-Pfad-Bindung hat den Grundnamen traverse_subpath. Dies ist eine fortgeschrittene Variable�, die Sie nicht f�r Beispiele in diesem Buch brauchen werden. Wenn ihr Skript traversiert wird - was bedeutet, da� andere Pfad-Elemente ihm in einem URL folgen - dann werden diese Pfad-Elemente in einer Liste von rechts nach links in dieser Variable angeordnet.

Wenn sie ihre Skripte per FTP bearbeiten, werden Sie feststellen, da� diese Bindungen in Kommentaren am oberen Ende ihrer Skript-Dateien aufgelistet sind. Zum Beispiel:

      ## Script (Python) "beispiel"
      ##bind container=container
      ##bind context=context
      ##bind namespace=
      ##bind script=script
      ##bind subpath=traverse_subpath
      ##parameters=name, alter
      ##title=
      ##
      return "Hallo %s, Sie sind %d Jahre alt." % (name, alter)

Sie k�nnen die Bindungen ihres Skripts �ndern, indem Sie diese Kommentare �ndern und dann ihr Skript hochladen.

Print-Statement-Unterst�tzung

Python-basierte Skripte haben einen besonderen Dienst, um Ihnen beim Drucken von Informationen zu helfen. Normalerweise werden Druck-Daten an die Standardausgabe gesendet und auf der Konsole dargestellt. Das ist f�r eine Server-Anwendung wie Zope unpraktisch, weil Sie die meiste Zeit hindurch keinen Zugang zur Server-Konsole haben. Skripte erlauben Ihnen sowieso das Drucken und auch, mit der speziellen Variable printed zur�ckzubekommen, was Sie gedruckt haben. Zum Beispiel:

      ## Script (Python) "printExample"
      ##
      for word in ('Zope', 'on', 'a', 'rope'):
          print word
      return printed

Diese Skript wird zur�ckgeben:

      Zope
      on
      a
      rope

Der Grund f�r den Umbruch zwischen den Worten ist, da� Python jeden gedruckten String in einer neuen0 Zeile einf�gt.

Sie m�gen das Print-Statement benutzen wollen, um einfaches Debugging in ihren Skripts durchzuf�hren. F�r komplexere Kontrolle der Ausgabe sollten sie die Dinge wahrscheinlich eher selbst verwalten, indem Sie Daten sammeln, modifizieren und sie manuell zur�ckgeben, anstatt sich auf das Print-.Statement zu verlassen.

Sicherheitseinschr�nkungen

Skripte sind in ihren Rechten eingeschr�nkt, um ihre F�higkeit zum Anrichten von Schaden zu begrenzen. Was k�nnte sch�dlich sein? Generell werden Sie durch Skripte davon abgehalten, auf private Zope-Objekte zuzugreifen, sch�dliche �nderungen an Zope-Objekten vorzunehmen, den Zope-Proze� selbst zu st�ren und auf den Server zuzugreifen, auf dem Zope l�uft. Diese Einschr�nkungen sind durch eine Ansammlung von Grenzen dessen implementiert, was ihre Skripte tun k�nnen.

Loop-Grenzen
Skripte k�nnen endlose Loops anlegen. Wenn ihr Skript eine sehr gro�e Menge an Loops durchf�hrt, wird Zope einen Fehler melden. Diese Einschr�nkung deckt alle Arten von Loops ab, eingeschlossen for- und while-Loops. Der Grund f�r diese Einschr�nkung ist die Begrenzung ihrer M�glichkeiten, Zope durch endlose Loops zu blockieren.
Import-Grenzen
Skripte k�nnen keine willk�rlichen Pakete oder Module importieren. Daher sind Sie darauf beschr�nkt, das Einheitsmodul Products.PythonScripts.standard das Modul AccessControl, die per DTML verf�gbaren Module (string, random, math, sequence) und Module zu importieren, die von den Produkt-Autoren spezifisch f�r Skripte verf�gbar gemacht worden sind. Siehe Anhang B (API-Referenz) f�r mehr Informationen �ber diese Module. Wenn Sie jedes Python-Modul importieren k�nnen wollen, benutzen Sie ein Externes Skript (external method), wie unten im Kapitel beschrieben.
Zugriffsgrenzen
Sie werden beim Zugriff auf Objekte durch die Standard-Sicherheitsregeln von Zope beschr�nkt. In anderen Worten: Der Benutzer, der Skripte ausf�hrt, wird auf Authorisierung �berpr�ft, sobald er auf Objekte zugreift. Wie bei allen ausf�hrbaren Objekten k�nnen Sie die wirksamen Rollen ver�ndern, die ein Benutzer hat, wenn er ein Skript aufruft, indem sie die Proxy-Rollen (Proxy Roles) benutzen - siehe Kapitel 7 (Benutzer und Sicherheit) f�r mehr Informationen. Au�erdem k�nnen Sie nicht auf Objekte zugreifen, deren Name mit einem Unterstrich beginnt, weil Zope diese Objekte als privat betrachtet.
Schreib-Grenzen
Generell k�nnen Sie die Attribute von Zope-Objekten mit Skripten �ndern. Sie sollten eher Skripte auf Zope-Objekten aufrufen, um sie zu �ndern, anstatt direkt die Instanz-Attribute zu �ndern.

Trotz dieser Begrenzungen k�nnte ein bestimmter Benutzer gro�e Mengen an Prozessorzeit und Speicher mit der Benutzung von Python-basierten Skripten belegen. Solche b�sartigen Skripte k�nnten durch die Benutzung gro�er Ressourcenmengen eine Art "denial of service" (DOS)-Angriff darstellen. Das sind schwer zu l�sende Probleme und DTML leidet unter demselben Mi�brauchspotential. Was DTML angeht, sollten Sie vielleicht nur vertrauenw�rdigen Leuten Zugang zu Skripten gew�hren.

Eingebaute Funktionen

Python-basierte Skripte geben Ihnen eine leicht unterschiedliche Zusammenstellung von eingebauten Funktionen als Sie sie normalerweise in Python finden.Die meisten �nderungen wurden angelegt, um Sie von der Durchf�hrung unsicherer Aktionen abzuhalten. Zum Beispiel ist die Funktion open nicht verf�gbar, was Sie vor Zugang zum Dateisystem bewahrt. Um es teilweise f�r einige fehlende Einbauten zu �ffnen, sind ein paar Extra-Funktionen verf�gbar.

Diese eingeschr�nkten Einbauten arebiten genauso wie Python-Standard-Einbauten: None, abs, apply, callable, chr, cmp, complex, delattr, divmod, filter, float, getattr, hash, hex, int, isinstance, issubclass, list, len, long, map, max, min, oct, ord, repr, round, setattr, str, tuple. F�r mehr Informationen dar�ber, was diese Einbauten tun, siehe die online-Python Documentation.

Die Funktionen range und pow sind verf�gbar und arbeiten auf dieselbe Weise, wie sie es in Standard-Python tun; dennoch sind sie beschr�nkt, um zu verhindern, da� sehr gro�e Zahlen und Sequenzen generiert werden. Diese Beschr�nkung hilft dabei, sich gegen DOS-Angriffe zu sch�tzen, wie oben beschrieben.

Zus�tzlich sind diese Funktionen verf�gbar: DateTime und test. Siehe Anhang A (DTML-Referenz) f�r mehr Informationen �ber diese Funktionen.

Schlie�lich gibt es die Funktion same_type - die den Typ von zwei oder mehr Objekten vergleicht und "wahr" zur�ckgibt, wenn sie vom selben Typ sind - um das Fehlen der Funktion type auszugleichen. Also sagen Sie nicht:

      if type(foo) == type([]):
            return "foo ist eine Liste"

um zu pr�fen, ob foo eine Liste ist, sondern stattdessen benutzen Sie die Funktion same_type, um es zu pr�fen:

      if same_type(foo, []):
            return "foo ist eine Liste"

Lassen Sie uns nun einen Blick auf Externe Skripte (External Methods) werfen, die Macht und weniger Einschr�nkungen bieten als Python-basierte Skripte.

Externe Skripte benutzen

Manchmal geraten Ihnen die durch Skripte auferlegten Sicherheitseinschr�nkungen in den Weg. Sie m�gen zum Beispiel Dateien von der Festplatte lesen oder auf das Netzwerk zugreifen oder einige fortgeschritene Bibliotheken f�r Sachen wie Regel-Ausdr�cke oder Grafikbearbeitung nutzen. In diesen F�llen werden Sie Externe Skripte (External Methods) verwenden wollen.

Um Externe Skripte anzulegen, brauchen Sie Zugang zum Dateisystem. Das macht die Bearbeitung dieser Skripte etwas beschwerlicher, da Sie sie nicht direkt in ihrem Browser bearbeiten k�nnen. Dennoch ist das Verlangen von Zugriff auf das Dateisystem des Servers eine wichtige Sicherheitskontrolle. Wenn ein Benutzer Zugriff auf das Dateisystem des Servers hat, gibt ihm das auch schon die F�higkeit, Zope zu besch�digen. Also stellt Zope sicher, da� nur bereits als vertrauensw�rdig bekannte Leute Zugang haben, wenn verlangt wird, da� uneingeschr�nkte Skripte im Dateisystem bearbeitet werden.

Uneingeschr�nkte Skripte werden als Dateien auf dem Zope-Server im Verzeichnis Extensions angelegt und bearbeitet. Alternativ k�nnen Sie uneingeschr�nkte Skripte auch in einem Verzeichnis Extensions innerhalb eines installierten Zope-Product-Verzeichnisses anlegen und bearbeiten.

Legen sie eine Datei namens Beispiel.py im Zope-Verzeichnis Extensions auf ihrem Server an. In der Datei Beispiel.py geben Sie den folgenden Code ein:

      def hallo(name="Welt"):
          return "Hallo %s." % name

Sie haben eine Python-Funktion in einem Python-Modul angelegt. Nun lassen Sie uns diese Funktion in einem Externen Skript benutzen.

Sie verwalten Externe Skripte auf dieselbe Weise wie Sie eingeschr�nkte Skripte verwalten, mit der Ausnahme da� Sie das Skript nicht selbst �ber das Web bearbeiten k�nnen. Statt Code zu bearbeiten, m�ssen Sie Zope sagen, wo es ihren Code im Dateisystem findet. Das m�ssen Sie tun, indem Sie den Namen ihrer Python-Datei und den Namen der Funktion innerhalb des Moduls spezifizieren.

Um ein Externes Skript anzulegen, w�hlen Sie External Method aus der Liste "Add" im ZMI. Sie werden zu einem Formular gef�hrt, wo Sie eine id angeben m�ssen. Geben Sie "hallo" in das Feld Id und in das Feld Function name ein und "Beispiel" in das Feld Module name, und klicken Sie den Button Add. Sie sollten nun ein Externes Skript-Objekt in ihrem Ordner sehen. Klicken Sie darauf. Sie sollten zur Ansicht Eigenschaften (Properties) ihres neuen Externen Skripts gef�hrt werden wie in Abbildung 8.7 gezeigt.

Eigenschaften-Ansicht Externer Skripte

Figure 8.7 Eigenschaften-Ansicht Externer Skripte

Testen Sie nun ihr neues Skript, indem Sie die Ansicht Test aufrufen. Sie sollten eine Begr��ung sehen. Sie k�nnen dem Skript verschiedene Namen �bergeben, indem Sie sie im URL spezifizieren. Zum Beispiel hallo?name=Spanische+Inquisition.

Dieses Beispiel ist genau dasselbe wie das Hallo-Welt-Beispiel, das Sie f�r den Gebrauch von Skripten gesehen haben. Tats�chlich bieten eingeschr�nkte Skripte eine bessere L�sung f�r einfache String-Verarbeitungsaufgaben wie diese, weil es einfacher ist, mit ihnen zu arbeiten.

Die Hauptgr�nde f�r die Benutzung uneingeschr�nkter Skripte liegen darin, auf das Dateisystem oder Netzwerk zuzugreifen oder Python-Pakete zu benutzen, die f�r eingeschr�nkte Skripte nicht verf�gbar sind.

Hier ist ein Beispiel f�r ein Externes Skript, das die Python Imaging Library (PIL) benutzt, um eine Thumbnail-Version von einem exitierenden Grafik-Objekt in einem Ordner anzulegen. Geben Sie den folgenden Code in eine Datei namens Thumbnail.py im Ordner Extensions ein:

      def makeThumbnail(self, original_id, size=200):
          """
          Stellt �ber die Id einer vorhandenen Grafik eine Thumbnail-Grafik her, wenn es auf einem
          Zope-Ordner aufgerufen wird.

          Der Thumbnail ist ein Zope-Image-Objekt, das eine verkleinert JPG-Anzeige der Original-
          Grafik ist. Er hat eine Eigenschaft 'original_id', die auf die Id der Grafik in
          Originalgr��e gesetzt ist.
          """

          from PIL import Image
          from StringIO import StringIO
          import os.path

          # lege eine Thumbnail-Datei an
          original_image=getattr(self, original_id)
          original_file=StringIO(str(original_image.data))
          image=Image.open(original_file)
          image=image.convert('RGB')
          image.thumbnail((size,size))
          thumbnail_file=StringIO()
          image.save(thumbnail_file, "JPEG")
          thumbnail_file.seek(0)

          # lege eine Id f�r den Thumbnail an
          path, ext=os.path.splitext(original_id)
          thumbnail_id=path + '.thumb.jpg'

          # wenn es einen alten Thumbnail gibt, l�sche ihn
          if thumbnail_id in self.objectIds():
              self.manage_delObjects([thumbnail_id])

          # lege das Zope-Image-Objekt an
          self.manage_addProduct['OFSP'].manage_addImage(thumbnail_id,
                                                         thumbnail_file,
                                                         'thumbnail image')
          thumbnail_image=getattr(self, thumbnail_id)

          # setze die Eigenschaft 'originial_id'
          thumbnail_image.manage_addProperty('original_id', original_id, 'string')

Sie m�ssen die PIL installiert haben, damit das Beispiel funktioniert. Siehe die PythonWorks-Website f�r mehr Informationen �ber die PIL. Um diesen Code zu benutzen, legen Sie ein Externes Skript mit dem Namen makeThumbnail an, das die Funktion makeThumbnail im Modul Thumbnail benutzt.

Nun haben sie ein Skript, das eine Thumbnail-Grafik anlegen wird. Sie k�nnen es auf einem Ordner mit einem URL wie ImageFolder/makeThumbnail?original_id=Pferd.gif aufrufen. Das w�rde eine Thumbnail-Grafik anlegen, die Pferd.thumb.jpg hei�t.

Sie k�nnen ein Skript benutzen, um �ber alle Grafiken in einem Ordner zu loopen und Thumbnail-Grafiken von ihnen anzulegen. Legen Sie ein Skript namens makeThumbnails an:

      ## Skript (Python) "makeThumbnails"
      ##
      for image_id in context.objectIds('Image'):
          context.makeThumbnail(image_id)

Es wird �ber alle Grafiken in einem Ordner loopen und f�r jede einen Thumbnail anlegen.

Nun rufen sie dieses Skript auf einem Ordner mit Grafiken darin auf. Es wird eine Thumbnail-Grafik f�r jede enthaltene Grafik anlegen. Versuchen Sie, das Skript makeThumbnails noch einmal auf diesem Ordner aufzurufen und Sie werden feststellen, da� es Thumbnails von ihren Thumbnails hergetsellt hat. Das ist nicht gut. Sie m�ssen das Skript makeThumbnails �ndern, damit es vorhandene Thumbnail-Grafiken erkennt und keine Thumbnails von ihnen mehr anlegt. Weil alle Thumbnails die Eigenschaft original_id haben, k�nnen Sie als eine Unterscheidungsmethode zwischen Thumbnails und normalen Grafiken gegen diese Eigenschaft pr�fen:

      ## Skript (Python) "makeThumbnails"
      ##
      for image in context.objectValues('Image'):
          if not image.hasProperty('original_id'):
              context.makeThumbnail(image.getId())

L�schen Sie alle Thumbnail-Grafiken in ihrem Ordner und versuchen sie, ihr nachbearbeitetes Skript makeThumbnails auf dem Ordner aufzurufen. Jetzt scheint es richtig zu funktionieren.

Nun k�nnen Sie ihr Skript und das Externe Skript mir ein wenig DTML zusammenkleben. Legen Sie ein DTML-Skript an, das displayThumbnails hei�t:

      

      
        
      

      

Thumbnails


Wenn Sie dieses DTML-Skript auf einem Ordner aufrufen, wird es durch alle Grafiken in dem Ordner loopen, alle Thumbnail-Grafiken anzeigen und Sie mit dem Orginal verlinken wie in Abbildung 8.8 gezeigt.

Thumbnail-Grafiken anzeigen

Abbildung 8.8 Thumbnail-Grafiken anzeigen

Dieses DTML-Skript schlie�t auch ein Formular ein, das Ihnen erlaubt, die Thumbnail-Grafiken zu aktualisieren. Wenn sie in ihrem Ordner Grafiken hinzuf�gen, l�schen oder �ndern, k�nnen Sie dieses Formular nutzen, um ihre Thumbnails zu aktualisieren.

Dieses Beispiel zeigt, wie Skripte, Exterme und DTML-Skripte, gemeinsam benutzt werden. Python sorgt f�r die Logik, w�hrend DTML die Darstellung �bernimmt. Ihre Externen Skripte gehen mit externen Paketen um, w�hrend ihre Skripte die einfache Verarbeitung von Zope-Objekten durchf�hren.

XML-Verarbeitung mit Externen Skripten

Sie k�nnen Externe Skripte benutzen, um damit dammich fast alles zu tun. Eine interessante Sache, die Sie machen k�nnen, ist die Kommunikation �ber XML. Sie k�nnen mit Externen Skripten XML generieren und verarbeiten.

Zope versteht schon ein paar XML-Nachrichten wie etwa XML-RPC und WebDAV. W�hrend Sie Web-Anwendungen schreiben, die mit anderen Systemen kommunizieren, m�gen sie die F�higkeit haben wollen, XML-Nachrichten zu erhalten. Sie k�nnen XML auf eine Anzahl von Wegen erhalten: Sie k�nnen XML-Dateien aus dem Dateisystem oder �ber das Netzwerk lesen, oder Sie k�nnen Skripte definieren, die XML-Argumente �bernehmen, die von entfernten Systemen aufrufbar sind.

Wenn Sie eine XML-Nachricht erhalten haben, m�ssen sie das XML verarbeiten, um herauszufinden, was es bedeutet und wie darauf zu reagieren ist. Lassen Sie uns einen schnellen Blick darauf werfen, wie Sie XML mit Python manuell parsen k�nnen. Angenommen, Sie wollen ihre Web-Anwendung an einen Jabber-Chatserver anbinden. Sie m�gen Benutzern erlauben wollen, Sie zu benachrichtigen und dynamische Antworten zu erhalten, die auf dem Status ihrer Web-Anwendung gr�nden. Nehmen Sie zum Beispiel an, Sie wollen Benutzern erlauben, mit Instant Messaging den Status von Tieren zu �berpr�fen. Ihre Anwendung sollte etwa so auf XML-Instant Messaging antworten:

      
        
        F�tterungsstatus Affen
        
      

Sie k�nnten den Inhalt der Nachricht auf Kommandos scannen, ein Skript aufrufen und Antworten wie diese zur�ckgeben:

      
        
        Die Affen wurden zuletzt um 3.15 Uhr gef�ttert.
        
      

Hier ist eine Skizze davon, wie Sie diese XML-Messaging-Einheit mit einem Externen Skript in ihre Web-Anwendung implementieren k�nnten:

      # Benutzt Python 2.x Standard-XML-Verarbeitungspakete. Siehe
      # http://www.python.org/doc/current/lib/module-xml.sax.html fuer
      # Informationen ueber Pythons SAX(Simple API for XML)-Unterstuetzung.
      # Wenn Sie Python 1.5.2 benutzen, koennen sie das PyXML-Paket erhalten.
      # Siehe http://pyxml.sourceforge.net f�r mehr Informationen �ber PyXML.

      from xml.sax import parseString
      from xml.sax.handler import ContentHandler

      class MessageHandler(ContentHandler):
          """
          SAX message handler class

          Loest eine Nachricht nach oder von ihrem Nachrichtenkoerper auf
          """

          inbody=0
          body=""

          def startElement(self, name, attrs):
              if name=="message":
                  self.recipient=attrs['to']
                  self.sender=attrs['from']
              elif name=="body":
                  self.inbody=1

          def endElement(self, name):
              if name=="body":
                  self.inbody=0

          def characters(self, content):
              if self.inbody:
                  self.body=self.body + content

      def receiveMessage(self, message):
          """
          Aufgerufen von einem Jabber-Server
          """
          handler=MessageHandler()
          parseString(message, handler)

          # rufe ein Skript auf, das einen Antwort-String auf einen
          # bestimmten Nachrichtenkoerper-String zur�ckgibt
          response_body=self.getResponse(handler.body)

          # lege eine XML-Antwortnachricht an
          response_message="""
            
              
              %s
              
            """ % (handler.sender, handler.recipient, response_body)

          # gib sie zurueck an den Server
          return response_message

Das Externe Skript receiveMessage benutzt Pythons SAX(Simple API for XML)-Paket, um die XML-Nachricht zu parsen. Die Klasse MessageHandler erh�lt R�ckrufe, w�hrend Python die Nachricht parst. Der Handler speichert die Informationen, die ihn interessieren. Das Externe Skript benutzt die Handler-Klasse, indem es eine Instanz von ihr anlegt und �bergibt sie an die Funktion parseString. Dann findet es eine Antwort-Nachricht heraus, indem es mit dem Nachrichtenk�rper getResponse aufruft. Das Skript getResponse (hier nicht gezeigt) scannt den Nachrichtenk�rper wahrscheinlich auf Kommandos, durchsucht den Status der Web-Anwendung und gibt eine Antwort zur�ck. Das Skript receiveMessage legt dann eine XML-Nachricht an, indem es die Antwort und die Absenderinformationen benutzt und gibt sie zur�ck.

Der entfernte Server w�rde dieses Externe Skript benutzen, indem das Skript receiveMessage mit dem Standard-HTTP POST-Kommando aufgerufen wird. Vo�la, Sie haben einen brauchbaren XML-Chatserver aufgesetzt, der �ber HTTP l�uft.

Fallstricke Externer Skripte

W�hrend Sie grunds�tzlich in dem, was sie in einem Externen Skript tun k�nnen, unbeschr�nkt sind, gibt es immer noch einige Dinge, die schwer zu tun sind.

W�hrend ihr Python-Code tun kann, was er m�chte, m�ssen sie bei der Arbeit mit im Rahmen von Zope dessen Regeln respektieren. Die Programmierung des Zope-Frameworks ist ein zu anspruchsvoller Punkt , um ihn hier zu diskutieren, und es gibt ein paar Dinge, denen sie sich bewu�t sein sollten.

Probleme k�nnen auftreten, wenn Sie Instanzen ihrer eigenen Klassen an Zope �bergeben und erwarten, da� sie funktionieren wie Zope-Objekte. Sie k�nnen beispielsweise in einem Externen Skript keine Klasse definieren und sie dann als Attribut einem Zope-Objekt zuweisen. Das macht Probleme mit Zopes Dauermaschinerie. Sie k�nnen auch nicht einfach Instanzen ihrer eigenen Klassen an DTML oder Skripte �bergeben. Der Knackpunkt ist hier, da� ihre Instanzen keine Zope-Sicherheitsinformationen haben. Sie k�nnen nach Herzenslust ihre eigenen Klassen und Instanzen definieren und benutzen, aber erwarten Sie nicht, da� Zope sie direkt benutzt. Beschr�nken sie sich darauf, einfache Python-Strukturen wie Strings, W�rterb�cher und Listen oder Zope-Objekte zur�ckzugeben.

Perl-basierte Skripte verwenden

Perl-basierte Skripte erlauben ihnen, Zope in Perl zu skripten. Wenn Sie Perl m�gen, und Python nicht erlernen wollen, um Zope zu benutzen, sind diese Skripte f�r Sie. Um Perl-basierte Skripte zu verwenden, k�nnen Sie all ihre Lieblings-Perl-Module benutzen und Zope behandeln wie eine Ansammlung von Perl-Objekten.

Die Programmiersprache Perl

Perl ist eine hochentwickelte Skriptsprache wie Python. Grob betrachtet sind Perl und Python sehr �hnliche Sprachen, sie haben �hnlich primitive Datenkonstrukte und verwenden �hnliche Programmierkonstrukte.

Perl ist eine popul�rew Sprache f�r Internet-Skripting. In den fr�hen Tagen des CGI-Skriptings waren Perl und Python praktisch Synonyme. Perl ist immer noch die herrschende Internet-Skripting-Sprache.

Perl hat eine sehr reiche Sammlung von Modulen, um fast jede Computeraufgabe zu erledigen. CPAN (Comprehensive Perl Archive Network) ist der beste F�hrer zu Perl-Ressourcen.

Perl-basierte Zope-Skripte sind zum Herunterladen bei ActiveState verf�gbar. Perl-basierte Skripte verlangen, da� Sie Perl und ein paar andere Pakete installiert haben, und wie diese Dinge installiert werden, ist jenseits des Horizonts dieses Buches. Schlagen Sie in der Dokumentation nach, die Sie bei den Perl-basierten Skripten vom obigen URL finden. Es gibt auch mehr Informationen, die Andy McKay auf der Zope.org bereitgestellt hat.

Perl-basierte Skripte anlegen

Perl-basierte Skripte sind Python-basierten Skripten ziemlich �hnlich. Beide haben Zugriff auf Zope-Objekte und werden auf �hnliche Weise aufgerufen. Hier ist das Hallo-Welt-Programm in Perl:

      my $name=shift;
        return "Hallo $name.";

Lassen Sie uns einen Blick auf ein komplexeres Beispiels-Skript von Monty Tailor werfen. Es benutzt das LWP::UserAgent-Paket, um den URL des t�glich erscheinenden Dilbert-Comic aus dem Netz zu erhalten. Legen sie ein Perl-basiertes Skript namens get_dilbert_url mit diesem Code an:

      use LWP::UserAgent;

      my $ua = LWP::UserAgent->new;

      # hole die Dilbert-Seite
      my $request = HTTP::Request->new('GET','http://www.dilbert.com');
      my $response = $ua->request($request);

      # sieh nach dem Grafik-URL im HTML
      my $content = $response->content;
      $content =~ m,(/comics/dilbert/archive/images/[^"]*),s;

      # gib den URL zur�ck
      return $content

Sie k�nnen sich den t�glichen Dilbert-Comic anzeigen lassen, wenn Sie dieses Skript �ber DTML aufrufen, wo das Skript innerhalb eines HTML-IMGTags aufgerufen wird:

      

Dennoch gibt es ein Problem mit diesem Code. Jedes Mal, wenn Sie den Cartoon anzeigen lassen, mu� Zope eine Netzverbindung aufbauen. Das ist ineffizient und verschwenderisch. Es w�re viel besser, den aktuellen URL des Dilbert-Comics nur einmal t�glich herauszufinden.

Hier ist ein Skript namens cached_dilbert_url, das die Situation verbessert, indem mit Hilfe einer Eigenschaft dilbert_url_date beobachtet wird, wann zum letzten Mal der Dilbert-URL geholt worden ist:

      my $context=shift;
      my $date=$context->getProperty('dilbert_url_date');

      if ($date==null or $now-$date > 1){
          my $url=$context->get_dilbert_url();
          $context->manage_changeProperties(
            dilbert_url => $url
            dilbert_url_time => $now
          );
      }
      return $context->getProperty('dilbert_url');

Dieses Skript benutzt zwei Eigenschaften: dilbert_url und dilbert_url_date. Wenn der URL zu alt wird, wird ein neuer geholt. Sie k�nnen dieses Skript von DTML aus genauso benutzen wie das Original-Skript:

      

Sie k�nnen Perl und DTML zusammen benutzen, um ihre Logik und ihre Darstellung zu kontrollieren.

Perl-basierte Skript-Sicherheit

Wie DTML und Python-basierte Skripte verhindern auch Perl-basierte Skripte im Zope-Sicherheitssystem, da� sie irgendetwas tun, was Sie nicht d�rfen. Skript-Sicherheit ist in beiden Programmiersprachen �hnlich, aber es gibt ein paar Perl-spezifische Zw�nge.

Erstens erlaubt Ihnen das Sicherheitssystem nicht, einen Ausdruck in Perl mit dem Befehl eval zu behandeln. Beachten sie zum Beispiel dieses Skript:

      my $context = shift;
      my $input = shift;

      eval $input

Dieser Code nimmt ein Argument und evaluiert es in Perl. Das bedeutet, Sie k�nnten dieses Skript von - sagen wir - einem HTML-Formular aufrufen und die Inhalte eines der Formularelemente evaluieren. Das ist nicht erlaubt, weil das Formularelement b�sartigen Code enthalten k�nnte.

Perl-basierte Skripte k�nnen auch keine neuen Variablen an irgendein Objekt zuweisen, au�er lokale Variablen, die Sie mit my erkl�ren.

DTML gegen Python gegen Perl

Zope gibt Ihnen viele Weg, um Skripte anzulegen. F�r kleine Skript-Aufgaben macht die Wahl zwischen Python, Perl oder DTML wahrscheinlich keinen gro�en Unterschied. F�r gr��ere, Logik-orientierte Aufgaben sollten sie Python oder Perl benutzen. Sie sollten die Sprache w�hlen, die Ihnen am bequemsten ist. Nat�rlich k�nnte ihr Chef in dieser Angelegenheit mitreden wollen.

Nur zum Vergleich ist hier ein einfaches Skript, vorgeschlagen von Gisle Aas, dem Autor Perl-basierter Skripte, in drei verschiedenen Programmiersprachen.

In DTML:

      
        : 
      
      done

In Python:

      for item in context.objectValues():
          print "%s: %s" % (item.getId(), item)
      print "done"
      return printed

In Perl:

      my $context = shift;
      my @res;

      for ($context->objectValues()) {
          push(@res, join(": ", $_->getId(), $_));
      }
      join("\n", @res, "done");

Trotz der Tatsache, da� Zope in Python implementiert ist, folgt es der Perl-Philosophie, da� es mehr als einen Weg gibt, es zu tun.

Fern-Skripting und Netzwerkdienste

Webserver werden benutzt, um Inhalte an Software-Clients auszuliefern; gew�hnlich Leute, die Webbrowser-Software benutzen. Der Software-Client kann also ein anderer Computer sein der ihren Webserver benutzt, um auf irgendeine Art von Dienst zuzugreifen.

Weil Zope Objekte und Skripte im Web darstellt, kann es benutzt werden, um ein m�chtiges, gut organisiertes, sicheres Web-API f�r andere entfernte Netzwerk-Anwendungsclients zur Verf�gung zu stellen.

Es gibt zwei �bliche Wege, Zope aus der Entfernung zu skripten. Der erste Weg ist, ein simples Fern-Proze�aufruf-Protokoll namens XML-RPC zu benutzen. XML-RPC wird benutzt,um einenen Proze� auf einer entfernten Maschine auszuf�hren und ein Ergebnis auf der lokalen Maschine zu erhalten. XML-RPC wurde aufgebaut, um sprachneutral zu sein und in diesem Kapitel werden sie Beispiele in Python, Perl und Java sehen.

Der zweite �bliche Weg, um Zope aus der Entfernung zu skripten, l�uft �ber irgendeinen HTTP-Client, der mit einem Skript automatisiert werden kann. Viele Sprachbibliotheken enthalten simple, skriptbare HTTP-Clients und es gibt viele Programme, die Sie HTTP von der Kommandozeile aus skripten lassen.

XML-RPC benutzen

XML-RPC ist ein einfacher Fern-Proze�aufruf-Mechanismus, der �ber HTTP arbeitet und XML benutzt, um Informtionen zu verschl�sseln. XML-RPC-Clients sind f�r viele Programmiersprachen implementiert worden, eingeschlossen Python, Perl, Java, JavaScript und TCL.

Tiefere Informationen zu XML-RPC sind auf der XML-RPC-Website zu finden.

Alle Zope-Skripte, die von URLs aufgerufen werden k�nnen, k�nnen �ber XML-RPC aufgerufen werden. Grunds�tzlich bietet XML-RPC ein System, um Argumente zu Skripten zu ordnen, die vom Web aus aufgerufen werden k�nnen. Wie Sie oben gesehen haben, bietet Zope seine eigenen Ordnungskontrollen, die Sie �ber HTTP nutzen k�nnen. XML-RPC und Zopes eigenes Ordnen erf�llen zum gro�en Teil dasselbe. Der Vorteil von XML-RPC-Ordnen liegt darin, da� es ein breit unterst�tzter Standard ist, der auch das Ordnen von R�ckgabe-Werten wie von Argument-Werten unterst�tzt.

Hier ist ein versponnenes Beispiel, das zeigt, wie durch entfernes Skripten �ber XML-RPC eine Massenentlassung von Pf�rtnern ausgel�st werden kann.

Hier ist der Code in Python:

      import xmlrpclib

        server = xmlrpclib.Server('http://www.zopezoo.org/')
        for employeeID in server.JanitorialDepartment.personnel():
            server.fireEmployee(employee)

In Perl:

      use Frontier::Client;

        $server = Frontier::Client->new(url => "http://www.zopezoo.org/");

        $employees = $server->call("JanitorialDepartment.personnel");
        foreach $employee ( @$employees ) {

          $server->call("fireEmployee",$server->string($employee));

        }

In Java:

      try {
            XmlRpcClient server = new XmlRpcClient("http://www.zopezoo.org/");
            Vector employees = (Vector) server.execute("JanitorialDepartment.personnel");

            int num = employees.size();
            for (int i = 0; i < num; i++) {
                Vector args = new Vector(employees.subList(i, i+1));
                server.execute("fireEmployee", args);
            }

        } catch (XmlRpcException ex) {
            ex.printStackTrace();
        } catch (IOException ioex) {
            ex.printStackTrace();
        }

In Wirklichkeit wird das obige Beispiel vielleicht nicht korrekt laufen, weil sie h�chstwahrscheinlich das Skript fireEmployee sch�tzen wollen. Das bringt das Thema Sicherheit mit XML-RPC auf. XML-RPC hat keinerlei eigene Sicherheitsversorgung; dennoch kann es - weil es unter HTTP l�uft - existierende HTTP-Sicherheitskontrollen �bernehmen. Tats�chlich behandelt Zope eine XML-RPC-Anfrage genau wie eine normale HTTP-Anfrage, mit R�cksicht auf die Sicherheitskontrollen. Das bedeutet, da� Sie in ihrer XML-RPC-Anfrage eine Authentifizierung bieten m�ssen, damit Zope Ihnen Zugriff auf gesch�tzte Skripte gew�hrt. Der Python-Client unterst�tzt zum Zeitpunkt der Niederschrift dieses Textes keine Kontrolle von HTTP-Authentifizierungs-Headern. Dabei ist es ein ziemlich trivialer Zusatz. Zum Beispiel schlie�t ein Artikel auf XML.com, Internet Scripting: Zope and XML-RPC, ein Patch f�r Pythons XML-RPC-Unterst�tzung ein, wo gezeigt wird, wie ihrem XML-RPC-Client HTTP-Authentifizierungs-Header hinzugef�gt werden k�nnen.

Fern-Skripten mit HTTP

Jeder HTTP-Client kann zum Fern-Skriten von Zope verwendet werden.

Auf UNIX-Systemen haben sie eine Anzahl von Werkzeugen zur Verf�gung, um Zope fernzuskripten. Ein einfaches Beispiel ist, wget zu benutzen, um die URLs von Zope-Skripten aufzurufen und cron, um die Skript-Aufrufe zu planen. Stellen Sie sich beispielsweise vor, Sie h�tten ein Zope-Skript, das die L�wen f�ttert und Sie w�rden es gern jeden Morgen aufrufen. Sie k�nnen wget benutzen, um das Skript etwa so aufzurufen:

      $ wget --spider http://www.zopezope.org/Loewen/fuettern

Die Option spider sagt wget, da� es die Antwort nicht als Datei speichern soll. Nehmen Sie an, ihr Skript ist gesch�tzt und verlangt Authentifizierung. Sie k�nnen ihren Benutzernamen und das Pa�wort mit wget �bergeben, um auf gesch�tzte Skripte zuzugreifen:

      $ wget --spider --http_user=ZooKeeper --http_pass=SecretPhrase
      http://www.zopezope.org/Loewen/fuettern

Lassen Sie uns nun cron benutzen, um dieses Kommando jeden Morgen um 8.00 Uhr aufzurufen. Bearbeiten sie ihre crontab-Datei mit dem Kommando crontab:

      $ crontab -e

Dann f�gen sie eine Zeile hinzu, um wget jeden Tag um 8.00 Uhr aufzurufen:

      0 8 * * * wget -v --spider --http_user=ZooWaerter --http_pass=SecretPhrase
      http://www.zopezoo.org/Loewen/fuettern

Der einzige Unterschied zwischen der Benutzung von cron und dem manuellen Aufruf von wget ist, da� Sie den Schalter v benutzen sollten, wenn Sie cron benutzen, weil Sie die Ausgabe des Kommandos wget nicht interssiert.

Lassen sie uns f�r unser Schlu�beispiel richtig pervers werden. Weil Netzwerkf�higkeit in so viele verschiedene Systeme eingebaut ist, ist es einfach, einen Kandidaten zu finden, f�r den das Skripten von Zope eher unwahrscheinlich ist. Wenn Sie einen internetf�higen Toaster h�tten, k�nnten Sie auch damit wahrscheinlich Zope skripten. Lassen sie uns Microsoft Word als unseren Beispiels-Zope-Client nehmen. Alles Notwendige besteht darin, sich mit Word darauf zu einigen, da� es einen URL kitzelt.

Der einfachste Weg, Zope mit Word zu skripten ist es, Word zu sagen, es soll ein Dokument �ffnen und dann - wie in Abbildung 8.9 gezeigt - einen Zope-Skript-URL als Dateinamen einzugeben.

Einen URL mit Microsoft Word aufrufen

Abbildung 8.9 Einen URL mit Microsoft Word aufrufen

Word wird dann den URL laden und die Ergebnisse des Zope-Skript-Aufrufs zur�ckgeben. Trotz der Tatsache, da� Word Sie auf diese Weise keine Argumente POSTen l��t, k�nnen sie GET-Argumente �bergeben, indem Sie sie als Teil des URLs eingeben.

Sie k�nnen dieses Verhalten sogar kontrollieren, indem sie Words eingebautes Visual Basic-Scripting benutzen. Hier ist zum Beispiel ein Visual Basic-Fragment, das Word dazu bringt, ein neues Dokument zu �ffnen, indem es einen Zope-Skript-URL benutzt:

      Documents.Open FileName:="http://www.zopezoo.org/LoewenGehege/waschen?seife_verwenden=1&wasser_temp=heiss"

Sie k�nnten Visual Basic nutzen, um Zope-Skript-URLs auf viele verschiedene Weise aufzurufen.

Zopes URL zur �bersetzung per Skript-Aufruf ist der Schl�ssel zum Fern-skripten. Weil Sie Zope so einfach mit simplen URLs kontrollieren k�nnen, k�nnen Sie Zope auch einfach mit fast jedem netzwerkf�higen System skripten.

Schlu�

Zope bietet Skripten mit Python und Perl. Mit Skripten k�nnen Sie Zope-Objekte kontrollieren und ihre Anwendungslogik, Daten und Darstellung verbinden. Sie k�nnen auch ernsthafte Programmierungsaufgaben wie Grafik-Verarbeitung und XML-Parsing durchf�hren.

Im n�chsten Kapitel werden sie etwas �ber den ZCatalog lernen, Zopes eingebaute Suchmaschine.