Is there a way for attachments to display on screen rather than giving the user a download prompt when they are directed to the node/NID/attachment/newest filepath?

CommentFileSizeAuthor
#10 Screen shot 2011-11-30 at 4.15.32 PM.png54.42 KB_vid
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

_vid’s picture

@vee
Here's how I did it. I added this code to force load the 'preferred' link when the node is accessed (for non-admins).

+edit: I added an li item to the list of links displayed showing admins the full path they can use as a link.
$attachment_links = "<div class=\"item-list\"><ul><li class=\"first last\">Preferred version with clean url:".l(url($node->path, $options), $node->path)."</li></ul></div>\n".$attachment_links; This should probably be done with an override to attachment_links_build_links($node).

++edit: I replaced l($preferredLink,$preferredLink) with l(url($preferredLink, $options),$preferredLink) to display the fully qualified url to the admin.

  1. Replicate the link text that would be the preferred link.
  2. Check that attachment_links exist.
    • If so then check that the node is published and that the user doesn't have access to administer nodes.
      • If so then load the attachment using drupal_goto(). I've done this before with a CCK link type and I think the reasoning was that this helps ensure that cron can still access the page without opening an attachment. If I recall cron failed with other methods of forcing the attachment to load.
      • If not then display a message to the admin.
    • If not then display the node unaltered.

To do this I added this code before the current code in attachment-links.tpl.php.

<?php
//set link vars to match syntax of predetermined links
$preferredLink='node/'.$node->nid.'/attachment';
$newestLink=$preferredLink.'/newest';

//Always load the preferredLink for non-administrators but display a message for admins.
if(isset($attachment_links)){	//if attachment links exist 
	if($node->status && !user_access('administer nodes')){	//if this node is published - redirect to destination
		/* Tests: */
			//dsm('$node: '.print_r($node,true));
			//dsm('$node->nid: '.$node->nid); //display node
			//dsm('user_access(administer nodes): '.user_access('administer nodes'));		display if usr has access.
		/* END Tests: */
		drupal_goto($preferredLink);//load the preferred one
	}else{
		$options=array('absolute' => TRUE);
		?>
  	<div class="messages status" style="clear:right;"><h3>Non-admin viewers will be automatically redirected to the Preferred version: <?php print l(url($preferredLink, $options),$preferredLink);?>.</h3>
		<br />
		This behavior is editable in <?php print $template_file;?>
    </div>
	<?php //dsm(print_r(get_defined_vars(),true));
		//append attachment links
		$attachment_links = "<div class=\"item-list\"><ul><li class=\"first last\">Preferred version with clean url:".l(url($node->path, $options), $node->path)."</li></ul></div>\n".$attachment_links;
	} 
}?>

I'd prefer to do it with a custom module or template overrides but I'm just getting a grip on that and couldn't manage to hook the right functions.
In addition it would be nice to alter the form to add an option to turn this functionality on or off and lastly, set the permission that would determine the behavior (rather than just hard coding 'administer nodes'). Perhaps picking from available roles (admin, authenticated, etc...) would make sense as well.

But it would take a better Drupaler than I to do that.
If these seem like valuable additions maybe we could add them as feature requests.

Todd Nienkerk’s picture

Title: attachments displaying on screen » Display attachments
Status: Active » Fixed

This is a feature in Drupal core. Just check off the "List" box next to each attachment you want listed at the bottom of a node.

Is what you're asking for a display of the download links (newest/preferred)? Have you tried the official 6.x-1.0 release?

nunami’s picture

Status: Fixed » Active

I am trying out Attachment Links and I think Vee is referring to when you use the links provided by the module it will cause the browser to download the file rather than opening it.

The site I am working on has users that need to update PDFs which are linked on many pages. Rather than updating the links individually, it would be easier to use a module like Attachment Links which will link to the newest document version. However, when a user clicks on the "newest" link it asks them to download the file rather than opening it up in the browser.

So, if the "newest" link is used in FCK, is there any way to have that link open the PDF/Doc/PPT rather than asking the user to download it?

Thanks,
Nu

Todd Nienkerk’s picture

Is this not a browser setting? Shouldn't the browser decide (or give the user the option to decide) whether a file is opened or saved?

markabur’s picture

In Safari I can see the difference in behavior if I list the file in addition to displaying the attachment links. If I click the regular file link, the pdf is displayed in the browser like I'm accustomed to, but if I click the attachment link, the file is always downloaded immediately, with no dialog.

In Firefox I'm offered an "Opening attachment" dialog either way.

I find that if I comment-out lines 242 and 243 of attachment_links.module, then Safari behaves as expected and Firefox doesn't change. But both of them lose the filename.

    	$headers[] = 'Content-Type: application/force-download';
    	$headers[] = 'Content-Disposition: attachment; filename="' . $name .'"';
markabur’s picture

Fiddled around with this, and I get the behavior I want by using drupal_goto() instead of the file_transfer() stuff.

function _attachment_links_download($filepath) {
  // -- Copied from file_download().
  if (file_exists(file_create_path($filepath))) {
    $headers = module_invoke_all('file_download', $filepath);

    if (in_array(-1, $headers)) {
      return drupal_access_denied();
    }

    if (count($headers)) {
      
      // Just send the browser to the file.
      drupal_goto($filepath);

    }
  }

  return drupal_not_found();
}

Todd Nienkerk’s picture

Status: Active » Needs work

markabur: Interesting. We'll need to investigate whether what you proposed is a better method.

_vid’s picture

Just a follow up to my comment above (#1).
I've been using this method for the last year & 1/2 on several sites and it works great.
Anonymous users are redirected and admins are not. Instead they are presented with the list of links and the standard admin tabs.
I'm currently using Attachment Links 6.x-1.1.

Recently I found out that using drupal_goto on anonymous users can keep the cron process from completing. *Thanks to dev-art.net/en/article/solving-cron-run-exceeded... for the solution.

So I updated the copy of attachment-links.tpl.php in my theme to check if the script running is cron.php before drupal_goto.

    if ($_SERVER['SCRIPT_NAME'] != '/cron.php') { //Don't redrirect if cron
      drupal_goto($preferredLink);//load the preferred one
    }//else just display the page as a node

Here's the full code for my theme's attachment-links.tpl.php:

//set link vars to match syntax of predetermined links
$preferredLink='node/'.$node->nid.'/attachment';
$newestLink=$preferredLink.'/newest';

//Always load the preferredLink for non-administrators but display a message for admins.
if(isset($attachment_links)){  //if attachment links exist 
  if($node->status && !user_access('administer nodes')){  //if this node is published - redirect to destination
    if ($_SERVER['SCRIPT_NAME'] != '/cron.php') { //Don't redrirect if cron
      drupal_goto($preferredLink);//load the preferred one
    }//else just display the page as a node
  }else{
    $options=array('absolute' => TRUE);
    ?>
    <div class="messages status" style="clear:right;"><h3>Non-admin viewers will be automatically redirected to the Preferred version: <?php print l(url($preferredLink, $options),$preferredLink);?>.</h3>
    <br />
    This behavior is editable in <?php print $template_file;?>
    </div>
  <?php //dsm(print_r(get_defined_vars(),true));
    //append attachment links
    $attachment_links = "<div class=\"item-list\"><ul><li class=\"first last\">Preferred version with clean url: ".l(url($node->path, $options), $node->path)."</li></ul></div>\n".$attachment_links;
  } 
}?>
<div id="attachment-links">
  <?php if ($attachment_links_title): ?>
    <h3><?php print $attachment_links_title; ?></h3>
  <?php endif; ?>
  <?php print $attachment_links; ?>
   <?php /*
  if($content){ 
    print '<div class="content">'.$content.'</div>'; //displaying this so search will index it. 
  } 
  */ ?>
</div>

I'm happy to make this a patch if this option is inline with the direction of the module.

Todd Nienkerk’s picture

Title: Display attachments » Let browser/user determine whether the file should be opened in browser or downloaded

Given the problem with drupal_goto() and the complexity of the resulting workaround, I think we should dig deeper into the solution provided by markabur in #5. I suspect, however, that changes to the headers will break IE.

Changing the issue title to reflect the clarified scope of this issue.

_vid’s picture

Works for me.
Though; I think think there's two different issues here. Perhaps we should split them apart.

markabur is addressing the browser delivery of the attachment.

I want to address how the node is presented to anonymous vs. administrative users. Here's what I would like to see:

  • Administrative users are able to view and edit the node without downloading the attachment every time they visit the node. Like so: Screenshot of the customized admin view
  • Anonymous users on the other hand, should automatically download the preferred attachment whenever they visit the node directly. i.e. node/508 or the clean url: http://hr.uoregon.edu/attachments/temporary-employment-memo. I wouldn't want them to ever see a list of links for preferred or newest.

What are you thoughts on that?

markabur’s picture

I am kind of keeping an eye on this, though I don't have access to the site I used it on anymore. I hope they aren't having cron troubles because of drupal_goto().

Since D7 has the cron queue, I wonder if drupal_goto() only causes a problem on D6?