Forums / Developer / Link directly to a PDF - to make it open in the browser

Link directly to a PDF - to make it open in the browser

Author Message

Jordan Hirsch

Thursday 01 July 2010 2:36:38 pm

I'm trying to construct a link to a binary file (a PDF) that's in content class File. When I use the standard method of constructing the link via "content/download" the browser prompts me to download the file. However, I need the PDF to open in the browser window - this is the behavior I see if I link to a PDF file directly.

I tried to link directly to the file using this method:

href={concat('/', $attribute.content.filepath)|ezroot()}

But I get a 404 on the resulting link (which looks like /var/sitename/original/application/etc.) In addition, most of the files in my var folder don't have file extensions, so I'm not sure that the browser would even know what to do if I linked directly to one of the files (Firefox in particular tends not to recognize PDFs properly without their extension, at least I've seen that behavior before).

Is there a recommended method to link directly to a binary file without using content/download to force the browser to download the file?

Thanks!

UPDATE: I tried setting the PassThroughSettings in file.ini, but it didn't seem to have any effect - the PDF still downloads instead of opening in the browser when I use the content/download link.

[PassThroughSettings]
ContentDisposition[application/pdf]=inline
ContentDisposition[application/x-pdf]=inline

I resolved the 404 when linking directly to the file in var/ by changing my RewriteRules, but since the vast majority of files in that folder are missing their file extensions, the browser doesn't understand how to open the file without ".pdf" at the end. Any idea how I can restore those missing extensions?

UPDATE 2: Apparently setting the ContentDisposition settings was sufficient, but for some reason the change didn't take until I cleared the cache through the admin, as opposed to command-line (not sure why). If you're curious about the missing extensions in the filenames, it's a known issue which was supposedly resolved in 4.0, but I think it is still out there, I just haven't nailed down the exact circumstances to reproduce. I was able to solve it by running this script, which got me most of the way there, and then running the following SQL statement (the script changed the file names correctly but did not update every record in the ezbinaryfile table):

 UPDATE ezbinaryfile SET filename=concat(filename, '.', SUBSTR(original_filename, -3)) WHERE (filename NOT LIKE '%.___') AND (original_filename LIKE '%.___');

That SQL copies the extension from the original filename into the new filename field (only if the original filename had an extension of a . and then 3 characters and the new filename does not already have that).

Me: http://jordan.teamhirsch.com
My blog: http://wiredformusic.blogspot.com
My other company: http://thinkimprov.com
eZ Certification: http://auth.ez.no/certification/verify/402488
eZ Award: http://ez.no/company/news/ez_awards_2007_prize_winners

Conrad Decker

Saturday 03 July 2010 6:12:16 am

Hey Jordan!

I generally have three options for content creators on how they want to handle showing pdf files. One, as you mentioned would be to force a download of the file using the content/download module, the second one is forcing the browser to view the file, rather then forcing the download. I do this by linking directly to the file, however I notice the way a browser handles the file at that point is completely different on all browsers and is even handled differently on different operating systems.

It sounds like you were able to utilize the content/download functionality to actually view the file in the browser, is that correct? What OS/Browser combo did you get that to work on?

One other option that I thought I'd at least mention is using the Google PDF viewer to ensure the browser shows the PDF online rather then forcing the download. This is a nice way to ensure that your site is consistent across all browsers and OS's. I do this by constructing the link using the .filepath property, but I wrap it in a link to the Google PDF viewer. The final link ends up looking like this - http://docs.google.com/viewer?url='http://domain.com/var/path/to/file.pdf&embedded=true&width=700&height=1050'

And if you're feeling really froggy, you can even open that as an iframe directly in a modal window on the site when the link is clicked. It's a nice little addition to any site.

Hope that's somewhat helpful to you or someone else.

Jordan Hirsch

Saturday 03 July 2010 9:34:27 am

Hi Conrad!

Thanks a million for that Google PDF viewer tip - that sounds like an ideal solution that I will definitely be using in the future. Consistency across browsers is key for most clients when it comes to opening PDFs. This client in particular seemed to care mostly about Firefox, so I was doing my testing on FF 3.5 on Win XP SP 3. It looks like once I added the PassThrough lines to file.ini, FF started opening the PDFs in the browser window and not showing the "save file" dialogue box, even though I'm still using the "content/download" link structure (which is nice, because using that makes sure that eZ enforces permissions, as opposed to linking directly to the PDF in the var/ folder).

All that stuff about missing file extensions really threw me off, but in the end it turns out I had the fix very early on, I just hadn't cleared the cache fully enough (sometimes the command line just doesn't do it, I guess) to see the change.

Thanks again for that Google tip - that's a great solution!

Me: http://jordan.teamhirsch.com
My blog: http://wiredformusic.blogspot.com
My other company: http://thinkimprov.com
eZ Certification: http://auth.ez.no/certification/verify/402488
eZ Award: http://ez.no/company/news/ez_awards_2007_prize_winners

Conrad Decker

Tuesday 06 July 2010 3:34:01 am

Oh wow, that's interesting. I hadn't even thought about how linking directly to the PDF in the var folder would bypass the normal permissions in place with eZPublish, but that does make a lot of sense. I'll have to take a look at file.ini and the PassThrough directive...thank you for the pointer.

Definitely let me know about the Google PDF Viewer and if you have any questions on it's functionality. I agree it's a pretty smooth solution with all of the browser/os consistencies!

Peter Keung

Tuesday 06 July 2010 11:01:57 am

I've had good experiences using the Google Docs Viewer... except for this annoying IE8 problem: http://www.google.com/support/forum/p/Google+Docs/thread?tid=22d92671afd5b9b7&hl=en

http://www.mugo.ca
Mugo Web, eZ Partner in Vancouver, Canada

Conrad Decker

Tuesday 06 July 2010 7:19:42 pm

Thanks for the input Peter, I've actually run into that issue as well, but only when trying to show the viewer in an iframe.

My solution was initially to open the pdf viewer in an iframe, within a modal window, but I ran into the issue that you pointed out in that posting. Apparently the doc viewer doesn't provide a compact privacy policy which is a standard in IE. I was actually disappointed to read that Google left something relatively simple out of their implementation. I understand not supporting older versions of IE, but unfortunately this makes their viewer completely non-functional in IE in an iframe.

Ah well, what I ended up doing was a browser check using jquery. If the browser was IE, I opened the pdf viewer in a pop-up window, if not, I used pretty photo to open the viewer in an iframe embedded into a modal window. Here's the simple js if anyone is interested.

UPDATE: moved the code to pastie...

http://pastie.org/1033684

eZ debug

Timing: Jan 17 2025 23:36:37
Script start
Timing: Jan 17 2025 23:36:37
Module start 'content'
Timing: Jan 17 2025 23:36:37
Module end 'content'
Timing: Jan 17 2025 23:36:38
Script end

Main resources:

Total runtime0.1777 sec
Peak memory usage2,048.0000 KB
Database Queries141

Timing points:

CheckpointStart (sec)Duration (sec)Memory at start (KB)Memory used (KB)
Script start 0.00000.0086 588.9922180.8125
Module start 'content' 0.00860.0050 769.8047106.5547
Module end 'content' 0.01360.1640 876.3594537.3750
Script end 0.1776  1,413.7344 

Time accumulators:

 Accumulator Duration (sec) Duration (%) Count Average (sec)
Ini load
Load cache0.00362.0527200.0002
Check MTime0.00130.7188200.0001
Mysql Total
Database connection0.00170.965210.0017
Mysqli_queries0.134075.43631410.0010
Looping result0.00130.74151390.0000
Template Total0.163792.110.1637
Template load0.00090.513910.0009
Template processing0.162891.619010.1628
Override
Cache load0.00060.309610.0006
Sytem overhead
Fetch class attribute can translate value0.00070.408110.0007
XML
Image XML parsing0.00020.135710.0002
General
dbfile0.00160.8954200.0001
String conversion0.00000.004430.0000
Note: percentages do not add up to 100% because some accumulators overlap

CSS/JS files loaded with "ezjscPacker" during request:

CacheTypePacklevelSourceFiles
CSS0extension/community/design/community/stylesheets/ext/jquery.autocomplete.css
extension/community_design/design/suncana/stylesheets/scrollbars.css
extension/community_design/design/suncana/stylesheets/tabs.css
extension/community_design/design/suncana/stylesheets/roadmap.css
extension/community_design/design/suncana/stylesheets/content.css
extension/community_design/design/suncana/stylesheets/star-rating.css
extension/community_design/design/suncana/stylesheets/syntax_and_custom_tags.css
extension/community_design/design/suncana/stylesheets/buttons.css
extension/community_design/design/suncana/stylesheets/tweetbox.css
extension/community_design/design/suncana/stylesheets/jquery.fancybox-1.3.4.css
extension/bcsmoothgallery/design/standard/stylesheets/magnific-popup.css
extension/sevenx/design/simple/stylesheets/star_rating.css
extension/sevenx/design/simple/stylesheets/libs/fontawesome/css/all.min.css
extension/sevenx/design/simple/stylesheets/main.v02.css
extension/sevenx/design/simple/stylesheets/main.v02.res.css
JS0extension/ezjscore/design/standard/lib/yui/3.17.2/build/yui/yui-min.js
extension/ezjscore/design/standard/javascript/jquery-3.7.0.min.js
extension/community_design/design/suncana/javascript/jquery.ui.core.min.js
extension/community_design/design/suncana/javascript/jquery.ui.widget.min.js
extension/community_design/design/suncana/javascript/jquery.easing.1.3.js
extension/community_design/design/suncana/javascript/jquery.ui.tabs.js
extension/community_design/design/suncana/javascript/jquery.hoverIntent.min.js
extension/community_design/design/suncana/javascript/jquery.popmenu.js
extension/community_design/design/suncana/javascript/jScrollPane.js
extension/community_design/design/suncana/javascript/jquery.mousewheel.js
extension/community_design/design/suncana/javascript/jquery.cycle.all.js
extension/sevenx/design/simple/javascript/jquery.scrollTo.js
extension/community_design/design/suncana/javascript/jquery.cookie.js
extension/community_design/design/suncana/javascript/ezstarrating_jquery.js
extension/community_design/design/suncana/javascript/jquery.initboxes.js
extension/community_design/design/suncana/javascript/app.js
extension/community_design/design/suncana/javascript/twitterwidget.js
extension/community_design/design/suncana/javascript/community.js
extension/community_design/design/suncana/javascript/roadmap.js
extension/community_design/design/suncana/javascript/ez.js
extension/community_design/design/suncana/javascript/ezshareevents.js
extension/sevenx/design/simple/javascript/main.js

Templates used to render the page:

UsageRequested templateTemplateTemplate loadedEditOverride
1pagelayout.tpl<No override>extension/sevenx/design/simple/templates/pagelayout.tplEdit templateOverride template
 Number of times templates used: 1
 Number of unique templates used: 1

Time used to render debug report: 0.0001 secs