Drupal's menu system lets you define an arbitrary number of menu items in a hierarchy, each of which is a link to somewhere in the site (or on another site). That's great, unless you want to have a menu tree that has items in it which are not, in fact, links. Several scenarios for this exist, including parent categories and section separators.
This page explains how to add "menu links" that will not actually link anywhere.
Modules
Modules that allow links that are not links:
Theme layer: Drupal 5
Alternatively, this can be accomplished in your theme:
Step 1
We will define the magic value <none>
to mean "a path to nowhere", just like <front>
means "the home page". The crucial part here is the theme_menu_item_link()
function, which we will override. Place the following function in your template.php file.
function phptemplate_menu_item_link($item, $link_item) {
if ($item['path'] == '<none>') {
$attributes['title'] = $link['description'];
return '<span'. drupal_attributes($attributes) .'>'. $item['title'] .'</span>';
}
else {
return l($item['title'], $link_item['path'], !empty($item['description']) ? array('title' => $item['description']) : array(), isset($item['query']) ? $item['query'] : NULL);
}
}
Any menu item whose path is <none>
will now become a span rather than a link. Note that because it's not a link you can't click on it, so you can't access sub-menu items unless the no-link menu item has the "Expand" checkbox checked so that its children are always visible. If you need to have access to the sub-menu items for things like dropdown/flyout menus, try using the JavaScript version of this snippet.
This method can also be used as a separator. Simply have a menu item with text "------" or similar, and set its path to <none>
. It will then show as text with no link, providing a nice separation of the menu.
Step 2
As a nice extra, we can also add additional help text to the menu item edit page. For that you will need to implement a very small module that implements form_alter. The module itself doesn't need anything more than the following code snippet:
function example_form_alter($form_id, &$form) {
if ('menu_edit_item_form' == $form_id) {
$form['path']['#description'] .= ' ' . t('Enter %none to have a menu item that generates no link.', array('%none' => '<none>'));
}
}
That will modify just the menu item edit form and add additional text to the description (the text that appears below the textfield) describing how to use the <none>
.
Drupal 6
In Drupal 6 (and 7) you cannot use the value <none>
as the target path. You need to define a valid target first.
Add a node with the path alias "nolink" as a dummy to identify this link isn't a link.
Add this to template.php:
function YOURTHEMENAME_menu_item_link($link) {
if ($link['type'] && $link['href'] == 'nolink') {
return '<span class="nolink">'.check_plain($link['title']).'</span>';
}
}
Now add a menu item with "nolink" as target path. Style the .nolink class to your needs
Drupal 7
For Drupal 7 follow the Drupal 6 approach and use this function in template.php:
function YOURTHEMENAME_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
if (strpos(url($element['#href']), 'nolink')) {
$output = '<a href="#" class="nolink">' . $element['#title'] . '</a>';
} else {
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
}
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
Drupal 8
Related issue for 8.x core:
#1543750: Allow menu items without path
Quick solution
Put the below line in path & put your desire title
http://#
Use the below CSS to avoid linking. You must add the "nolink" class, which can be done with the code above, or using a module like https://www.drupal.org/project/menu_attributes
.nolink {
pointer-events: none;
cursor: default;
}
Comments
Drupal 6 + Nice Menus
This is the only version that works for me with Nice Menus module... (I also had strange problems when I tried the dummy node approach, so I used the fake url one - in this case I use http://fake.link for every item I do not want to be linkable)
Note: class nolink is purely optional, but it's good for adding some useful styling like changing the cursor etc.
This version worked for me
This version worked for me (Great work!)
to avoid having the page scroll to the top when clicking on the fake link,
use
javascript:void(0)
instead of the
#
sign
inside of return '
This works & additional improvement
This solution works for nice menus (and other menu's occasions where dummy link needed [?])
A quick additional improvement: insert
to the return code for dummy link to become as follows:
so dummy link (#) not causing web browser to search whole page for link anchor #
Another improvement
Thanks digitallica - there was a couple things I wanted to add/share to this improvement. When using nice menus, "menu-path-fake.link" is created as a class in each parent li. I don't believe having a period in the class is good form. I also wanted to utilize javascript:void(0) instead of # so that the current URL isn't read into the href (removing an incorrect URL may be better for SEO?), so I made the below modifications and added a new function from the nice menus module to my sub-theme's template.php file.
Obviously THEMENAME would be the name of your theme. The second function will remove "http://menu." creating the class "menu-path-nolink".
fixed [I can't make this work in D7 and bartik theme]
I installed nice menus and added the code in bartik's template.php
- I then changed the themename to bartik
- cleared all cache (drush cc)
-
but I still could not get the menu.nolink url to change to javascript:void(0) after menu was re-displayed.I also tried the other sample code, and it did not work for me too.I must be missing some change that must be done. Help.Drupal's menu system was saving the link as system paths and not url alias. I changed strpos() search string and it worked.
There's a bit of a wrinkle, the parent menu link which is changed with javascript:void(0) may need to be set to 'expanded' and not collapsed.
Thanks.
Works great with Nice Menus
To help other forum wanderers, I'd like to say that the code provided by tekket works great with Nice Menus. Steps for newbies:
1) Copy and paste the code at the very bottom of your theme's template.php file, but remove the
<?php
and?>
php tags.2) notice the function name is themename_menu_item_link... You must replace "themename" with the name of your theme. It could look something like garland_menu_item_link($link) after you're finished.
3) Purge the Drupal cache using the button at the bottom of the /admin/settings/performance page.
4) Enter "http://fake.link" as the link destination for menu items that shouldn't be links.
Special thanks to ...
tekket's php snippet combo attack with Bassplaya CSS code
Fantastic solution
This solution worked for me.
It's a workaround, but it sure save lots of time and hassle, therefore it's a winning one!
CSS to the rescue
I know it's not the best but in the worst case scenario:
you could use css by tricking the user to feel that certain links aren't links..
.certain-links a,
.certain-links a:hover {
cursor: default;
text-decoration: none;
}
Authentically,
BassPlaya
jQuery really comes to the rescue.
My client discovered this 'bug' and demanded a fix, I found this thread and spent 45 minute reading and digesting this issue. Every solution presented seems to ignore the power of Drupals Behaviors.
Obviously my solution works for me, but it could work for you too. It's a matter of your comfort level with Drupal Behaviors and Themes.
1) find the js included in your theme
For me:
Yours will possibly be parallel, with your theme insted of "<my_theme>"
2) Using some Dom inspector, find the tightest css rule you need to isolate your troublesome 'A' fathers:
For me:
3) Add a behavior at the end of the javascript file:
As is, this snipit won't work, replace <my_theme> with the name of your theme. Also note that the css selector from step 2 is incorporated in the javascript string there, but we add the text [':not(.<my_theme>-process)'] after the 'a'.
The Javascript here is selecting the father 'A's that aren't yet processed and replacing their href with '#' and marking them as processed.
Voila, quick, correct, and clear.
Some possible problem you might have:
(my suggestion is to change to one, or modify your theme to do so)
(ummm, I can't give any direct advice on this, ask someone about your site)
(Well the last line of code there is ".addClass('someclass');" add your own and use css for styling
(If you want other hard to define, or specific items, I think you can use secondary rules in your javascript Behavior to specify them, Since these aren't really likely to be needed on every site, consider this a per-site customization, that way you really give the client what they want.)
Have Fun and Good Luck
Jeff
For Drupal 7...
This worked for me. Thanks.
Note that for Drupal 7, you'll need to declare the .js file in your theme .info file, e.g.:
.. and wrap the code in your .js file like this (CSS selectors adapted for my needs):
Thank you, this worked for
Thank you, this worked for me.
stumped by a simple ErRor
just a simple addin to the "nolink" method: If its ssl server, even if you add the function accurately, you will get no effect when "nolink" is set as path verbatim (of course without the double-quotes). the "nolink" is refuted as any other incorrect path. I kept on searching for all possible reasons as to "why the %$#&" is it not working ? :-P
ok, please set the path to "https://nolink" and Volla! :D
Amazing!
This is Amazing/ Stupid on how Drupal 7 doesn't have a simple feature for something so basic. I hate downloading mods for something so simple.
No kidding
For a CMS that does so many amazing things, not having a simple solution for this is absurd. And Drupal folks wonder why Wordpress has become so popular.
The Drupal 7 approach is not
The Drupal 7 approach is not working?
I have the code:
And it is not working?
The code for Drupal 7 is not
The code for Drupal 7 is not working for me either. too bad
http://SocialNicheGuru.com
Delivering inSITE(TM), we empower you to deliver the right product and the right message to the right NICHE at the right time across all product, marketing, and sales channels.
Drupal 7 uses the node/n path
Drupal 7 uses the node/n path for menu links, and not the alias that's being tested for. The below should get you there - this adds a url() call to the strpos check to convert the node/n path to /nolink.
BlueFusion.co.nz
Drupal 7 Solution?
^ Sorry, but that solution isn't working in D7.
Any ideas how to get this to work?
What path is your relevant
What path is your relevant menu item taking through the code? And what is the value of $element['#href'] for the item that's not working?
BlueFusion.co.nz
d-nz,
d-nz,
I copied your function into my template.php file and changed the function name "THEME_menu_link" to my theme name "aplvncc_menu_link". Cleared cache through Performance > Cache, as well as, Devel has "Rebuild the theme registry on every page load" turned on. Am I missing a step?
When I try entering for the menu item path either as "<nolink>" or "nolink", it doesn't get pass the check (ie. The path '<nolink>' is either invalid or you do not have access to it.).
Not quite sure what you mean. I don't have any menu modules (Admin Menu/Superfish) installed that would be affecting core to my knowledge.
aplvncc_menu_link() doesn't appear to be called ever. If I put a print into your function just below:
Nothing shows up when I view source after I tried to save the menu item.
Thanks for the help.
Running:
- Drupal core 7.28
EDIT: I just achieved the <nolink> with the Special Menu Item module. The Instructions at the top imply you can use either 1 of 3 of those modules OR apply the YOURTHEMENAME_menu_link function to your template file if you don't want to bloat your website with modules. At least, that's how I interpreted it. The latter doesn't work unless you install Special Menu Item for me.
You don't need the special
You don't need the special menu item module to use the code, that's an alternative - not one I've ever used so I can't advise you on it.
Did you 'Add a node with the path alias "nolink" as a dummy to identify this link isn't a link.' ?
If you've done that then the only issue left is that the function isn't being called. Double/triple/quadruple check the name and clear the cache again. If that doesn't help then you're going to have to track down why it isn't being called, it won't work until it is.
Cheers
BlueFusion.co.nz
Creating anchor links
When using this quick solution in D7 I noticed that the URL changes literally links to
http:///#
(3 backslashes). Instead ofhttp://example.com/current-page#
what you probably expect it to do.I'm sure there are people like me searching for a solution to make it work like output in the second example marked, to avoid the output in the first marked example. This easily can be done by removing the backslashes (it's some kind of hack/bug). So when you enter something similar in the path field like this
http:#
or thishttp:#anchorname
, than the path will be validated as well. Unfortunately the output doesn't differ much in comparison with "#", so yea..Here's what worked for me
function THEMENAME_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
if ($element['#href'] == 'http://nolink') {
$output = ''. $element['#title'] . '';
} else {
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
}
return '
\n";
}
Just change the first output to whatever you want and your golden!
hello,
hello,
the topic is quite old now, but i'm new in drupal and a little lost. I don't find the function code that works for me and wonder is yours doesn't works because there some customization of the code to be made?
The comment you left at the end of the code make me wonder:
Just change the first output to whatever you want and your golden
To what should I change the first output.
Many thank's in advance.
Clémence
Excellent
Excellent
Good!!!
Excellent
Worked for me
Drupal 7
This is a solution that worked for me.
i just want to add this
i just want to add this
after all parent menu item if it has the child. can any one help me plz..
@fleuv
Thanks fleuv!
worked for me in Drupal 7!
Naveen_K's code worked for me...with one change
When setting up the menu link, I put the path as http:/# (not http://#). This produced an actual path of http://www.example.com/# for the link, which is also unclickable.
Thanks!
Drupal 7 one page approach
Drupal 7 version, worked fine, I've write this code for make a one page theme:
On each menu item, the links are such as http://#main-content.
Hope this helps someone.
Hi,
Hi,
For some reason tb_wall_menu_item_link is not being called at all.
I have the following function in template.php under my theme folder. Basically, when I refresh the page, I should see a blank page, while I see the contents in the page.
function tb_wall_menu_item_link($item, $link_item) {
exit;
}
I'm sure my theme name is right because I have the following function in the same template.php file and with exit function, page turns into blank page.
tb_wall_youtube_thumbnail{
exit;
}
Easiest Solution in drupal 7!
I´m not a code expert and I look for easy ways to solve issues without extra modules,
so I found this solution, hope somebody helps: http://www.thecomputergroup.com/blog/how-to-make-a-drupal-menu-item-link...
This is a great solution but
This is a great solution but the link is dead. Here is the method:
[current-page:url]#
Good luck...
Thanks
Thanks xtian7 your solution works.