[Zope] Variable substitution of <dtml-in> Attributes

Adam Warner lists@consulting.net.nz
07 Nov 2001 01:36:01 +1300


On Tue, 2001-11-06 at 19:04, Danny William Adair wrote:

> This is definitely not possible with the current dtml-in tag.
> The dtml-tag does not provide "reverse_expr=", "sort_expr=", and so forth 
> (like to the dtml-tree tag).

> b) use a python script :-)

Thanks for the info Danny. You're right about using a Python script.
Here is the original dtml method that I wrote:


<dtml-if expr="_.len(PARENTS)>3">
   <ul><li><a href="..">Up one level...</a></li></ul>
</dtml-if>

<dtml-comment>
 I can't just have unsorted list items above and below because <ul></ul> is
 a breach of HTML 4.01!
</dtml-comment>

<dtml-call "REQUEST.set('count', 0)">
<dtml-in expr="PARENTS[0].objectValues('Folder')" sort=id>

  <dtml-if expr="id!='Files'">
    <dtml-call "REQUEST.set('count', count+1)">
    <dtml-if expr="count==1">
      <ul>
    </dtml-if>
    <li><a href="&dtml-absolute_url;"><dtml-var expr="underscore2space(foldername=id)"></a><br /><br /></li>
    </dtml-if>
</dtml-in>
<dtml-if expr="count>0">
  </ul>
</dtml-if>



This is the equivalent functionality written as a Python script:


# Import a standard function, and get the HTML request and response objects.
from Products.PythonScripts.standard import html_quote
request = container.REQUEST
RESPONSE =  request.RESPONSE

import string

if len(request.PARENTS)>3:
   print '<ul><li><a href="..">Up one level...</a></li></ul>'

# Note: I can't just have unsorted list items above and below because <ul></ul> is
# a breach of HTML 4.01!

folders=request.PARENTS[0].objectValues('Folder')
folderids=[element.id for element in folders]
folderurls=[element.absolute_url() for element in folders]

#Now I'm going to generate a dictionary with the folder ids as the keys
folderdict={}
for key, value in map(None, folderids, folderurls):
   folderdict[key]=value

#Remove folder 'Files' from the menu
try:
   del folderdict['Files']
except:
   pass

sortedids=folderdict.keys()
sortedids.sort()

if len(folderdict.keys())>0:
   print '<ul>'
   for folder in sortedids:
      nounderscoreid=string.replace(folder, '_', ' ')
      print '<li><a href="'+folderdict[folder]+'">'+nounderscoreid+'</a><br /><br /></li>'
   print '</ul>'

return printed



I think the dtml method stacks up surprisingly well! However I had the
problem that I couldn't expand the dtml method to do other type of
sorting. This solves that problem.

If anyone can show a better rewrite of my Python script I won't be
offended.


This isn't an essential question but I noticed if:

folders=[<Folder instance at 88d95d0>, <Folder instance at 8abd0d8>,
<Folder instance at 8801408>,...]

print folders[1].id

gives me the id of the second element. But:

print folders[1].id() gives me the error:

Error Type: TypeError
Error Value: object of type 'string' is not callable

This seems to be inconsistent with:

print folders[1].absolute_url()

If someone could point out why folders[1].id() doesn't work I'd
appreciate it.

Regards,
Adam