|
|
Saturday, June 15, 2002 |
|
Reordering Items in a Zope ObjectManager We have movable Parts!. That's right. With a little bit of code, a couple of unit tests, and some surprisingly simple UI work, Parts in an SCS Document can be re-arranged. This is yielding something I've been wanting to do (and have) for years - decent through-the-web Document editing, with drop in objects than can be reorganized easily. While I'm sure it's been done many times before, it was great seeing the results yesterday as part of my own framework and application. The work went fairly quickly, once I moved the methods to the right class and added Unit Tests. The secret is in the _objects attribute of Zope ObjectManager based instances. _objects is a tuple of dictionaries with the keys 'id' and 'meta_type'. ObjectManager classes use this information to know what objects in the ObjectManager are being managed as subobjects, and to define their ordering. Most people never see or know of this attributes existence as its use is well-handled by the common ObjectManager API's. But one can use this list to their advantage, such as reordering.
So, in todays code we have what I used to reorder Parts in my PartContainer class. There are two important elements - finding the index of the object in question, and then swapping its place in the list. We can't use
class PartContainer(ObjectManager): def _findPartIndex(self, part_id, objectList=[]): """ Returns the index of a part in the object list """ idx = 0 for obj in objectList: if obj['id'] == part_id: break idx += 1 else: ## part not found raise IndexError(part_id) return idx security.declareProtected(change_scs_documents, 'movePartUp') def movePartUp(self, part_id): """ Move a part up. Raises IndexError if part is not found """ ## make a copy of our _objects list, which is a part of ObjectManager. ## _objects is a tuple of dictionaries with keys 'meta_type' and 'id'. parts = list(self._objects) idx = self._findPartIndex(part_id, parts) if idx == 0: ## Can't move past top, just exit return 0 ## swap fields, moving idx up parts[idx], parts[idx-1] = parts[idx-1], parts[idx] self._objects = tuple(parts) return 1 security.declareProtected(change_scs_documents, 'movePartDown') def movePartDown(self, part_id): """ Move a part down. Raises IndexError if part is not found """ ## make a copy of our _objects list, which is a part of ObjectManager. ## _objects is a tuple of dictionaries with keys 'meta_type' and 'id'. parts = list(self._objects) idx = self._findPartIndex(part_id, parts) if idx == len(parts)-1: ## Can't move past bottom, so just exit return 0 ## swap fields, moving idx up parts[idx], parts[idx+1] = parts[idx+1], parts[idx] self._objects = tuple(parts) return 1 10:40:39 AM |