[Zope] Running scripts after zope startup

Josef Meile jmeile at hotmail.com
Wed Oct 25 12:26:24 EDT 2006


I'm working in a configuration module for other products I'm developing. 
The idea is that the user first has to make an instance from this 
product, then define there where the other products instances will be 
created, what header, footer, and style sheets they will use, etc..

The configuration product has to detect which of my products are 
installed, then load some xml Formulator forms. I just created a 
registry class that to do the detection process:

import Products

JM_PRODUCTS = ['JMConfigurator','JMPlace','JMPerson']
class JMRegistry:
   def __init__(self):
     availableJMProducts = {}

     for productName in JM_PRODUCTS:
       productModule = getattr(Products,productName,None)
       if productModule is not None:
         availableJMProducts[productName] = productModule
     self._AvailableJMProducts = availableJMProducts

   """More methods come here

JM_Registry = JMRegistry()

The problem here is that if I import this in the initialize method of my 
configuration product, the _AvailableJMProducts dictionary is empty 
because at this point the other products hasn't been jet registered by zope.

I just thaught about something like the StartupScripts products does: 
running this after zope starts. This is achieved as follows:

__init__.py from my product:

from Products.JMUtils import JMRegistry
def initialize(context):
   #Some registration code comes here

   import ThreadedAsync.LoopCallback

JM_PRODUCTS = ['JMConfigurator','JMPlace','JMPerson']
class JMRegistry:
   #Class definition is the same as above

JM_Registry = None
def createRegistry(args *):
   JM_Registry = JMRegistry()

Unfortunatelly, after seeing the zope source code, I saw that the 
ThreadedAsync is only used by ZEO, which I'm not using.

My workaround was to call this in the __setstate__ method of my 
configuration product as follows:

from Products.JMUtils import JMRegistry

class JMConfigurator(ZCatalog):
   #__init__ and other methods come here

   def __setstate__(self, state):

     if JMRegistry.JM_REGISTRY is None:
       JMRegistry.JM_REGISTRY = JMRegistry.JMRegistry()

       #After having initialized the registry, I can call the methods to
       #load the Formulator forms

This works well, but I think it is not the better place to define this 
kind of things. Is there any better way of achieving the task?


More information about the Zope mailing list