[Zope-Checkins]
SVN: Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/
Bring back the ability to say some_iterator/first/bar and
some_iterator/last/foo
Philipp von Weitershausen
philikon at philikon.de
Tue May 23 04:40:06 EDT 2006
Log message for revision 68249:
Bring back the ability to say some_iterator/first/bar and some_iterator/last/foo
by providing PathIterator which (every much like the old PathIterator.Iterator
class) handles its own traversal (only now we use the Zope 3 traversal hooks).
Changed:
U Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/Expressions.py
U Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/PathIterator.py
U Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/tests/testHTMLTests.py
-=-
Modified: Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/Expressions.py
===================================================================
--- Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/Expressions.py 2006-05-22 23:59:14 UTC (rev 68248)
+++ Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/Expressions.py 2006-05-23 08:40:04 UTC (rev 68249)
@@ -17,16 +17,18 @@
$Id$
"""
+from zope.interface import implements
from zope.tales.tales import ExpressionEngine, Context, Iterator
from zope.tales.expressions import PathExpr, StringExpr, NotExpr
from zope.tales.expressions import DeferExpr, SubPathExpr
from zope.tales.expressions import SimpleModuleImporter
from zope.tales.pythonexpr import PythonExpr
+from zope.traversing.interfaces import ITraversable
from zope.traversing.adapters import traversePathElement
from zope.contentprovider.tales import TALESProviderExpression
+import OFS.interfaces
from zExceptions import NotFound, Unauthorized
-from OFS.interfaces import ITraversable
from Products.PageTemplates import ZRPythonExpr
from Products.PageTemplates.DeferExpr import LazyExpr
from Products.PageTemplates.GlobalTranslationService import getGlobalTranslationService
@@ -52,7 +54,7 @@
while path_items:
name = path_items.pop()
- if ITraversable.providedBy(object):
+ if OFS.interfaces.ITraversable.providedBy(object):
try:
object = object.restrictedTraverse(name)
except (NotFound, Unauthorized), e:
@@ -82,8 +84,7 @@
context = self.contexts.get('context')
return getGlobalTranslationService().translate(
domain, msgid, mapping=mapping,
- context=context,
- default=default)
+ context=context, default=default)
class ZopeEngine(ExpressionEngine):
@@ -97,8 +98,6 @@
class ZopeIterator(Iterator):
- __allow_access_to_unprotected_subobjects__ = True
-
# The things below used to be attributes in
# ZTUtils.Iterator.Iterator, however in zope.tales.tales.Iterator
# they're methods. We need BBB on the Python level so we redefine
@@ -122,27 +121,23 @@
def item(self):
return super(ZopeIterator, self).item()
- # The following things were in ZTUtils.Iterator.Iterator but
- # aren't anymore in zope.tales.tales.Iterator. For a good reason.
- # They're just insane.
-
+ # This method was on the old ZTUtils.Iterator.Iterator class but
+ # isn't part of the spec. We'll support it for a short
+ # deprecation period.
# BBB 2005/05/01 -- to be removed after 12 months
-
@property
@deprecate("The 'nextIndex' method has been deprecated and will disappear "
"in Zope 2.12. Use 'iterator.index+1' instead.")
def nextIndex(self):
return self.index + 1
- @deprecate("The 'first' method has been deprecated and will disappear "
- "in Zope 2.12. Use the 'start' property instead.")
+ # 'first' and 'last' are Zope 2 enhancements to the TALES iterator
+ # spec. See help/tal-repeat.stx for more info
def first(self, name=None):
if self.start:
return True
- return not self.same_part(name, self._last, self.item)
+ return not self.same_part(name, self._last_item, self.item)
- @deprecate("The 'last' method has been deprecated and will disappear "
- "in Zope 2.12. Use the 'end' property instead.")
def last(self, name=None):
if self.end:
return True
@@ -154,9 +149,47 @@
no = object()
return getattr(ob1, name, no) == getattr(ob2, name, no) is not no
+ # 'first' needs to have access to the last item in the loop
+ def next(self):
+ if self._nextIndex > 0:
+ self._last_item = self.item
+ return super(ZopeIterator, self).next()
+
+class PathIterator(ZopeIterator):
+ """A TALES Iterator with the ability to use first() and last() on
+ subpaths of elements."""
+ # we want to control our own traversal so that we can deal with
+ # 'first' and 'last' when they appear in path expressions
+ implements(ITraversable)
+
+ def traverse(self, name, furtherPath):
+ if name in ('first', 'last'):
+ method = getattr(self, name)
+ # it's important that 'name' becomes a copy because we'll
+ # clear out 'furtherPath'
+ name = furtherPath[:]
+ if not name:
+ name = None
+ # make sure that traversal ends here with us
+ furtherPath[:] = []
+ return method(name)
+ return getattr(self, name)
+
+ def same_part(self, name, ob1, ob2):
+ if name is None:
+ return ob1 == ob2
+ if isinstance(name, basestring):
+ name = name.split('/')
+ try:
+ ob1 = boboTraverseAwareSimpleTraverse(ob1, name, None)
+ ob2 = boboTraverseAwareSimpleTraverse(ob2, name, None)
+ except LookupError:
+ return False
+ return ob1 == ob2
+
def createZopeEngine():
e = ZopeEngine()
- e.iteratorFactory = ZopeIterator
+ e.iteratorFactory = PathIterator
for pt in ZopePathExpr._default_type_names:
e.registerType(pt, ZopePathExpr)
e.registerType('string', StringExpr)
Modified: Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/PathIterator.py
===================================================================
--- Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/PathIterator.py 2006-05-22 23:59:14 UTC (rev 68248)
+++ Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/PathIterator.py 2006-05-23 08:40:04 UTC (rev 68249)
@@ -18,8 +18,8 @@
"""
import zope.deferredimport
zope.deferredimport.deprecated(
- "It has been renamed to ZopeIterator and moved to the "
+ "It has been renamed to PathIterator and moved to the "
"Products.PageTemplates.Expressions module. This reference will be "
"gone in Zope 2.12.",
- PathIterator = "Products.PageTemplates.Expressions:ZopeIterator"
+ PathIterator = "Products.PageTemplates.Expressions:PathIterator"
)
Modified: Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/tests/testHTMLTests.py
===================================================================
--- Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/tests/testHTMLTests.py 2006-05-22 23:59:14 UTC (rev 68248)
+++ Zope/branches/ajung-zpt-end-game/lib/python/Products/PageTemplates/tests/testHTMLTests.py 2006-05-23 08:40:04 UTC (rev 68249)
@@ -125,15 +125,6 @@
self.assert_expected(self.folder.t, 'Loop1.html')
def checkFancyLoop(self):
- # XXX This checks among others for a feature of the
- # PathIterator which lets you do something like this in a path
- # expr: iterator/last/bla. This would check whether the
- # current item in the iteration was the last one with a
- # particular 'bla' attribute value. I wonder whether anyone
- # actually needs this? I vote for ripping it out. We can
- # provide BBB for a certain deprecation period by enabling a
- # specialized ITraversable adapter for ZopeIterator that works
- # similar to the old PathIterator.
self.assert_expected(self.folder.t, 'Loop2.html')
def checkGlobalsShadowLocals(self):
More information about the Zope-Checkins
mailing list