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
... logger
...
... [contentsource]
... blueprint = collective.transmogrifier.sections.tests.folderssource
...
... [folders]
... blueprint = collective.transmogrifier.sections.folders
...
... [logger]
... blueprint = collective.transmogrifier.sections.logger
... name = logger
... level = INFO
... """
>>> registerConfig(u'collective.transmogrifier.sections.tests.folders',
... constructor)
>>> transmogrifier(u'collective.transmogrifier.sections.tests.folders')
>>> print handler
logger INFO
{'_path': '/foo', '_type': 'Document'}
logger INFO
{'_path': '/existing/foo', '_type': 'Document'}
logger INFO
{'_path': '/nonexisting', '_type': 'Folder'}
logger INFO
{'_path': '/nonexisting/alpha', '_type': 'Folder'}
logger INFO
{'_path': '/nonexisting/alpha/foo', '_type': 'Document'}
logger INFO
{'_path': '/nonexisting/beta', '_type': 'Folder'}
logger INFO
{'_path': '/nonexisting/beta/foo', '_type': 'Document'}
logger INFO
{'_type': 'Document'}
logger INFO
{'_folders_path': '/delta', '_type': 'Folder'}
logger INFO
{'_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
... logger
...
... [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
...
... [logger]
... blueprint = collective.transmogrifier.sections.logger
... name = logger
... level = INFO
... """
>>> registerConfig(u'collective.transmogrifier.sections.tests.folders2',
... constructor)
>>> handler.clear()
>>> plone.exists.clear()
>>> transmogrifier(u'collective.transmogrifier.sections.tests.folders2')
>>> print handler
logger INFO
{'_path': '/foo', '_type': 'Document'}
logger INFO
{'_path': '/existing/foo', '_type': 'Document'}
logger INFO
{"'_folderconstructor_path": '/nonexisting',
"'_folderconstructor_type": 'My Folder'}
logger INFO
{"'_folderconstructor_path": '/nonexisting/alpha',
"'_folderconstructor_type": 'My Folder'}
logger INFO
{'_path': '/nonexisting/alpha/foo', '_type': 'Document'}
logger INFO
{"'_folderconstructor_path": '/nonexisting/beta',
"'_folderconstructor_type": 'My Folder'}
logger INFO
{'_path': '/nonexisting/beta/foo', '_type': 'Document'}
logger INFO
{'_type': 'Document'}
logger INFO
{"'_folderconstructor_path": '/delta',
"'_folderconstructor_type": 'My Folder'}
logger INFO
{'_folders_path': '/delta/foo', '_type': 'Document'}