How are you using plone.api?

Hi everybody!

I was wondering how you guys are using plone.api?

I'm looking for practical real-world code that already uses plone.api, but feels messy, feels not quite right.
Stuff like plone.api.content.find, instead of catalog = api.portal.get_tool(name='portal_catalog').

Cheers!

I assume you're also addressing gals, so here's my feedback: plone.api is one of the best things happened to Plone in its recent history, for the given reasonables and meets the setted goals, imho, congratulations! It is also very well documented, Chapeau. When it was fresh, it had a few bugs, but now I'm using it since some months regularly, mainly the find- and create-methods, as for example in adi.forumail no errors encountered :slight_smile: Thanks a lot guys (the creators), for closing that gap. Best, Ida

plone.api is one of the best things happened to Plone in its recent history

Just idly, I'd like to reiterate this.

Although there are a few rough edges (no way to do an unrestricted traverse for example), this one package has literally lifted Plone development to a higher level.

Honestly, I would trade Plone 5 for more packages that were this good.

Hi Doug,

Perhaps we're missing some part of the api.
Could you describe your use-case for unrestricted traverse?

-Roel

@jaroel Sorry, you didn't tag me so I didn't see this~

use-case for unrestricted traverse?

Consider the following use case:

  1. User submits a form

  2. The form response is saved in a folder called 'results' that is private.

  3. In order to cater for client failures, process the form by:

  • Look to see if there is currently a folder called 'results'
  • If not, create the folder
  • Create a new Result in the folder

However, you have to use unrestrictedSearchResults() to be able to find the private folder; the api's find function won't find it.

Similarly, I've occasionally had to fetch a content object for various reasons, and had to fallback to unrestrictedGetObject to access and update an object which is technically private, but needs to be modified via anonymous user form input.

@dougxxx
Could you file a ticket for this use case at https://github.com/plone/plone.api and mark it as enhancement?

I used the plone.api to write a command-line script, it was a quick fix (temporary) for a join form attack on a site I manage. I blogged about it here: http://blog.dbain.com/2015/08/removing-rogue-members-from-your-plone.html

I especially value the way it makes Plone programming more approachable for Plone newbies.

When hooking upon an event-listener and executing api.content.create I got "max. recursion exceeded", so I turned back to use invokeFactory, instead, which works fine. Same error occured with api.content.move.

I think this happens because api.content.create notifies the same event you are listening, thus generating a loop.

This happens after the execution of this line.

I think the same applies for api.content.move.

I do not see any easy solution for this, probably you are already doing the right thing by just calling the invokeFactory.

Oh nice, thanks for explaining @alert !

What would the approach for adding the body text for Dexterity content be ? Can it be added straight away or does the content first need to be created and then the field can be edited?

To answer my own question: the body text can be added straight away, so can other fields, (even the Image field)

from plone.app.textfield.value import RichTextValue

       text = RichTextValue(
            '<p>something</p>',
            'text/html',
            'text/x-html-safe'
        )
    )