Using Nice Menus how what do I put in the "Path" to link directly to a pdf file and where do I locate that pdf in the drupal file structure - Icreated a files sub-folder under root and tried variants of /files/my.pdf but get either invalid path or no access

Comments

tnanek’s picture

First see the location of the files directory. By default, the 6.x install will make it as a subfolder of your sites directory. Thus the address would be something like the following:
sites/default/files/my.pdf

The "default" directory may be different, but chances are if you don't know, then it is that.

I've done similar things in 5.x, and am guessing about 6.x now, but this should work.

yersin’s picture

HI, I have the same problem. I want a menu link that takes me to a pdf file. The file is a /up/file.pdf. When I type in this address in the "Path" textbox and I submit it, and "?q=" is added so "?q=up/file.pdf" is not found. It seems that links are made to link to nodes only. How can I link to pdf file from a menu link?
Thanks.
- yhh -

VM’s picture

I believe you would need to give the complete path to your files folder to the menu item

sites/default/files/up/file.pdf would be for a default install of drupal 6.x of course if you aren't using clean urls you will have to add the ?q= to the path

unless you've changed the files folder name to up then it would be sites/default/up/file.pdf

without knowing where the exact placement of the folder is on your server it is difficult to give you a concrete path.

yersin’s picture

The complete path is "http://mysite.com/up/u1/module1.pdf". The up folder is in the root folder. I'm using drupal 5 without clean urls. A "workaround" would be to type in "http://mysite.com/up/u1/module1.pdf" in the Path textbook, but links shouldn't depend on full paths. If I type "/up/u1/module1.pdf" in the path textbook, the resulting link searches for "http://mysite.com/?q=up/u1/module1.pdf", which obviously doesn't exist.
- yhh -

tnanek’s picture

I tested it for my own site, and even when the file is within my Drupal install, it is harder than I made out above. It is attached to a page, and I'd like to have a menu link directly to it. It is at:

sites/default/files/My_File.pdf

But when I try to enter that into a new menu item, it says:

The path 'sites/default/files/My_File.pdf' is either invalid or you do not have access to it.

I've tried using /sites/default/files/My_File.pdf but I get the same message. And I have clean url's on my site so the ?q= wouldn't be an issue.

I am uid 1, and I uploaded the files, so I believe I have access to it.

aloemantra’s picture

I have about 3,000 pdf files in a subdirectory. How can I link them into the menu? I am not using Nice Menus but that would be nice.

tcowin’s picture

I've managed to get this to work by using the complete URL - 'http://www.example.com/sites/default/files/my.pdf', but that is not ideal obviously. There should be a way to use a relative URL...(got the same error as mentioned above in 6.2.)

tnanek’s picture

Yes, this is what I did as a temporary work around as well, but its going to stink when I take the site out of development and make it accessible with a different domain - thus I would rather relative links as well.

Compuwizard123’s picture

Any workaround for this found besides using a full absolute url?

tnanek’s picture

If I find any, I shall post it here - but for now none to my knowledge.

cybertron1’s picture

i wanna bump this because I have run into the same problem. Relative links doesn't work (unless I add them directly in the database)

This worked in drupal 5.x but stopped in 6.x

anyone must know what to do?

Ron Williams’s picture

I'm having this issue also. I wonder if there is a way to disable url checking.

Ron Williams
http://ronwilliams.io/

cybertron1’s picture

yes there is a way. All my internal urls starts with /dg

so I did it like this: (take attention to $colonpos === )
originally it only looks at the ":" . If you wanna disable it completly then you can take away : and just use ''
'nothing'

BUT BEWARE! BE CAREFUL AND IF ANYTHING BREAKS DONT COMPLAIN TO ME OR DRUPAL! THIS IS A TEMPORARY "SOLUTION"!!

MENU.INC
function menu_path_is_external($path) {

$colonpos = strpos($path, ':');
if ($colonpos === false) {
	$colonpos = strpos($path, '/dg');
      return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path);
}
else
return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path);

}


Ron Williams’s picture

For those still having this issue there has been some discussion regarding fixes to the solution at the following:

http://drupal.org/node/308263
http://drupal.org/node/190867

Ron Williams
http://ronwilliams.io/

merzikain’s picture

An alternative solution to this problem would be to create a blank page for the link to your file (like "Read Me"), then create a page template for that fake page (page-content-read-me.tpl.php) that contains the following:

header("Location:/sites/default/files/file.pdf");

This will create the appropriate menu link and open the file you want without having to use a full url or futz with any code you may not be comfortable with. If you only have a few files to link this may be the simpler solution but if you have "3000" like that one guy said then you might want a different solution.

sudhir37’s picture

/**
* Returns TRUE if a path is external (e.g. http://example.com).
*/
function menu_path_is_external($path) {
if(string_begins_with($path,'sites/default')){
return true;
}
if(string_begins_with($path,'/sites/default')){
return true;
}
$colonpos = strpos($path, ':');
return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path);
}

function string_begins_with($string, $search)
{
return (strncmp($string, $search, strlen($search)) == 0);
}

jrockowitz’s picture

The menu_link_save function requires that all menu links map to a router item. So my solution was to create a menu router item for the installation's files directory. This router item will never be hit if the file is found, it just allows you to create menu links for any file in your 'site/installation/files' directory. If the file is missing this will execute Drupal's default file not found handler.

Not a perfect solution but it does seem to work without hacking core.

Hope this helps.

/**
 * Implementation of hook_menu().
 */
function my_module_menu() {
  // Define a router item for the installation's files directory.
  $items[ file_directory_path() ] = array(
    'page callback' => 'drupal_not_found', 
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $items;
}
waaadim’s picture

1) create a dummy node, you can use whatever content type you like most.
2) create a url alias
from: node/(your-node-id)
to: /sites/default/files/filename.pdf

in the menu path put: "node/(your-node-id)"

that's it.

Maurice M.’s picture

This worked for me :)

skheadshooter’s picture

Dont get it... it still does not work.

SteelToedBoots’s picture

Well, I didn't bother reading the whole thread, but this is how I add in PDFs without touching the code.

I'm using Drupal 7, WYSIWYG, IMCE, and Tiny MCE. Edit any random page and look at your WYSIWYG tool bar. I upload a pdf through the tool bar by clicking the icon for an image. Make sure there are not any spaces in the name of the file, or this will not work. Leave the menu system after uploading the PDF.

Highlight any random word on your page. Click on the add link icon. Find the pdf and set it as a link. You'll be able to see the link url in one of the dialogue windows. Just copy that url and close everything out without saving.

Go and edit your menu and just paste in the link to the pdf. Shouldn't be trouble.

Alan D.’s picture

I like the callback example above. This is the D7 version, for the default file schema (public:// or private://)

  // This allows menu item links directly to the file directory.
  $items[file_stream_wrapper_get_instance_by_scheme(file_default_scheme())->getDirectoryPath()] = array(
    'page callback' => 'drupal_not_found',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );

Alan Davison
flyke’s picture

I am using Drupal 7 and I want my content editor to be able to add a menulink to any file that resides in the folder 'downloads' (in the root). I solved this by creating a custom module for this. The first part of my module I got from this thread. I did not find the solution above with token very clean nor was it working so I used a custom page callback function that executes a drupal goto with an absolute path (this is because on multilingual sites drupal adds the language prefix and otherwise you would have a false link to /en/downloads/xxx instead of /downloads/xxx).

Here is the code of my custom_module:

/**
 * Implements hook_menu().
 *
 * This module allows to create a menu item that links to a file that is in the downloads folder
 */

function itr_file_menulink_menu() {
  // Define a router item for the downloads directory.
  $items['downloads/%'] = array(
    'title' => 'Direct file link',
    'page callback' =>'open_file',  //our custom function that will actually open the file
    'access callback' => TRUE);
  return $items;
}

function open_file(){
  global $base_url;
  $file = 'downloads/'.arg(1);  //I am assuming that the file is directly in the folder downloads, so arg(0) will be 'downloads' and arg(1) will be the file name
  if (file_exists($file)) {
    $file = $base_url . '/' .$file;
    drupal_goto($file, array('absolute' => 'true'));
  }else{
    $file = $base_url . '/' .$file;
    watchdog('file not found', 'there is a menulink that links to this file that can not be found: '.$file);
    drupal_goto('<front>');
  }
}
Alan D.’s picture

Pays to escape your watchdog entries. You should use check_plain($file) at the very least! I believe that this would work (in some form) if passed in by an attack.

"downloads/document.pdf<script>steal_admin_session_cookie();</script>"


Alan Davison