[Zope-CMF] transparent folder
Gregoire Weber
gregoire.weber@switzerland.org
Fri, 07 Mar 2003 11:08:47 +0100
Hi,
IMO it's better to extend PortalFolder with the relevant methods,=20
as I've done it. Have a look at the code below.
Additional Resources:
- Proposal:=
<http://www.zope.org//Wikis/DevSite/Proposals/OrderedObjectManager>
- Code: <http://www.zope.org/Members/mjablonski/OrderedObjectManager>
Gregoire
---------- OrderedPortalFolder.py start ----------
#####
##
# OrderedPortalFolder
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# This product uses modified codes from the OrderedFolder-Product
# written by Stephan Richter / copyrighted by iuveno AG
# Please read the LICENSE.txt!
#
# The code below is derived from OrderedObjectManager
# from maik.jablonski@uni-bielefeld.de
##
####
from types import StringType
from Globals import ImageFile, DTMLFile, InitializeClass
from AccessControl import ClassSecurityInfo
from Products.CMFCore import CMFCorePermissions
from Products.CMFCore.PortalFolder import PortalFolder
oomPermission =3D 'Copy or Move'
class OrderedPortalFolder(PortalFolder):
security =3D ClassSecurityInfo()
security.declareObjectProtected(CMFCorePermissions.View)
# override the ZMI folder view
manage_main =3D DTMLFile('dtml/manage_main', globals())
misc_ =3D {'up' : ImageFile('zmi/up.gif', globals()),
'down' : ImageFile('zmi/down.gif', globals()),
'top' : ImageFile('zmi/top.gif', globals()),
'bottom' : ImageFile('zmi/bottom.gif', globals())}
security.declareProtected(oomPermission, 'get_object_position')
def get_object_position(self, id):
""" Get the position of a particular object. """
=20
ids =3D map(lambda obj: obj['id'], self._objects)
if id in ids:
return ids.index(id)
else:
raise 'ObjectNotFound', self.aq_parent._objects =20
=20
security.declareProtected(oomPermission, 'move_objects_by_positions')
def move_objects_by_positions(self, ids, position_delta):
""" moves objects with ids by position_delta """
if type(ids) is StringType: ids =3D (ids,)
# Interestingly enough, we need to switch the order when
# moving done, so that the movements won't cancel each other
if position_delta > 0:
ids =3D list(ids)
ids.reverse()
=20
moved_objects =3D 0
=20
for id in ids:
old_position =3D self.get_object_position(id)
new_position =3D old_position + position_delta
object =3D self._objects[old_position]
# Make sure the new position makes sense and is valid
if not (old_position =3D=3D new_position or
new_position > len(self._objects) or
new_position < 0):
=20
objects =3D list(self._objects)
# now delete the entry ...
objects =3D filter(lambda obj, id=3Did: obj['id'] !=3D id,=
objects)
# ... and now add it again
objects.insert(new_position, object)
self._objects =3D tuple(objects)
moved_objects =3D moved_objects + 1
return moved_objects
security.declareProtected(oomPermission, 'move_objects_up')
def move_objects_up(self, ids):
""" moving the items up """
=20
return self.move_objects_by_positions(ids, -1)
security.declareProtected(oomPermission, 'move_objects_down')
def move_objects_down(self, ids):
""" moving the items down """
=20
return self.move_objects_by_positions(ids, +1)
security.declareProtected(oomPermission, 'move_objects_to_top')
def move_objects_to_top(self, ids):
""" moving the items to the top """
=20
if type(ids) is StringType: ids =3D (ids,)
position_delta =3D - self.get_object_position(ids[0])
return self.move_objects_by_positions(ids, position_delta)
security.declareProtected(oomPermission, 'move_objects_to_bottom')
def move_objects_to_bottom(self, ids):
""" moving the items to the bottom """
if type(ids) is StringType: ids =3D (ids,)
# We will do the reverse twice,
# but for going to the bottom there is no other choice.
ids =3D list(ids)
ids.reverse()
position_delta =3D len(self.objectIds()) -=
self.get_object_position(ids[-1])
return self.move_objects_by_positions(ids, position_delta)
security.declareProtected(oomPermission, 'manage_move_objects_up')
def manage_move_objects_up(self, ids=3DNone, REQUEST=3DNone):
""" moves selected items up by one """
if type(ids) is StringType: ids =3D (ids,)
=20
attempt =3D 0
if ids: attempt =3D self.move_objects_up(ids)
if REQUEST: REQUEST.RESPONSE.redirect('manage_main')
return attempt
security.declareProtected(oomPermission, 'manage_move_objects_down')
def manage_move_objects_down(self, ids=3DNone, REQUEST=3DNone):
""" moves selected items down by one """
if type(ids) is StringType: ids =3D (ids,)
attempt =3D 0
if ids: attempt =3D self.move_objects_down(ids)
if REQUEST: REQUEST.RESPONSE.redirect('manage_main')
return attempt
security.declareProtected(oomPermission, 'manage_move_objects_to_top')
def manage_move_objects_to_top(self, ids=3DNone, REQUEST=3DNone):
""" moves selected items to top """
=20
if type(ids) is StringType: ids =3D (ids,)
attempt=3D0
if ids: attempt=3Dself.move_objects_to_top(ids)
if REQUEST: REQUEST.RESPONSE.redirect('manage_main')
return attempt
security.declareProtected(oomPermission,=
'manage_move_objects_to_bottom')
def manage_move_objects_to_bottom(self, ids=3DNone, REQUEST=3DNone):
""" moves selected items to bottom """
if type(ids) is StringType: ids =3D (ids,)
attempt=3D0
if ids: attempt =3D self.move_objects_to_bottom(ids)
if REQUEST: REQUEST.RESPONSE.redirect('manage_main')
return attempt
security.declareProtected(oomPermission, 'manage_orderObjects')
def manage_orderObjects(self, ids=3DNone, REQUEST=3DNone):
""" orders a container with the ordered list 'ids' """
if ids:
for id in ids:
old_position =3D self.get_object_position(id)
new_position =3D ids.index(id)
object =3D self._objects[old_position]
# Make sure the new position makes sense and is valid
if not (old_position =3D=3D new_position or
new_position > len(self._objects) or
new_position < 0):
=20
objects =3D list(self._objects)
# now delete the entry ...
objects =3D filter(lambda obj, id=3Did: obj['id'] !=3D=
id, objects)
# ... and now add it again
objects.insert(new_position, object)
self._objects =3D tuple(objects)
if REQUEST: REQUEST.RESPONSE.redirect('manage_main')
=20
# Override 'manage_renameObject' of CopyContainer -
# manage_renameObject should preserve the order
def manage_renameObject(self, id, new_id, REQUEST=3DNone):
""" rename a particular sub-object """
=20
position =3D self.get_object_position(id)
result =3D PortalFolder.manage_renameObject(self, id, new_id,=
REQUEST)
newposition =3D self.get_object_position(result)
self.move_objects_by_positions(result, position - newposition)
return result
InitializeClass(OrderedPortalFolder)
---------- OrderedPortalFolder.py end ----------
At 20:02 07.03.2003 +1100, David Hart wrote:
>Hi,
>
>Okay, I did a crazy thing: I patched PortalFolder to superclass=
OrderedFolder instead of Folder:
>
>#pwd
>/opt/zope/Products/CMF-1.3/CMFCore
>#
>#diff PortalFolder.py.orig PortalFolder.py.Ordered
>25a26
>> from Products.OrderedFolder.OrderedFolder import OrderedFolder
>67c68
>< class PortalFolder(DynamicType, CMFCatalogAware, Folder):
>---
>> class PortalFolder(DynamicType, CMFCatalogAware, OrderedFolder):
>380c381
>< self.manage_addFolder( id=3Did, title=3D'' )
>---
>> self.manage_addOrderedFolder( id=3Did, title=3D'' )
>463c464
>< def manage_addFolder( self
>---
>> def manage_addOrderedFolder( self
>
>
>Now from the CMF interface (Plone, actually), all works fine. I can add new=
PloneFolders, set the transparent flag, add other objects, like documents,=
to them, etc.
>
>However, when I use invokeFactory from within a python script, the new=
object is created in the parent folder:
>
>inline_content.invokeFactory(id=3Dobject_id, type_name=3D'Document')
>
>Now, I think this may have to do with util.py and acquisition within=
getToolByName, but I'm not sure... Can anyone help shed any light on the=
problem?
>
>Constructive comments only please.
>
>Thanks,
>
>Dave Hart
_____________________________________
Gr=E9goire Weber
mailto:gregoire.weber@switzerland.org