Commit 78d70b09 authored by Evan Simpson's avatar Evan Simpson

Fix first() and last() to work with Zope security, document them.

parent 56e64abe
...@@ -17,7 +17,7 @@ Page Template-specific implementation of TALES, with handlers ...@@ -17,7 +17,7 @@ Page Template-specific implementation of TALES, with handlers
for Python expressions, string literals, and paths. for Python expressions, string literals, and paths.
""" """
__version__='$Revision: 1.30 $'[11:-2] __version__='$Revision: 1.31 $'[11:-2]
import re, sys import re, sys
from TALES import Engine, CompilerError, _valid_name, NAME_RE, \ from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
...@@ -272,7 +272,8 @@ class DeferExpr: ...@@ -272,7 +272,8 @@ class DeferExpr:
def restrictedTraverse(self, path, securityManager, def restrictedTraverse(self, path, securityManager,
get=getattr, has=hasattr, N=None, M=[]): get=getattr, has=hasattr, N=None, M=[],
TupleType=type(()) ):
REQUEST = {'path': path} REQUEST = {'path': path}
REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy! REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy!
...@@ -290,6 +291,10 @@ def restrictedTraverse(self, path, securityManager, ...@@ -290,6 +291,10 @@ def restrictedTraverse(self, path, securityManager,
__traceback_info__ = REQUEST __traceback_info__ = REQUEST
name = path.pop() name = path.pop()
if isinstance(name, TupleType):
object = apply(object, name)
continue
if name[0] == '_': if name[0] == '_':
# Never allowed in a URL. # Never allowed in a URL.
raise AttributeError, name raise AttributeError, name
......
...@@ -17,21 +17,21 @@ A TALES Iterator with the ability to use first() and last() on ...@@ -17,21 +17,21 @@ A TALES Iterator with the ability to use first() and last() on
subpaths of elements. subpaths of elements.
""" """
__version__='$Revision: 1.1 $'[11:-2] __version__='$Revision: 1.2 $'[11:-2]
import TALES import TALES
from Expressions import restrictedTraverse, Undefs, getSecurityManager from Expressions import restrictedTraverse, Undefs, getSecurityManager
from string import split
class Iterator(TALES.Iterator): class Iterator(TALES.Iterator):
def __bobo_traverse__(self, REQUEST, name): def __bobo_traverse__(self, REQUEST, name):
if name in ('first', 'last'): if name in ('first', 'last'):
path = REQUEST['TraversalRequestNameStack'] path = REQUEST['TraversalRequestNameStack']
names = list(path) names = list(path)
del path[:]
names.reverse() names.reverse()
return getattr(self, name)(names) path[:] = [tuple(names)]
return getattr(self, name) return getattr(self, name)
def same_part(self, name, ob1, ob2): def same_part(self, name, ob1, ob2):
if name is None: if name is None:
return ob1 == ob2 return ob1 == ob2
......
...@@ -42,6 +42,10 @@ repeat: Repeat an element ...@@ -42,6 +42,10 @@ repeat: Repeat an element
o *end* - true for the ending, or final, repetition. o *end* - true for the ending, or final, repetition.
o *first* - true for the first item in a group - see note below
o *last* - true for the last item in a group - see note below
o *length* - length of the sequence, which will be the total number o *length* - length of the sequence, which will be the total number
of repetitions. of repetitions.
...@@ -65,6 +69,15 @@ repeat: Repeat an element ...@@ -65,6 +69,15 @@ repeat: Repeat an element
attribute access to get the information, for example, attribute access to get the information, for example,
'python:repeat['item'].start'. 'python:repeat['item'].start'.
Note that 'first' and 'last' are intended for use with sorted
sequences. They try to divide the sequence into group of items
with the same value. If you provide a path, then the value
obtained by following that path from a sequence item is used for
grouping, otherwise the value of the item is used. You can
provide the path by passing it as a parameter, as in
"python:repeat['item'].first('color')", or by appending it to the
path from the repeat variable, as in "repeat/item/first/color".
Examples Examples
Iterating over a sequence of strings:: Iterating over a sequence of strings::
...@@ -96,3 +109,12 @@ repeat: Repeat an element ...@@ -96,3 +109,12 @@ repeat: Repeat an element
</td> </td>
</tr> </tr>
</table> </table>
Objects (already sorted by meta-type) in groups by meta-type::
<table border="1">
<tr tal:repeat="object objects">
<td><span tal:condition="repeat/object/first/meta_type"
tal:replace="object/meta_type">Meta Type</span></td>
</tr>
</table>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment