Folders section
===============

The ``collective.transmogrifier.sections.constructor`` blueprint can construct
new content, based on a type (``_type`` key) and a path (``_path`` key).
However, it will bail if it is asked to create an item for which the parent
folder does not exist.

One way to work around this is to ensure that the folders already exist, for
example by sending the instruction to construct them through the pipeline
before any contents of that folder. This requires sorted input, of course.

Alternatively, you can use the ``collective.transmogrifier.sections.folders``
blueprint. This will look at the path of each incoming item and construct
parent folders if needed. This implies that all folders (that do not yet
exist), are of the same type. That type defaults to ``Folder``, although you
can supply an alternative type. The folder will be created without an id only,
but a subsequent schema updated section for a subsequent item may have the
opportunity to update it (but not change its type.)

This blueprint can take the following options, all of the optional:

``path-key``
    The name of the key holding the path. This defaults to the same semantics
    as those used for the constructor section. Just use ``_path`` and you'll
    be OK.
``new-type-key``
    The type key to use when inserting a new item in the pipeline to create
    folders. The default is ``_type``. Change it if you need to target a
    specific constructor section.
``new-path-key``
    The path key to use when inserting a new item in the pipeline to create
    folders. The default is to use the same as the incoming path key. Change
    it if you need to target a specific constructor section.
``folder-type``
    The name of the portal type to use for new folders. Defaults to
    ``Folder``, which is the default folder type in CMF and Plone.
``cache``
    By default, the section will keep a cache in memory of each folder it has
    checked (and possibly created) to know whether it already exists. This
    saves a lot of traversal, especially if you have many items under a
    particular folder. This will use a small amount of memory. If you have
    millions of objects, you can trade memory for speed by setting this option
    to false.

Here is how it might look by default:

    >>> import pprint
    >>> constructor = """
    ... [transmogrifier]
    ... pipeline =
    ...     contentsource
    ...     folders
    ...     printer
    ...     
    ... [contentsource]
    ... blueprint = collective.transmogrifier.sections.tests.folderssource
    ... 
    ... [folders]
    ... blueprint = collective.transmogrifier.sections.folders
    ... 
    ... [printer]
    ... blueprint = collective.transmogrifier.sections.tests.pprinter
    ... """
    >>> registerConfig(u'collective.transmogrifier.sections.tests.folders',
    ...                constructor)
    >>> transmogrifier(u'collective.transmogrifier.sections.tests.folders')
    [('_path', '/foo'), ('_type', 'Document')]
    [('_path', '/existing/foo'), ('_type', 'Document')]
    [('_path', '/nonexisting'), ('_type', 'Folder')]
    [('_path', '/nonexisting/alpha'), ('_type', 'Folder')]
    [('_path', '/nonexisting/alpha/foo'), ('_type', 'Document')]
    [('_path', '/nonexisting/beta'), ('_type', 'Folder')]
    [('_path', '/nonexisting/beta/foo'), ('_type', 'Document')]
    [('_type', 'Document')]
    [('_folders_path', '/delta'), ('_type', 'Folder')]
    [('_folders_path', '/delta/foo'), ('_type', 'Document')]
    
To specify alternate types and keys, we can do something like this:

    >>> import pprint
    >>> constructor = """
    ... [transmogrifier]
    ... pipeline =
    ...     contentsource
    ...     folders
    ...     printer
    ...     
    ... [contentsource]
    ... blueprint = collective.transmogrifier.sections.tests.folderssource
    ... 
    ... [folders]
    ... blueprint = collective.transmogrifier.sections.folders
    ... folder-type = My Folder
    ... new-type-key = '_folderconstructor_type
    ... new-path-key = '_folderconstructor_path
    ... 
    ... [printer]
    ... blueprint = collective.transmogrifier.sections.tests.pprinter
    ... """
    >>> registerConfig(u'collective.transmogrifier.sections.tests.folders2',
    ...                constructor)
    >>> transmogrifier(u'collective.transmogrifier.sections.tests.folders2')
    [('_path', '/foo'), ('_type', 'Document')]
    [('_path', '/existing/foo'), ('_type', 'Document')]
    [("'_folderconstructor_path", '/nonexisting'),
     ("'_folderconstructor_type", 'My Folder')]
    [("'_folderconstructor_path", '/nonexisting/alpha'),
     ("'_folderconstructor_type", 'My Folder')]
    [('_path', '/nonexisting/alpha/foo'), ('_type', 'Document')]
    [("'_folderconstructor_path", '/nonexisting/beta'),
     ("'_folderconstructor_type", 'My Folder')]
    [('_path', '/nonexisting/beta/foo'), ('_type', 'Document')]
    [('_type', 'Document')]
    [("'_folderconstructor_path", '/delta'),
     ("'_folderconstructor_type", 'My Folder')]
    [('_folders_path', '/delta/foo'), ('_type', 'Document')]
