10

I am busy working on a site on my localhost that needs to link to some content that is separate from Drupal.

I have the current menu paths set up like this: http://mylocalsite/the_folder_for_the_other_content. If I try <front>/the_folder_for_the_other_content or /the_folder_for_the_other_content or the_folder_for_the_other_content, I get the error "The path 'whatever_I_use' is either invalid or you do not have access to it."

When I go live I obviously need all the menu items to point to http://myrealsite/the_folder_for_the_other_content.

How can I set it up so that I won't have to edit all the menu paths when I go live?

  • @irishbuzz has a workaround for Drupal 6 below, but I was hoping that I could avoid doing this in Drupal 7. Is that wishful thinking on my part? – Martin Duys Apr 12 '11 at 12:20
  • Is Drupal installed in the root directory of the web server? – kiamlaluno Apr 17 '11 at 18:44
  • Not on my localhost version, but when it finally goes live it will be in the root of the public_html folder. Does that count as 'root of the web server'? – Martin Duys Apr 19 '11 at 12:02
  • By "root directory of the web server," I mean the directory that in Apache is set with the "DocumentRoot" directive and which, by default, is the public_html directory. It is the directory Apache access when you use a URL like http://example.com/. – kiamlaluno Apr 19 '11 at 12:24
  • Then: yes ultimately the site will be in the root directory – Martin Duys Apr 19 '11 at 12:54
4

kiamlaluno's answer did not quite work for me. Using %menu_tail produced a storm of errors that the menu_tail_load function was having problems with missing arguments:

Warning: Missing argument 2 for menu_tail_load(), called in  ... /includes/menu.inc on line 579 and defined in menu_tail_load() (line 827 of ... /includes/menu.inc).
Warning: Missing argument 3 for menu_tail_load(), called in ... /includes/menu.inc on line 579 and defined in menu_tail_load() (line 827 of ... /includes/menu.inc).

What did work for me was

function allow_menu_links_menu() {
  $items = array();
  $items['sites/d8/files/%'] = array(
    'title' => 'Folder Content',
    'page callback' => 'allow_menu_links_cb', /* never called */
    'access callback' => TRUE,
  );
  return $items;
}

Then, I could serve up files in the sites/d8/files folder (and subfolders) using menu items with paths like sites/d8/files/Documents/MyFile.pdf

The menu system will then generate a link like href="/sites/d8/files/Documents/MyFile.pdf"

If you don't use the custom menu module, the menu system will reject a path starting as above.

If you try to use a path like http:sites/d8/files/Documents/MyFile.pdf , it will produce a link like href="http:sites/d8/files/Documents/MyFile.pdf", which will work when you are at the root of the site, but when you are on a content page, the browser will interpret the url relative to the content page, and it will not work.

If you use a path like http:/sites/d8/files/Documents/MyFile.pdf, the menu system will accept it, but the menu system will produce a link like href="http:/sites/d8/files/Documents/MyFile.pdf" , which the browser (at least Safari) will interpret as href="http://sites/d8/files/Documents/MyFile.pdf" , and fail trying to find the server named "sites".

(On further investigation, the reason the code using menu_tail fails is that you need to add the 'load arguments', as noted here: http://api.drupal.org/api/drupal/includes--menu.inc/function/menu_tail_load/7 . If you add 'load arguments' => array('%map', '%index'), to the definition of $items in kiamlaluno's code, it will work. The issue of whether menu_tail_load should require the explicit load arguments is also discussed here: http://drupal.org/node/298561)

(Don't forget to enable your new module, or the menu system will not accept the new links)

5

When you add a new link, the link is validated from menu_edit_item_validate(), which calls drupal_valid_path() to check if the path is valid, or it can be accessed from the user.
drupal_valid_path() returns TRUE if

  • The path is <front> (<front>/directory, or similar paths are excluded)
  • The path is an external path (the function url_is_external() returns TRUE)
  • The path is associated with a menu callback

Apart from using absolute URLs, the only solution is to have a custom module that defines a menu callback associated with the path you want to use.
When you use the URL that points to a file, or a directory, the web server should show that file or directory, without invoking Drupal. That is what happens with Apache, as the .htaccess file that comes with Drupal contains the following directives:

# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]

In your case, the custom module should contain code similar to the following:

function mymodule_menu() {
  $items = array();

  $items['the_folder_for_the_other_content/%menu_tail'] = array(
    'title' => 'Folder content', 
    'page callback' => 'mymodule_view', 
    'access callback' => TRUE,
    'load arguments' => array('%map', '%index'), 
  );

  return $items;
}

You can use any values for title and page callback, as that menu callback should never be called. The value of access callback says to Drupal that every user has access to that menu callback.

As an alternative you can define a menu callback associated to "alias_for_directory/%menu_tail" that redirects the user to the directory you want they see (using drupal_goto()). I would use this solution when the server does not use the content of .htaccess, and it would invoke Drupal even when the URL is pointing to an existing file or directory.

3

For me the following did the trick (on drupal 6).

I want to direct to another URL on the same domain, let's say Drupal is running on http://www.example.com and I want to have a link to http://www.example.com/frontend

In the menu item, please enter as path:

http:/frontend

The drupal menu will link to: http://www.example.com/frontend

When you use https, you should enter https:/frontend in the path field for the menu item.

  • Any idea if this would work in 7/ – Martin Duys Oct 18 '12 at 17:50
  • Don't know, just give it a try. – Paul Oct 19 '12 at 7:45
  • I'm finding this method not working as of version 7.22. – Rick Apr 10 '13 at 21:04
  • 1
    This works on Drupal 7.23. I have been trying to do this for a while, if I could I would upvote you +10 – DrCord Nov 7 '13 at 23:28
1

I resolved my link issues with the following:

http://groups.drupal.org/node/210308 and http://drupal.org/node/372252

It turns out my theme was printing the menu incorrectly so that all items were relative to my current location (ie admin/logout, instead of /logout).

Hope this helps.

1

I used sql to replace the link in the menu structure:

UPDATE menu_links SET link_path = replace(link_path, "livesite.com", "localhost.com");

Not sure if I needed to do this but I then flushed the menu caches.

  • why would you want to change the query though? It's not recommended. – gerl Nov 23 '16 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.