Skip to content

Commit

Permalink
Merge pull request #18 from plone/issue_16_1x
Browse files Browse the repository at this point in the history
Issue 16 1.0.x - Fix incompatibilities with five.pt and chameleon
  • Loading branch information
mauritsvanrees committed Nov 26, 2015
2 parents 8e4ea73 + 59e8d2b commit 9022a3d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 10 deletions.
5 changes: 5 additions & 0 deletions docs/HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Changelog

Fixes:

- Fixed incompatibilities with five.pt and chameleon (closes `#16`_).
[rodfersou, maurits]

- Fixed 404 NotFound error when accessing image scales via webdav.
[maurits]

Expand Down Expand Up @@ -239,3 +242,5 @@ Fixes:

- Initial package structure.
[zopeskel]

.. _`#16`: https://github.com/plone/plone.app.imaging/issues/16
51 changes: 46 additions & 5 deletions src/plone/app/imaging/scaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,54 @@ def publishTraverse(self, request, name):
raise NotFound(self, name, self.request)

def traverse(self, name, furtherPath):
""" used for path traversal, i.e. in zope page templates """
"""Used for path traversal, i.e. in zope page templates.
This method is called when you have something like this in a
page template:
<img tal:replace="structure context/@@images/image/mini" />
What then happens during traversal, is that the traverse method
gets called twice: we first traverse to name='image' and then to
name='mini'. The traversal is done by the Zope page template
machinery. There are differences between standard
zope.pagetemplate and five.pt (chameleon). Roughly, it happens
like follows.
With zope.pagetemplate:
view = <the @@images view for this context>
new_view = view.traverse('image', ['mini'])
tag = new_view.traverse('mini', [])
And with five.pt:
view = <the @@images view for this context>
new_view = view.traverse('image', ('mini', ))
tag = new_view.traverse('mini', ())
"""
if not furtherPath:
if hasattr(self, '_image_fieldname'):
# We have been here before, with the current name argument in
# the furtherPath.
scale_name = name
name = self._image_fieldname
else:
scale_name = None
field = self.context.getField(name)
return field.get(self.context).tag()
image = self.scale(name, furtherPath.pop())
if image is not None:
return image.tag()
image = self.scale(name, scale_name)
if image is not None:
return image.tag()
raise TraversalError(self, name)
field = self.field(name)
if field is not None:
# We have an image field of this name. Store the scale name on
# self and return it. Since there is a furtherPath, we will get
# called again in a moment, with this same 'self' with the
# _image_fieldname attribute, and with the current furtherPath as
# name, and an empty furtherPath.
self._image_fieldname = name
return self
raise TraversalError(self, name)

def make(self, info):
Expand Down
51 changes: 46 additions & 5 deletions src/plone/app/imaging/tests/test_new_scaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,19 @@
from unittest import TestSuite, makeSuite


class ImageTraverseTests(ImagingTestCase):
class ImageStandardTraverseTests(ImagingTestCase):
# Note: this class is subclassed by ImageChameleonTraverseTests, which
# inherits our tests but uses a different traverser. We use the standard
# Zope pagetemplate traverser.

def traverser(self, view, path=''):
# Standard Zope page template traversal uses a list as path.
# This is a simplified version specialised for the scaling view.
stack = path.split('/')
while stack:
name = stack.pop(0)
view = view.traverse(name, stack)
return view

def afterSetUp(self):
self.data = self.getImage()
Expand All @@ -16,9 +28,7 @@ def afterSetUp(self):

def traverse(self, path=''):
view = self.image.unrestrictedTraverse('@@images')
stack = path.split('/')
name = stack.pop(0)
tag = view.traverse(name, stack)
tag = self.traverser(view, path)
base = self.image.absolute_url()
expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \
r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />' % base
Expand Down Expand Up @@ -69,6 +79,35 @@ def testCustomSizeChange(self):
self.assertEqual(height, 42)
self.assertNotEqual(uid1, uid2, 'scale not updated?')


class ImageChameleonTraverseTests(ImageStandardTraverseTests):
# This class inherits all test methods from its parent, but uses the
# Chameleon/five.pt traverser.

def traverser(self, view, path=''):
# five.pt/chameleon uses a tuple as path. This is a simplified
# version of BoboAwareZopeTraverse.traverse from five.pt.expressions,
# specialised for the scaling view.
path_items = tuple(path.split('/'))
length = len(path_items)
if length:
i = 0
while i < length:
name = path_items[i]
i += 1
view = view.traverse(name, path_items[i:])
return view


class ImageTagTests(ImagingTestCase):

def afterSetUp(self):
self.data = self.getImage()
self.image = self.folder[self.folder.invokeFactory(
'Image', id='foo', image=self.data)]
field = self.image.getField('image')
self.available = field.getAvailableSizes(self.image)

def testViewTagMethod(self):
folder = self.folder
image = folder['foo']
Expand Down Expand Up @@ -315,7 +354,9 @@ def testGetImageSize(self):

def test_suite():
return TestSuite([
makeSuite(ImageTraverseTests),
makeSuite(ImageStandardTraverseTests),
makeSuite(ImageChameleonTraverseTests),
makeSuite(ImageTagTests),
makeSuite(ImagePublisherTests),
makeSuite(ScalesAdapterTests),
])

0 comments on commit 9022a3d

Please sign in to comment.