I’ve been trying to create content in my plone site using the Dexterity tool createContentInContainer.
I wrote a script that runs under my zopepy instance, and it accomplishes the following:
- Selects data from a SQL table.
- Creates a list of tuples that mirrors the custom content type defined in my product.
I know I’m extremely naive in my approach, but I’ve created a connection to the applications database by:
storage = FileStorage.FileStorage('.../var/filestorage/Data.fs')
db = DB(storage)
conn = db.open()
dbroot = conn.root()
I’m trying to create content by:
createContentInContainer(dbroot['Application']['myapp']['existingfolder'], portal_type, checkConstraints=False, content=item)
portal_type is previously set to my custom content type. item has been both the list of tuples passed to the content’s interface (which throws a Could not adapt TypeError) as well as an unregistered adapter that inherits from the interface.
The interface for the type is registered in mysite.Widget.xml in profiles/defualt/types, but the script keeps throwing:
Traceback (most recent call last):
File "./bin/zopepy", line 345, in <module>
execfile(__file__)
File "importdex.py", line 105, in <module>
createContentInContainer(dbroot['Application']['myapp']['existingfolder'], portal_type, checkConstraints=False, content=item)
File "env/mysite/eggs/plone.dexterity-1.0-py2.7.egg/plone/dexterity/utils.py", line 149, in createContentInContainer
content = createContent(portal_type, **kw)
File "env/mysite/eggs/plone.dexterity-1.0-py2.7.egg/plone/dexterity/utils.py", line 105, in createContent
fti = getUtility(IDexterityFTI, name=portal_type)
File "env/mysite/eggs/zope.component-3.9.5-py2.7.egg/zope/component/_api.py", line 169, in getUtility
raise ComponentLookupError(interface, name)
zope.component.interfaces.ComponentLookupError: (<InterfaceClass plone.dexterity.interfaces.IDexterityFTI>, 'mysite.Widget')
As I’ve mentioned, I know I’m extremely naive in my approach, and I probably deserve a slap on the hand. I apologize if I’ve presented my question in a confusing manner.
My questions are these:
- Can I instantiate
createContentInContainerfrom zopepy? Is my rigged connection enough or does the script need to be run within the application to inherit stuff that Dexterity/FTI needs to accomplish what I’m asking? - Do I need an adapter? The one i have inherits from
grok.Adapterand passes the interface togrok.providesandgrok.context, but should it declare properties based on the entirety of the content schema? - The list of tuples is arbitrary. It just seemed like the thing to do given the structure of the ZODB. If I declare the schema of the content type as properties in a registered adapter, the data should be crafted to conform to attributes of an object (the adapter), right?
You need to set up a little more context for your code to work. The Plone site acts as a local component registry, for example.
You are also better off using the
bin/instance run [scriptname]command, it’ll set up the database connection for you and pass the root object asappto your script. In that script, use the following boilerplate to get the rest of the scaffolding up:With these in place you’ll have everything you need to run your code. Don’t forget to call
transaction.commit()at the end. Your Plone site is reachable in the local variablesite.