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
for Python expressions, string literals, and paths.
"""
__version__='$Revision: 1.30 $'[11:-2]
__version__='$Revision: 1.31 $'[11:-2]
import re, sys
from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
......@@ -272,7 +272,8 @@ class DeferExpr:
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['TraversalRequestNameStack'] = path = path[:] # Copy!
......@@ -290,6 +291,10 @@ def restrictedTraverse(self, path, securityManager,
__traceback_info__ = REQUEST
name = path.pop()
if isinstance(name, TupleType):
object = apply(object, name)
continue
if name[0] == '_':
# Never allowed in a URL.
raise AttributeError, name
......
......@@ -17,21 +17,21 @@ A TALES Iterator with the ability to use first() and last() on
subpaths of elements.
"""
__version__='$Revision: 1.1 $'[11:-2]
__version__='$Revision: 1.2 $'[11:-2]
import TALES
from Expressions import restrictedTraverse, Undefs, getSecurityManager
from string import split
class Iterator(TALES.Iterator):
def __bobo_traverse__(self, REQUEST, name):
if name in ('first', 'last'):
path = REQUEST['TraversalRequestNameStack']
names = list(path)
del path[:]
names.reverse()
return getattr(self, name)(names)
path[:] = [tuple(names)]
return getattr(self, name)
def same_part(self, name, ob1, ob2):
if name is None:
return ob1 == ob2
......
......@@ -42,6 +42,10 @@ repeat: Repeat an element
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
of repetitions.
......@@ -65,6 +69,15 @@ repeat: Repeat an element
attribute access to get the information, for example,
'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
Iterating over a sequence of strings::
......@@ -96,3 +109,12 @@ repeat: Repeat an element
</td>
</tr>
</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