Programmatisch einen Zope3-Ordner in eine Site umwandeln

Eine Site enthält einen "SiteManager" und kann damit lokale Utilities beinhalten. Aus einem Ordner im ZMI eine Site zu machen, sind nur ein paar Klicks, programmatisch ist es aber auch nicht viel schwerer.

by Michael Howitz posted at 2007-05-15 16:10 last modified 2007-05-15 16:10

Angenommen, immer wenn eine Instanz der Klasse MySite angelegt wird, soll daraus eine Site gemacht werden. Es wird weiterhin angenommen, dass MySite das Interface IMySite implementiert.
Man abonniert zuerst per ZCML den ObjectAddedEvent:

<subscriber
for="zope.app.container.interfaces.IObjectAddedEvent"
handler=".eventhandler.onObjectAdded"
/>

Wir legen nun eine Datei eventhandler.py an und definieren dort die Funktion onObjectAdded, mit folgendem Inhalt:

from mypackage import IMySite
import zope.app.appsetup.bootstrap
import zope.app.component.interfaces
import zope.app.component.site
import zope.app.component.hooks
import zope.app.intids
import zope.app.intids.interfaces


def onObjectAdded(event):
if IMySite.providedBy(event.object):
# Macht aus object eine Site, wenn es noch keine ist
if not zope.app.component.interfaces.ISite.providedBy(event.object):
site_manager = zope.app.component.site.LocalSiteManager(event.object)
event.object.setSiteManager(site_manager)

# Wenn in der Site lokale Utilities installiert werden sollen, die
# sich auf den thread-globalen Context verlassen, dann ist dieser
# temporär zu setzen, damit in der richtigen, nämlich der neuen
# Site gesucht wird.
try:
old_site = zope.app.component.hooks.getSite()
zope.app.component.hooks.setSite(event.object)

 # Hier kann man jetzt die Utilities installieren.
# z.B. ein IntId-Util
zope.app.appsetup.bootstrap.ensureUtility(event.object,
zope.app.intid.interfaces.IIntIds, '', zope.app.intid.IntIds)

finally:
# Zum Schluss wird der alte Zustand wieder hergestellt.
zope.app.component.hooks.setSite(old_site)

Wenn der ObjectAddedEvent ausgelöst wird, ist das Objekt schon in seinem Container eingebettet und hat selbst Kontext. Nur in der thread-globalen Variablen steht noch der alte Wert für die Site, so dass neu installierte Utilities nicht gefunden werden.

Category(s)
Zope 3
The URL to Trackback this entry is:
http://blog.gocept.com/programmatisch-einen-zope3-ordner-in-eine-site-umwandeln/tbping