[Zope] HOWTO (but to be improved) - linking to neighbours
Marcin Kasperski
Marcin.Kasperski@softax.com.pl
Wed, 16 Aug 2000 12:46:00 +0200
[ Below I describe my solution to the problem which seems to me to be
fairly frequent. Maybe someone is interested, maybe someone can show me
better (faster, shorter) solution ]
* Problem
The problem: while presenting some page, I would like to automagically
add links to 'previous' and 'next' page in the same directory. Say you
organize a bunch of HOWTOS and you would like to let the people navigate
via 'next' links - without going back go table of contents.
* Idea
What I really need is to calculate identifiers of 'neighbours' of my
page in its container. I do have id of the current page, I can easily
got list of all identifiers in the container. So I can just scan this
list, find my id and read previous and next element. Transforming it
into hyperlink is natural.
* Code
First I create the following Python Method (could be External Method as
well). The method returns tuple (previous_id, next_id) substituting ''
if there is no such element (we are at the start or at the end).
----------
Name: neighbours
Parameters: self,myId,allIds
Contents:
position = 0
for x in range(0, len(allIds)):
if allIds[x] == myId:
position = x
break
else:
raise 'Internal inconsistency: id ' + str(myId) + ' does not belong
to list ' + str(allIds)
left = ''
right = ''
if position > 0:
left = allIds[position - 1]
if position < len(allIds) - 1:
right = allIds[position + 1]
return (left, right)
----------
Then I add standard_html_footer DTML Method to the directory with my
iterated items. I put there sth like that (of course presentation can
vary, 'MyHowto' is the metatype of objects I iterate over, as you can
see I call original footer after writting my navigational details):
---------
<p>
<dtml-let allIds="PARENTS[0].objectIds(['MyHowto'])"
myId=id
neigh="neighbours(myId,allIds)">
<table border="0" width="90%" align="center"><tr>
<td width="33%" align="left">
<dtml-if "neigh[0] != ''">
<a href="<dtml-var "neigh[0]">">Previous</a>
<dtml-else>
</dtml-if>
</td>
<td width="33%" align="center">
<a href="<dtml-var howto_index url>">Table of Contents</a>
</td>
<td width="33%" align="right">
<dtml-if "neigh[1] != ''">
<a href="<dtml-var "neigh[1]">">Next</a>
<dtml-else>
</dtml-if>
</td>
</tr></table>
</dtml-let>
<dtml-with "PARENTS[1]">
<dtml-var standard_html_footer>
</dtml-with>
----------
(by the way I do not know why I need 'myId=id' in <let> - but removing
it and putting id on the neighbours parameters list does not work)
* Unsolved problems
There are two important unsolved problems:
- efficiency - I perform linear scan which can be expensive if my
directory contains a lot of objects (I do not know good method to solve
it - I would need some help from Folder class)
- order - if I need to present my objects in some order other than
default, I would need to sort allIds in some way (probably I would need
youse objectValues instead of objectIds)
* Minor tricks
The python method I wrote is generic, I use the same method for two
different folders.
In fact I worked around the order problem for the very simple case -
presenting everything in reverse order. I just exchanged neigh[0] and
neigh[1] in standard_html_footer.
-- Serwis nie tylko mieszkaniowy: http://www.mk.w.pl
|
| You have the right to say how long each requirement will take you to
| implement, and to revise estimates given experience. (Ken Beck's
| Second Developer Right)