How-to: Writing setup handlers for GenericSetup

  If your products subclass existing tools or provide new tools (or new
  sub-object classes) they might need their own setup handlers in order to
  make use of 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 they really work for your classes.

  Step 2:

    Make sure those classes that need setup handlers have Zope 3 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 IBody.

    - 'XML adapter':
    'body adapter' in XML format. Also provides 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 parents XML document.
    Provides INode. This is useful for sub-objects of complex tools. Custom
    catalog index or action classes need that kind of adapter.

    - 'import and export steps':
    Top level handlers that can be registered as import step or export step
    and call the body adapters. Maybe these will become obsolete for tools,
    but currently they are required.

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

  Step 5:

    CMFCore.exportimport contains many examples for XML and node adapters. If
    you need a pure body adapter, 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 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 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 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.
