Reputation: 379
I'm having an issue getting a handle on creating some Dexterity content programmatically on Plone 5. Any pointers would be much appreciated.
Starting off with client2 debug
I run the following:
from plone import api
portal = api.portal.get()
And that promptly fails with:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/opt/plone/buildout-cache/eggs/plone.api-1.4.7-py2.7.egg/plone/api/portal.py", line 65, in get
"Unable to get the portal object. More info on "
CannotGetPortalError: Unable to get the portal object. More info on https://ploneapi.readthedocs.org/en/latest/api/exceptions.html#plone.api.exc.CannotGetPortalError
Or am I missing some prerequisite from the docs?
However, this code adapted from some earlier code for Plone 4 all works:
from Testing.makerequest import makerequest
from Products.CMFCore.utils import getToolByName
# point to our plone instance (hsfintranet off of the zope root)
portal = makerequest(app.hsfintranet)
siteadmin = portal.acl_users.getUserById('siteadmin')
if siteadmin == None:
print "Could not locate admin account"
exit()
# Switch security to our automated site administrator
siteadmin = siteadmin.__of__(portal.acl_users)
newSecurityManager(None, siteadmin)
# Find the staff directory
allfolder = getattr(portal, 'all', None)
# Did we find the all folder?
if allfolder == None:
print "Could not locate the 'all' folder"
exit()
staffdir = getattr(allfolder, 'staff-directory', None)
if staffdir == None:
print "Could not locate the staff directory"
exit()
That works fine to that point.
portal_types = getToolByName(portal, "portal_types")
# Get the FTI for our Dexterity type
type_info = portal_types.getTypeInfo('employee')
from plone.dexterity.utils import createContentInContainer
Checking type_info looks good
>>> type_info
<DexterityFTI at /hsfintranet/portal_types/employee>
But item = createContentInContainer(staffdir, type_info, title="Test")
fails with:
ComponentLookupError: (<InterfaceClass plone.dexterity.interfaces.IDexterityFTI>, <DexterityFTI at /hsfintranet/portal_types/employee>)
That was trying another example from these other docs
However there appears to be an endless number of ways to skin this cat! Trying all of:
item = staffdir.invokeFactory("employee", "test")
item = type_info._constructInstance(staffdir, 'Test')
from Products.CMFPlone.utils import _createObjectByType
item = _createObjectByType("employee", staffdir, 'Test')
All those fail with ComponentLookupError: (<InterfaceClass zope.component.interfaces.IFactory>, 'employee')
What get's me is that even this fails:
item = api.content.create(container=staffdir,type='Document',title='Test')
with ComponentLookupError: (<InterfaceClass zope.component.interfaces.IFactory>, 'Document')
.
And that's a built in type.
I just can't seem to get past Go here.
Upvotes: 2
Views: 362
Reputation: 6839
You need to set up the component registry for your plone site. If you're using a debug console.
from zope.component.hooks import setSite
setSite(portal)
Without this your component registry will be empty.
Upvotes: 2