4

How can i make my folderish custom type display it's object listing in reverse chronological order in folder_contents view?

Default is oldest object at the top of the list, I would like a new object just added to be at the top of the list.

Would be nice if Plone had this feature out of the box... if it does i can't find it.

Ida
  • 3,994
  • 21
  • 40
Aaron Williams
  • 655
  • 4
  • 11
  • Note: Added the final code for 'Add new object to top of folder' as an Answer below. Not worrying about the default sort order for folder_contents as it's kind of irrelevant now with this working code. – Aaron Williams Sep 24 '15 at 01:55

5 Answers5

9

To actually change the obj-position in its parent you can utilize Zope2's OFS.IOrderedContainer-interface for accessing the relevant methods and hook it up on zope.lifecycleevent.interfaces.IObjectAddedEvent, like in this Plone-addon "adi.revertorder" (disclaimer: author=meh):

In you configure.zcml register the eventlistener:

<subscriber for="Products.CMFCore.interfaces.IContentish
                 zope.lifecycleevent.interfaces.IObjectAddedEvent"
            handler=".subscriber.revertOrder" />

And in the handler (here: subscriber.py), define the called method:

from Acquisition import aq_inner
from Acquisition import aq_parent

from OFS.interfaces import IOrderedContainer

def revertOrder(obj, eve):
    """
    Use IOrderedContainer interface to move an object to top of folder on creation.
    """
    parent = obj.aq_inner.aq_parent
    ordered = IOrderedContainer(parent, None)
    if ordered is not None:
        ordered.moveObjectToPosition(obj.getId(), 0)

Applies to Dexterity- and Archetype-based contenttypes.

See also the docs: http://docs.plone.org/external/plone.app.dexterity/docs/advanced/event-handlers.html

Community
  • 1
  • 1
Ida
  • 3,994
  • 21
  • 40
  • Thanks, i was hoping to keep /folder_contents as the view and use the standard 'Contents' click on the green bar... i just want new items added to the top of the list. And the user will still want to be able to arbitrarily order content using drag and drop. – Aaron Williams Sep 23 '15 at 08:58
  • I already have a custom dexterity folderish object and view template, but i dont know if there's a way to easily override the standard /folder_contents behaviour with a 'prepend' of new objects behaviour instead of an 'append'if that makes sense... – Aaron Williams Sep 23 '15 at 08:59
  • @AaronWilliams: Updated quest with solution for Dexterity, also. – Ida Sep 23 '15 at 18:01
3

The folder_contents View displays the items (children) by the position stored on the folder itself. As you may know you can change the positions by drag'n'drop.

Currently plone does an append if you add a new item to the folder. IMHO this behavior is perfect suitable for most usecases.

I'm not sure what your goal ist, but if you need a folder_contents, which shows the items chronological, you may customize the folder_contents to your needs, which means, sorting by creation date (newest on top) and no longer show the manual sort column.

Hints about customize the folder_contents

A good entry point is the tableview.py of plone.app.content -> https://github.com/plone/plone.app.content/blob/2.1.5/plone/app/content/browser/tableview.py#L30

Mathias
  • 6,777
  • 2
  • 20
  • 32
  • I would like exactly the same behaviour except with prepend instead of append... any ideas? – Aaron Williams Sep 23 '15 at 08:53
  • I've used Plone for a long time and always thought putting the newest items first was more logical. Plone should provide a standard control for this in the display menu imo. – Aaron Williams Sep 23 '15 at 08:54
  • 1
    @AaronWilliams: Would you like help making that option hapenning? Best way would be to provide a code example which could possibly one day be regarded to make it into the core. Find a similar event for Dexterity, like the one I cited for Archetypes and add a controlpanel-option for setting the prop via the UI, that should be it :-) – Ida Sep 23 '15 at 12:11
  • @AaronWilliams: I think what Mathias was trying to point out, is that there ar two separate concerns: One is the ability to set manually an order at a users arbitrary will, the other to have the folder_contents-view sorted by some criteria, like newest first. – Ida Sep 23 '15 at 13:49
  • 2
    @AaronWilliams: You can now install adi.revertorder, if you you want prepending new content-items, to be the default-behaviour of a site. – Ida Sep 24 '15 at 15:41
2

Using a rule is also an option.

The following moves objects on creation to the top position in folder.

Add a workflow script (type 'Python Script') ‚moveToFirstPosition‘ to your workflow:

contentObject = review_state.object
obj_id = contentObject.getId()
parent = contentObject.aq_parent
parent.moveObjectToPosition(obj_id, 0)

Add a transition 'moveToTop‘ and select script ‚moveToFirstPosition'

Use this transition in a new rule triggered on creating objects in folders. Activate rule globally or on selected folders.

Katja Süss
  • 759
  • 6
  • 13
  • Looks like a working solution for the case one would want to restrict the behaviour location-wise. Cool, upvoted. – Ida Oct 01 '15 at 08:00
  • Thanks, i took a look into plone.app.contentrules. Not sure how to add a 'workflow script' that i can select from the 'Perform the following actions' vocabulary? Any link to doco? I found a product called 'collective.contentrules.runscript' is that required also? – Aaron Williams Oct 05 '15 at 06:13
  • It's Default-Plone, no add-on needed. The action that is used for this new rule is a workflow transition. This transition has to be created in portal_workflow in one of your workflows. The transition uses the script that has to be created in the same workflow. The script could be one like 'moveToFirstPosition' as mentioned above. If you like this way, maybe you consider defining this all, transition and script, in a product instead of doing this all via webinterface. – Katja Süss Oct 05 '15 at 12:47
1

collective.sortmyfolder has some options for reversing the order, or ordering on a different field, but it only works once. After you add another item, you would need to reorder the folder again. Not exactly what you want, but it may be helpful in some cases.

maurits
  • 2,355
  • 13
  • 16
1

Thanks All. The pointer from Ida got me there... and I only need to import IObjectAddedEvent:

In myobject.py

from zope.lifecycleevent.interfaces import IObjectAddedEvent

...

class IMyObject(model.Schema):

...

# Listener for adding myObject: move myObject to the top of the parent folder
def addItemToTop(myObject, event):
    event.newParent.moveObjectToPosition(myObject.getId(),0)

And register the listener in configure.zcml:

<subscriber
    for=".myobject.IMyObject zope.lifecycleevent.interfaces.IObjectAddedEvent"
    handler=".myobject.addItemToTop"
/>

Doco is here: http://docs.plone.org/external/plone.app.dexterity/docs/advanced/event-handlers.html

Aaron Williams
  • 655
  • 4
  • 11
  • 1
    Besides that this is identical to my answer, you're missing the interface-argument in `for`, like the asterix-wildcard I use in the example-package. Quoting the docs: "The first argument to `for` is an interface describing the object type. The second argument is the event type". Interesting though, that nevertheless it seems to work for you. – Ida Sep 24 '15 at 05:52
  • P.S.: Using wildcard-asterix is bad, updated answer with restriction to contentish objects. In your case you can use `path.to.myobject.IMyObject`, if you want this only to happen with your specific contenttype. – Ida Sep 24 '15 at 07:01
  • 1
    Thanks Ida...i did accept your answer as the correct answer, i just added my completed solution in case it helps anyone as i didn't need IOrderContainer to access the moveObjectToPosition method... it's already available. AS for the missing 'for' argument, it is actually there, you're just not seeing the space in between the two arguments :) – Aaron Williams Sep 25 '15 at 02:13
  • Oh I see, immediately available, that's neat, thanks. Apologies for reading to hastiliy, I'm used to each argument consuming a line for itself. – Ida Sep 25 '15 at 06:02