Skip to content

Commit

Permalink
Add a @@display-file view which doesn't set Content-Disposition, so w…
Browse files Browse the repository at this point in the history
…e don't force download of images, for example.

svn path=/plone.namedfile/trunk/; revision=48720
  • Loading branch information
lentinj committed Apr 11, 2011
1 parent c522c1f commit 6537a9e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/HISTORY.txt
Expand Up @@ -7,6 +7,10 @@ Changelog
* Declare dependency on plone.rfc822 >= 1.0b2 (for IPrimaryField).
[davisagli]

* Add a @@display-file view which doesn't set Content-Disposition, so we don't
force download of images, for example.
[lentinj]

1.0b7 - 2011-03-22
------------------

Expand Down
22 changes: 18 additions & 4 deletions plone/namedfile/browser.py
Expand Up @@ -40,6 +40,14 @@ def publishTraverse(self, request, name):
return self

def __call__(self):
file = self._getFile()

if not self.filename:
self.filename = getattr(file, 'filename', self.fieldname)
set_headers(file, self.request.response, filename=self.filename)
return stream_data(file)

def _getFile(self):
if not self.fieldname:
info = IPrimaryFieldInfo(self.context, None)
if info is None:
Expand All @@ -53,9 +61,15 @@ def __call__(self):
if file is None:
raise NotFound(self, self.fieldname, self.request)

if not self.filename:
self.filename = getattr(file, 'filename', self.fieldname)

set_headers(file, self.request.response, filename=self.filename)
return file

class DisplayFile(Download):
"""Display a file, via ../context/@@display-file/fieldname/filename
Same as Download, however in this case we don't set the filename so the
browser can decide to display the file instead.
"""
def __call__(self):
file = self._getFile()
set_headers(file, self.request.response)
return stream_data(file)
7 changes: 7 additions & 0 deletions plone/namedfile/configure.zcml
Expand Up @@ -11,6 +11,13 @@
permission="zope2.View"
/>

<browser:page
name="display-file"
for="*"
class=".browser.DisplayFile"
permission="zope2.View"
/>

<include zcml:condition="installed z3c.blobfile" file="z3c-blobfile.zcml" />
<include zcml:condition="installed plone.supermodel" file="handler.zcml" />
<include zcml:condition="installed plone.rfc822" file="marshaler.zcml" />
Expand Down
85 changes: 81 additions & 4 deletions plone/namedfile/usage.txt
Expand Up @@ -191,10 +191,11 @@ Note that is possible for force the mimetype:
Download view
-------------

This package also comes with a view that can be used to download files. To
use it, link to ../context-object/@@download/fieldname, where `fieldname` is
the name of the attribute on the context-object where the named file is
stored.
This package also comes with a view that can be used to download files. This
will set Content-Disposition to ensure the browser downloads the file rather
than displaying it. To use it, link to ../context-object/@@download/fieldname,
where `fieldname` is the name of the attribute on the context-object where the
named file is stored.

We will test this with a dummy request, faking traversal.

Expand Down Expand Up @@ -266,6 +267,82 @@ We will test this with a dummy request, faking traversal.
'image/foo'
'attachment; filename="zpt.gif"'

Display-file view
-------------

This package also comes with a view that can be used to display files in the
browser. To use it, link to ../context-object/@@display-file/fieldname, where
`fieldname` is the name of the attribute on the context-object where the named
file is stored.

We will test this with a dummy request, faking traversal.

>>> from plone.namedfile.browser import DisplayFile
>>> from zope.publisher.browser import TestRequest

>>> request = TestRequest()
>>> display_file = DisplayFile(container, request).publishTraverse(request, 'simple')
>>> display_file()
'dummy test data'
>>> request.response.getHeader('Content-Length')
'15'
>>> request.response.getHeader('Content-Type')
'text/plain'
>>> request.response.getHeader('Content-Disposition')

>>> if HAVE_BLOBS:
... request = TestRequest()
... display_file = DisplayFile(container, request).publishTraverse(request, 'blob')
... data = display_file()
... print repr(isinstance(data, file))
... print repr(data.read())
... print repr(request.response.getHeader('Content-Length'))
... print repr(request.response.getHeader('Content-Type'))
... print repr(request.response.getHeader('Content-Disposition'))
... else:
... print repr(True)
... print repr('dummy test data')
... print repr('15')
... print repr('text/plain')
... print repr(None)
True
'dummy test data'
'15'
'text/plain'
None

>>> request = TestRequest()
>>> display_file = DisplayFile(container, request).publishTraverse(request, 'image')
>>> display_file() == zptlogo
True

>>> request.response.getHeader('Content-Length')
'341'
>>> request.response.getHeader('Content-Type')
'image/foo'
>>> request.response.getHeader('Content-Disposition')

>>> request = TestRequest()
>>> if HAVE_BLOBS:
... display_file = DisplayFile(container, request).publishTraverse(request, 'blobimage')
... data = display_file()
... print repr(isinstance(data, file))
... print repr(data.read() == zptlogo)
... print repr(request.response.getHeader('Content-Length'))
... print repr(request.response.getHeader('Content-Type'))
... print repr(request.response.getHeader('Content-Disposition'))
... else:
... print repr(True)
... print repr(True)
... print repr('341')
... print repr('image/foo')
... print repr(None)
True
True
'341'
'image/foo'
None

Specifying the primary field
----------------------------

Expand Down

0 comments on commit 6537a9e

Please sign in to comment.