How-to: Writing setup handlers for Products.GenericSetup

If your product subclasses existing tools or provides new tools (or new sub-object classes), it might need to supply its own setup handlers in order to support exporting / importing tool settings using GenericSetup.

Step 1:

Identify those classes in your product that need their own setup handlers. In theory you don’t need your own handlers for classes which implement a CMF tool interface that already has a setup adapter. In practice the adapters shipped with the CMF sometimes use methods that are not part of the interface, so you have to verify that they really work for your classes.

Step 2:

Make sure those classes that need setup handlers have Zope3 style interfaces. Later you will write setup adapters for those interfaces.

Step 3:

Create an exportimport module inside your product. If you plan to write many setup handlers this can be a sub-package.

Step 4:

Decide which kind of setup handler you need:

body adapter
For objects represented by a complete file body. Provides Products.GenericSetup.interfaces.IBody.
XML adapter
A ‘body adapter’ in XML format. Also provides Products.GenericSetup.interfaces.IBody, but has its own base class because XML is the preferred format.
node adapter
For sub-objects represented by an XML node of the parent’s XML document. Provides Products.GenericSetup.interfaces.INode. This is useful for sub-objects of complex tools. Custom catalog index or action classes need this kind of adapter.
import and export steps
Top level handlers can be registered to manage import steps and / or export steps and call the body adapters.

If you use the base classes from Products.GenericSetup.utils, XML and node adapters are implemented in a very similar way. Both can mix in ObjectManagerHelpers and PropertyManagerHelpers.

Step 5:

Products.CMFCore.exportimport contains many examples for XML and node adapters. If you need a pure body adapter, Products.GenericSetup.PythonScripts would be a good example. Follow those examples and write your own multi adapter, register it for the interface of your class and for Products.GenericSetup.interfaces.ISetupEnviron and don’t forget to write unit tests.

Adapters follow the convention that self.context is always the primary adapted object, so the minimal setup context (ISetupEnviron) used in these multi adapters is self.environ.

XML and body adapters are always also small node adapters. This way the XML file of the container contains the information that is necessary to create an empty object. The handler of the container has to set up sub-objects before we can adapt them and configure them with their own handlers. The base classes in Products.GenericSetup.utils will care about that.

Step 6:

If your adapter is a top-level adapter (e.g for a tool), you need import and export steps that know how to use the adapter. Again there are many examples in Products.CMFCore.exportimport.

To make those steps available you have to add them to export_steps.xml and import_steps.xml of a setup profile and to load that profile into the setup tool.

Step 7:

Now you are done. To ship default settings with your product, make your settings through the ZMI (or set your stuff up the old way if you have old setup code like an Install.py) and export your settings using the setup tool. Unpack the exported tarball into a profiles subdirectory of your product, and then add gs:registerProfile entries to its configure.zcml file to register that directory as a base profile or extension profile.

See also

See About Profiles for more details.