Content¶
Create content¶
To add an object, you must first have a container in which to put it. Get the portal object, it will serve nicely:
from plone import api
portal = api.portal.get()
Create your new content item using the
api.content.create()
method. The type argument will decide which content type
will be created. Both Dexterity and Archetypes content
types are supported.
from plone import api
obj = api.content.create(
type='Document',
title='My Content',
container=portal)
The
id
of the new object is automatically and safely generated
from its
title
.
assert obj.id == 'my-content'
Get content object¶
There are several approaches to getting your content object. Consider the following portal structure:
plone (portal root)
|-- blog
|-- about
| |-- team
| `-- contact
`-- events
|-- training
|-- conference
`-- sprint
The following operations will get objects from the
stucture above, including using
api.content.get()
.
# let's first get the portal object
from plone import api
portal = api.portal.get()
assert portal.id == 'plone'
# content can be accessed directly with dict-like access
blog = portal['blog']
# another way is to use ``get()`` method and pass it a path
about = api.content.get(path='/about')
# more examples
conference = portal['events']['conference']
sprint = api.content.get(path='/events/sprint')
# moreover, you can access content by its UID
uid = about['team'].UID()
team = api.content.get(UID=uid)
# returns None if UID cannot be found in catalog
not_found = api.content.get(UID='notfound')
Find content objects¶
You can use the find function to search for content.
Finding all Documents:
from plone import api
documents = api.content.find(portal_type='Document')
Finding all Documents within a context:
from plone import api
documents = api.content.find(
context=api.portal.get(), portal_type='Document')
Limit search depth:
from plone import api
documents = api.content.find(depth=1, portal_type='Document')
Limit search depth within a context:
from plone import api
documents = api.content.find(
context=api.portal.get(), depth=1, portal_type='Document')
Search by interface:
from plone import api
from Products.CMFCore.interfaces import IContentish
documents = api.content.find(object_provides=IContentish)
Combining multiple arguments:
from plone import api
from Products.CMFCore.interfaces import IContentish
documents = api.content.find(
context=api.portal.get(),
depth=2,
object_provides=IContentish,
SearchableText='Team',
)
More information about how to use the catalog may be found
in the
Plone Documentation. Note that the catalog returns brains (metadata
stored in indexes) and not objects. However, calling
getObject()
on brains does in fact give you the object.
document_brain = documents[0]
document_obj = document_brain.getObject()
Get content object UUID¶
A Universally Unique IDentifier (UUID) is a unique, non-human-readable identifier for a content object which stays on the object even if the object is moved.
Plone uses UUIDs for storing references between content and for linking by UIDs, enabling persistent links.
To get the UUID of any content object use
api.content.get_uuid()
. The following code gets the UUID of the
contact
document.
from plone import api
portal = api.portal.get()
contact = portal['about']['contact']
uuid = api.content.get_uuid(obj=contact)
Move content¶
To move content around the portal structure defined above
use the
api.content.move()
method. The code below moves the
contact
item (with all it contains) out of the folder
about
and into the Plone portal root.
from plone import api
portal = api.portal.get()
contact = portal['about']['contact']
api.content.move(source=contact, target=portal)
Actually,
move
behaves like a filesystem move. If you pass it an
id
argument the object will have that new ID in it's new
home. By default it will retain its original ID.
Rename content¶
To rename a content object (change its ID), use the
api.content.rename()
method.
from plone import api
portal = api.portal.get()
api.content.rename(obj=portal['blog'], new_id='old-blog')
Copy content¶
To copy a content object, use the
api.content.copy()
method.
from plone import api
portal = api.portal.get()
training = portal['events']['training']
api.content.copy(source=training, target=portal)
Note that the new object will have the same ID as the old object (unless otherwise stated). This is not a problem, since the new object is in a different container.
You can also set
target
to source's container and set
safe_id=True
. This will duplicate your content object in the same
container and assign it a new, non-conflicting ID.
api.content.copy(source=portal['training'], target=portal, safe_id=True)
new_training = portal['copy_of_training']
Delete content¶
To delete a content object, pass the object to the
api.content.delete()
method:
from plone import api
portal = api.portal.get()
api.content.delete(obj=portal['copy_of_training'])
To delete multiple content objects, pass the objects to
the
api.content.delete()
method:
from plone import api
portal = api.portal.get()
data = [portal['copy_of_training'], portal['events']['copy_of_training'], ]
api.content.delete(objects=data)
If deleting content would result in broken links you will get a LinkIntegrityNotificationException. To delete anyway, set the option check_linkintegrity to False:
from plone import api
portal = api.portal.get()
api.content.delete(obj=portal['copy_of_training'], check_linkintegrity=False)
Content manipulation with the safe_id option¶
When manipulating content with
api.content.create()
,
api.content.move()
or
api.content.copy()
the safe_id flag is disabled by default. This
means the uniqueness of IDs will be enforced. If another
object with the same ID is already present in the target
container these API methods will raise an error.
However, if the safe_id option is enabled, a non-conflicting id will be generated.
api.content.create(container=portal, type='Document', id='document', safe_id=True)
document = portal['document-1']
Get workflow state¶
To find out the current workflow state of your content,
use the
api.content.get_state()
method.
from plone import api
portal = api.portal.get()
state = api.content.get_state(obj=portal['about'])
The optional default argument is returned if no workflow is defined for the object.
from plone import api
portal = api.portal.get()
state = api.content.get_state(obj=portal['image'], default='Unknown')
Transition¶
To transition your content to a new workflow state, use
the
api.content.transition()
method.
from plone import api
portal = api.portal.get()
api.content.transition(obj=portal['about'], transition='publish')
If your workflow accepts any additional arguments to the checkin method you may supply them via kwargs. These arguments can be saved to your transition using custom workflow variables inside of the ZMI using an expression. ie. "python:state_change.kwargs.get('comment', '')"
from plone import api
portal = api.portal.get()
api.content.transition(obj=portal['about'], transition='reject', comment='You had a typo on your page.')
Get view¶
To get a
BrowserView
for your content, use
api.content.get_view()
.
from plone import api
portal = api.portal.get()
view = api.content.get_view(
name='plone',
context=portal['about'],
request=request,
)
Further reading¶
For more information on possible flags and usage options please see the full plone.api.content specification.