Last updated August 2, 2013. Created by JohnAlbin on January 4, 2007.
Edited by sapiotech, drupalshrek, Steve Dondley. Log in to edit this page.

In Drupal 7, a link to a named anchor or named region on the page can be created in the Menu system. Go to admin/structure/menu/manage/navigation/add. To link to an anchor on just one of your sites pages, set the path to the full url of the page and include the anchor reference, for example:

http://example.com/node/5#anchor

For a link to an anchor on the current page (that is, a link that works on every page the menu link is displayed on), you can use the Menu token module. Once that is installed together with the modules that it requires, you will be able to set the link path to:

[current page:url]#anchor
or
node/[node:nid]#anchor

In earlier versions of Drupal, users who have tried using “named anchors,” also known as “jump links,” in the menu system can run into problems with them not working. A named anchor will look like this:
<a name="anchor"></a>

The expected behavior is that when a link that points to this named anchor is clicked, the user’s browser should jump to the anchor tag on the html page, making it appear at the top of the user’s browser window.

This desired behavior can be accomplished by adding the following function to your theme’s template.php file:

function phptemplate_menu_item_link($item, $link_item) {
  // Convert anchors in path to proper fragment
  $path = explode('#', $link_item['path'], 2);
  $fragment = !empty($path[1]) ? $path[1] : NULL;
  $path = $path[0];
  return l(
            $item['title'],
            $path,
            !empty($item['description']) ? array('title' => $item['description']) : array(),
            !empty($item['query']) ? $item['query'] : NULL,
            $fragment,
            FALSE,
            FALSE
          );
}

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

As drupal outputs strict xhtml 1.1 named anchors ie. <a name="anchor"></a> do not work.

They have been deprecated in xhtml 1.1 and replaced with the id tag. The id can be used on any tag eg.
<p id="anchor"></p> and then the anchor can be called as you would previously ie.

http://www.example.com#anchor

To get the links to the anchors working in your menu you need the full url as the link ie.

http://www.example.com/example#anchor

not

/example#anchor

The above code is not necessary for this to work.

I had forgotten that named anchors were deprecated, so, thanks for reminding me. Much cleaner anyhow.

However, absolute urls are not viable for a production site. The whole point of a framework (and cms in drupal's case) is to abstract as much as possible in order to make the application portable and scalable. I agree with others that a permanent solution for named anchors in Drupal 5.x menus would be greatly appreciated. Until then, I will try this template override.

thanks,
Brian

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
http://www.terraeclipse.com -- where I work
http://www.brianthomaslink -- where I will someday get around to playing

Thank you rmyoung, good point. I had forgotten and wasted hours. Very good point.

Hi,

I'm very interested in this as it is a great feature when trying to improve the accessibility of your website. But the code doesn't appear to do anything, I entered "#content" into my menu item Path and the link remains as

http:///example.com/%23content

instead of:

http:///example.com/#content

And also I am interested in how this has become deprecated? Where would I read up on this?

Thanks, Garry.

Don't know if it was just a typo but you have too many slashes after http. The snippet for the template file only works for named anchors. If you are using an id such as #content you need to have the full path in your menu item ie. http://example.com#comments NOT #comments.

Here's a page from w3c schools explaining that it's deprecated: http://www.w3schools.com/xhtml/xhtml_syntax.asp

Sorry about the typo, that was an accident!

Either way, putting in a whole path into the menu does not solve the issue. This link should be on every page so that users can skip to content, for example,

On the homepage:

http://www.example.com/#content

On the contact page:

http://www.example.com/contact#content etc...

This is vital for users with screenreaders who want to skip to main content, thus I think it's important that it is made available in the drupal menu items

Garry Bain, Edge Three Sixty
Drupal Developers

Agree.

(subscribing)
Absolute path is not a solution. I may have different sections for all the pages in a website (#main-content or #site-information, for examples) . It really does not make any senses to redirect user to a particular page.

I am using Zen. I found a solution.

I don't think the code is deprecated. I think it should be marked for 6.x as well (or an updated version should be posted). I had a similar problem with hook_link, but hook_link directly calls the l() function and it has a 'fragment' option specifically for handling anchors (see http://api.drupal.org/api/function/l for details), so you can do something like this:

<?php
/**
* Implementation of hook_link().
*/
function drivingforce_features_link($type, $node = NULL, $teaser = FALSE) {
 
$links = array();
  if (
$type == 'node' && $node->type == 'story' && is_numeric(arg(1))) {
   
$links['node_top'] = array(
     
'title' => t('Top'),
     
// link node back to itself - path module will sort out any aliases for us
     
'href' => 'node/' . $node->nid,
     
// this line will properly attach #top-anchor to the end of our URL
     
'fragment' => 'top-anchor',
     
'attributes' => array('title' => t("Jump back to the top of the page.")),
    );
  }
  return
$links;
}
?>

Then all you need to do is add an id of 'top-anchor' to the h1 tag in the page.tpl.php template.

HOWEVER, hook_menu still has no 'fragment' option itself. The template.php code above mimicks the 'fragment' behaviour of the l() function for hook_menu and re-builds the link using the l() function if it finds a # in the path.

AFAIK, this is still valid. There's nothing in the current hook_menu docs referring to 'fragments', nor is there any reference to a similar mechanism in Drupal 7.x hook_menu docs, so it seems to me this will continue to be valid for a few years. If it doesn't work with Drupal 6.x, it probably just needs a tiny tweak to make it work, but it *is* required. As te-brian said, absolute URLs are not a viable solution. =(

Has anyone raised this as a D7 feature request for the menu system, btw??

Hook_menu has an options element where you can pass options to the link function, including fragment.

Hi,

Sorry I'm new to Drupal, and this is my first time on the Forum and I have been looking for this information for a while, and don't know where to find it.

Is this an anchor on the right side on this website (the menu on the right with the numbers)? www.loreal-paris.co.uk
Can it done on Drupal?

Thanks!
MERRY CHRISTMAS

Matt

Just a note to add here, as it didn't seem clear to me:

But if you want to add items (perhaps sub items) to your menus that are actually anchors within existing pages, it only seems to work in Drupal 6, if you specify the path as node/number#anchor version of the node, and not the alias.

For example, if you have a page: http://example.com/services
which was actually http://example.com/node/5
and you wanted a menu item to an anchor on that page, e.g. #maintenance
then you would need to add the item to your menu with the path
node/5#maintenance

The menu saves fine, and in things like local menu and sitemaps, the aliased URL and anchor still translates properly.

We would need to use this "named anchor" on every page so that users can jump to "#mainContent" on every single page - the actual link would be stored in the header so you could quickly jump to the main content on every single page.

Your solution is fine but would only work on the node/5 page on the site.

Garry Bain, Edge Three Sixty
Drupal Developers