Produkte installieren
Vorgang
- Verzeichnisse anlegen [1], [2]
$ cd $ZOPE
$ mkdir AddedProducts
$ mkdir TestingProducts
$ cd lib/python/Products
$ mkdir AddProductsDir
Damit werden die drei Verzeichnisse $ZOPE/AddedProducts (für neue Produkte), $ZOPE/TestingProducts (für Produkte, die man testen will) und $ZOPE/lib/python/Products/AddProductsDir angelegt - Script anlegen
$ZOPE/lib/python/Products/AddProductsDir/__init__.py
import Products
import sys, os
*addingDirs = [$ZOPE/AddedProducts
, '$ZOPE/TestingProducts']*
for DIR in addingDirs:
if not os.path.exists(DIR): continue
for PATH in Products.__path__:
PATH = os.path.abspath(PATH)
if DIR in (PATH, PATH + os.sep): break
else:
Products.__path__.append(DIR)
- Zope neu starten
Unter Debian: $ zopectl force-reload
Unter anderen Linux-Distributionen muss man Zope komplett herunterfahren und dann neu starten. Ein $ zopectl restart reicht zumindest unter Debian nicht.
Erklärung
Products.__path__ enthält eine Dictionary mit allen Verzeichnissen, in denen nach Zope-Produkten gesucht werden soll (siehe dazu z.B. $ZOPE/lib/python/OFS/Application.py Funktion get_products()). Durch import Products wird die Klasse Products in den lokalen Namensraum importiert. append() fügt dem Dictionary ein weiteres Element zu.
Die beiden for-Schleifen und die Überprüfungen im Code sind nicht zwingend notwendig, verhinderen aber mögliche Fehler. Die äußere for-Schleife durchläuft das Dictionary, welches die Pfade enthält, die man hinzufügen will. Die erste Überprüfung läßt die for-Schleife zum nächsten Element springen, wenn das Verzeichnis nicht existiert. Die innere for-Schleife überprüft, ob der Pfad schon in Products.__path__ ist, damit ein Pfad nicht ein zweites Mal hinzugefügt wird. Erst wenn dieser Test positiv verläuft, wird der Pfad zu Products.__path__ hinzugefügt, ansonsten wird das nächste Element der äußeren for-Schleife angesprungen.
Dies alles hätte man theoretisch in jeder beliebigen Datei machen können, die von Zope ausgeführt wird. Im Products-Verzeichnis muss man aber keine Datei patchen, da jedes Unterverzeichnis von Zope automatisch importiert wird und die darin enthaltene __init__.py ausgeführt wird.
Vielleicht wundern sich einige Anfänger, wieso Products.__path__ die Methode append() besitzt. Das liegt daran, das es sich bei __path__ um ein Dictionary handelt und jedes Dictionary eingebaute Funktionen wie eben append() besitzt.
Da in Python grundsätzlich Verweise (entspricht Pointern in C) und nicht Kopien von Variablen wie z.B. in PHP gemacht werden, reicht es, die Klasse Products zu importieren, um sie dann im gesamten Kontext zu ändert. So etwas nennt man im übrigen im Zope Jargon "Monkey Patch".
Gotchas
- Wenn das mit Products.__path__.append() deklarierte Verzeichnis nicht existiert oder Zope dieses Verzeichnis nicht lesen kann, dann startet Zope nicht mehr (Panic (300) z2 Startup exception). Dies wird durch if not os.path.exists(DIR): continue verhindert.
Quellen
Basiert auf: Define additional Products directories
Überprüfungsroutinen aus dem Python Cookbock von O'Reilly (4.22 , Page 148)
Konventionen
[1] $ZOPE entspricht den Verzeichnis, in dem die ZOPE-Binaries und Scripte abgelegt sind. Bitte diesen Zeichenkette bei der Eingabe durch den entsprechenden Verzeichnisnamen ersetzen. Unter Debian entspricht das /usr/lib/zope, unter SuSE IMHO /opt/zope.
[2] Befehle, die in einer Shell (Eingabeaufforderung) eingegeben werden, sind wie *$ Befehl" formatiert. Das bedeutet, das man an der Eingabeaufforderung nach dem $
bzw. #
die Worte "Befehl" eingibt und dann drückt. Das $
nicht mit eingeben!
[3] Die Namen von Funktionen, Klassen und Dateien außerhalb von Befehlen werden fett geschrieben.
[4] Dateiinhalte werden kursiv geschrieben.