[Zope] multi key dtml-in sorts

Dr. Ross Lazarus rossl@med.usyd.edu.au
Fri, 07 Apr 2000 16:06:22 +1000


<dtml-in "foo" sort=akey> is really handy as everyone knows.

I needed to sort on multiple fields for an application I have, so I
hacked at 
lib/python/DocumentTemplate/DT_In.py so the following now appears to
work

<dtml-in "foo" sort=akey1,akey2,akey3> 

This is only VERY lightly tested which is why I'm posting it here. If
anyone needs this, please try it - but NOT on a production server.
Please let me know how you go. If it proves useable, I'd suggest it
eventually might be worth considering for a future release since without
this patch, if you need multiple keys you have to fake them in your data
which is cruel..

I haven't even tried the mapping version code and I suspect that it's
unlikely to work, but, in the spirit of opensource, for those of a self
destructive urge and strong stomach, here's the diff. 

This is highly experimental..PLEASE don't even think about using this
unless you're willing to clean up any mess that results. All care, no
responsibility.

Note that the patch will rename the original method to osort_sequence so
you can easily revert to normal operation.

390c390
< from string import find, atoi, join
---
> from string import find, atoi, join, split
703c703,759
<     def sort_sequence(self, sequence):
---
>     def sort_sequence(self, sequence):
>         '''
>         hacks to support multiple sort fields
>         april 7 ross lazarus rossl@med.usyd.edu.au
>         eg <dtml in "foo" sort=akey,anotherkey>
>         all keys are converted to strings 
>         since integers and so on can't be appended...
>         Highly experimental and dangerous - use at your own risk
>         Please let me know how it goes - I'll submit a patch to
>         the collector when enough people have tried it.
>         '''
> 
>         sort=self.sort
>         sortfields = split(sort,',')   # multi sort = key1,key2 
>         multsort = len(sortfields) > 1 # is multiple sort
>         mapping=self.mapping
>         isort=not sort
>         s=[]
>         for client in sequence:
>             k = ''
>             if type(client)==TupleType and len(client)==2:
>                 if isort: k=client[0]
>                 v=client[1]
>             else:
>                 if isort: k=client
>                 v=client
> 
>             if sort:
>                  if multsort: # more than one sort key ?
>                     for sk in sortfields:
>                           if mapping: # can't do this?
>                                akey = v[sk] # str hack - not needed if string?
>                           else:
>                                akey =getattr(v, sk)
>                           if not basic_type(akey):           
>                               try: akey=akey()
>                               except: pass
>                           if type(akey) <> type(''):
>                                akey = str(akey)
>                           k = k + akey    
>                  else: # original code  
>                      if mapping: k=v[sort]
>                      else: k=getattr(v, sort)
>                      if not basic_type(k):           
>                          try: k=k()
>                          except: pass
> 
>             s.append((k,client))
> 
>         s.sort()
> 
>         sequence=[]
>         for k, client in s:
>              sequence.append(client)
>         return sequence
> 
>     def osort_sequence(self, sequence):
-- 

Dr Ross Lazarus
Associate Professor and Sub-Dean for Information Technology
Faculty of Medicine, Room 126A, A27, University of Sydney,
Camperdown, NSW 2006, Australia
Tel: (+61 2) 93514429   Mobile: +61414872482  
Fax: (+61 2) 93516646   Email: rossl@med.usyd.edu.au