Newbie Question: Ordering items within a folder based on a property
Everyone: I know that this has come up over and over on the list, I just still can't get a handle on it. If I could get some good information from the list, I would like to put together a HOW-TO on this, because I think it's a common goal. I have folders that contain folders and other objects. I want to build a menu along the lefthand-side that shows all the folders with an attribute 'publish' defined, and, we'll show their 'nickname' or 'displayname' properties in place of 'title_or_id' if those are defined. So far, this is easy. However, we also want to arbitrarily sort the folders and while the below code works, it doesn't do exactly what I want. We define an integer property 'sort_value', then sort based on sort_value and alternatively title_or_id. This works, sort of: id sort_value Folder1 (100) Folder2 (200) Folder3 (300) FolderA (not defined) FolderB (1) FolderC (2) The folders in Folder3 will be sorted as FolderB (1) FolderC (2) FolderA (300) <--- inherited from Folder3 above. This is not awful, but I know it's not the right way to do things. How can I improve it? Thanks to everyone involved with Zope! Sorry to be so dense, Ben Chapman --- START SAMPLE CODE --- <dtml-comment> Menu builder version one. This is confusing. Even though I tell it to build this list from the objectValues in the current folder (PARENTS[0]), it still inherits sort_value from above when it's doing a sort. I'm not sure how to turn off sort_value. I'm not sure how this would affect us very often, but it is still less than ideal. BJC 03/26/2002 </dtml-comment> <dtml-in expr="PARENTS[0].objectValues(['Folder','TUFolder','Photo Folder','TULawPerson','Squishdot Site'])" sort="sort_value,title_or_id" skip_unauthorized > <dtml-if publish> <p><a class="menu" href="&dtml-absolute_url;" title="&dtml-sort_value;"> <dtml-if "hasProperty('nickname')"> <dtml-var nickname> <dtml-elif "hasProperty('displayname')"> <dtml-var displayname> <dtml-else> <dtml-var title_or_id> </dtml-if nickname> </a></p> </dtml-if publish> </dtml-in folder tufolder photofolder> --- END CODE SEGMENT --- -- Benjamin J. Chapman benjamin-chapman@utulsa.edu 918/631-2405 Director of Computing Resources TU College of Law http://www.utulsa.edu/law/support/ Send computing support requests to: support@mail.law.utulsa.edu
From: "Ben Chapman" <benjamin-chapman@utulsa.edu>
However, we also want to arbitrarily sort the folders and while the below code works, it doesn't do exactly what I want. We define an integer property 'sort_value', then sort based on sort_value and alternatively title_or_id.
Several ways of doing this. The best ones all involve using a ZCatalog to index all objects and make a query on that ZCatalog. For code example you can checkout my LUF content management system. http://www.zope.org/Members/regebro/ It's a trivial hack done in a week or so, but it worked. :) It works by a "Navigator" object. You place that menu in the folder you want to appear in a menu, and enter the name of the menu in the navigation object, together with the navigation title and navigation order. It then indexes itself in a Navigation ZCatalog, which you can query to build menues. I can't help you with it otherwise, I moved my last LUF CMS site over to Easy Publisher a couple of weeks ago. EP uses the same principal of indexing the navigatable objects in a ZCatalog, but instead of creating special objects we use objects that subclass from a Navigatable mixin class, that keeps track of all the navigation information.
Ahh, bitten by acquisition. But, I think we can actually use acquistion here to defeat itself. Put a python script named "getSortValue" wherever this dtml method is. Put the following in it: return context.getProperty('sort_value', 0) Then change your sort attribute of your dtml-in to: sort="getSortValue,title_or_id" The trick here is that getProperty doesn't acquire values. The second argument is the default if the property is not defined on the object. You should set this lower than the lowest possible sort_value. hth, -Casey Ben Chapman wrote:
Everyone:
I know that this has come up over and over on the list, I just still can't get a handle on it. If I could get some good information from the list, I would like to put together a HOW-TO on this, because I think it's a common goal. I have folders that contain folders and other objects. I want to build a menu along the lefthand-side that shows all the folders with an attribute 'publish' defined, and, we'll show their 'nickname' or 'displayname' properties in place of 'title_or_id' if those are defined. So far, this is easy.
However, we also want to arbitrarily sort the folders and while the below code works, it doesn't do exactly what I want. We define an integer property 'sort_value', then sort based on sort_value and alternatively title_or_id.
This works, sort of:
[snip]
Ben Chapman writes:
... custom sorting over (potentially) undefined property .... This works, sort of:
id sort_value
Folder1 (100) Folder2 (200) Folder3 (300) FolderA (not defined) FolderB (1) FolderC (2)
The folders in Folder3 will be sorted as
FolderB (1) FolderC (2) FolderA (300) <--- inherited from Folder3 above.
This is not awful, but I know it's not the right way to do things. How can I improve it? You have 2 subproblems:
* checking whether an object has a property for properties you can use "hasProperty" (see Zope Help -> API Reference -> PropertyManager) otherwise, you need "aq_base" (see the mailing list archives) * define a custom sort function handling the case that a sort value is undefined. It is not clear a priori, how this should be handled (see the Python library documentation for the list method "sort" for details on custom sort functions). Dieter
participants (4)
-
Ben Chapman -
Casey Duncan -
Dieter Maurer -
Lennart Regebro