Creating a Pre-Populated Folder
This How-to applies to:
Any version.
This How-to is intended for:
Integrators, Customizers
You want to create a new folderish object that is pre-populated with a variety of content objects.
in ZMI:
- goto portal_types
- add new
(Script) Python- id: addPopulatedFolder
- title: prepopulated folder
- parameters: container, id
Code:
## Script (Python) "addPrePopulatedFolder"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=parent, id
##title=Subject Area
##
# First, create an instance of the portal_type most like the
# one we want, to allow the instance to be persisted in the ZODB.
parent.invokeFactory(id=id, type_name='Folder')
# Get a reference to the newly created portal_type object.
obj = getattr(parent,id)
obj.invokeFactory(id='newsitem_1', type_name='News Item')
obj.invokeFactory(id='document_1', type_name='Document')
obj.invokeFactory(id='image_1', type_name='Image')
# We have just populated it with 3 content objects!
# We can nest a few folders; of course nesting Populated Folder
# would do bad things
# Create folder1 inside of our Populated Folder instance
obj.invokeFactory(id='folder1', type_name='Folder')
# Get a reference to the newly created folder ...
folder1 = getattr(obj, 'folder1')
# ... and create a subfolder inside.
folder1.invokeFactory(id='subfolder1', type_name='Folder')
return obj
# It is very important to hand back the object so that
# the CMF machinery can imprint some type information onto
# the instance. Up to this point, obj is just a Folder. But
# when you return it the machinery will make it a Populated
# Folder.
In portal_types in the drop down list there is a 'Scriptable Type Information'; add it.
- you only need to fill out two fields:
- id: Populated Folder
- use Default Type Information: CMFPlone: Plone Folder
- now that you've created the type information, click on it to edit it.
- Constructor permission: Add portal content
- Constructor path: portal_types/addPopulatedFolder
- NOTE: the above is the relative path to the portal from where you are adding the object. So anywhere inside a CMF portal you can easily access the portal_types by just traversing to it. This happens via Acquisition.
Now you are done. You should be able to add Populated Folder instances
to your Folderish objects. If you are using Plone there is one more step
to go.
- in portal_properties/site_properties there is a property,
use_folder_tabs. AddPopulated Folderto that list (on a new line).
Why is this? Because Plone attempts to layer functionality on top of CMF instead of completely replacing it. Therefore there are some implementation details (e.g., when something is a folder/object) that are exposed. The tab code is crufty and old but fairly easy to fix (especially if you aren't trying to be all things to all people).
Error:No such content type: Populated Folder
After trying to test the recipe with green tag link "Neuen Artikel hinzufügen/Populated Folder" this messages follows:
No such content type: Populated Folder
Anny idea what's going wrong here?
AT content types
Is setTitle appropriate for Plone 2.1 AT content? When I use it the Title is changed correctly as seen from the content View and Edit actions, but the Folder listing shows the ID and ignores the Title now. Is there a better method for Plone 2.1?
id in navigation
I get the same problem: I think it has something to do with updating the catalogue. Not sure how to fix this as yet.
Need to reindex
PloneHelpCenter has an example of this for Archetypes. It calls reindexObject() on each newly created sub object.
if faq not in self.objectIds():
self.invokeFactory(HelpCenterFAQFolder,faq)
obj = self['faq']
obj.setTitle(self.translate(
msgid=phc_faq_title,
domain=plonehelpcenter,
default=FAQs))
obj.setDescription(self.translate(
msgid=phc_faq_description,
domain=plonehelpcenter,
default=Frequently Asked Questions))
obj.reindexObject()
mmm
duh, both methods work actually - ? allthough I did get an error first that I couldn't use keyword arguments - ?
Doesn't work with Plone 2.1
Doesn't work on Plone 2.1 for me. When you try to add a "Populated Folder" you just get a large traceback. I won't paste it here, as this should be reproduceable but it ends with what I've pasted below. Any tips on 2.1-ifying this handy recipe?
- Module Products.CMFCore.FSPythonScript, line 163, in _exec
Module None, line 15, in getSelectableViews
Line 15 Module Products.CMFDynamicViewFTI.browserdefault, line 227, in getAvailableLayouts AttributeError: getAvailableViewMethods (Also, an error occurred while attempting to render the standard error message.)
The method cannot work with plone 2.1
The issue is that the UI for Folders in plone 2.1 expects the folders to use the CMFDynamicViewFTI which provides some methods which are unavailable on the Scriptable FTI in use here. The workaround would be to use a folder type which does not implement the BrowserDefaultMixin as the basis for your Scriptable FTI. The other option would be to use one of the many other techniques for doing this like: http://www.mxm.dk/products/public/dmcs/
Will this work in Plone 2.5?
I'm trying to get this to work in Plone 2.5. When trying to add a Scriptable Type Information, I only see id and not 'use Default Type Information". If I skip this part, I just end up getting an error about "no view action found" when trying to add the new content type. Does this work with Plone 2.5? Is there an easy way to do something like this in Plone 2.5?
Can do it with initializeArchetype too
def initializeArchetype(self, **kwargs):
self.invokeFactory(id='folder1', type_name='Folder')
to your content type's class and it will add a folder...
Can do it with initializeArchetype too
loop through line field values
EX: creating departments inside a directory based on 'Department' lines fields values
setTitle() on the new objects
I found it useful to call setTitle(self,title) and setDescription(self,description) on the newly created object. I've also called these functions in the post_validate() function, after the data fields have been set.