Hi,

how can I deactivate the "active" link (in the menu.inc?)?

It is usefull for screenreader-users, when a link in the site doesen't point to the active page. I want only the name of the site in the menu, not the anchor.
It is possible with drupal?

Comments

gerd riesselmann’s picture

If I get you right, you want to turn every "active" link into plain text. For example, if you have a menu like this:

<ul>
<li><a href="/somepage">some page</a></li>
<li><a class="active" href="/thispage">this page</a></li>
<li><a href="/anotherpage">another page</a></li>
</ul>

It should look like this:

<ul>
<li><a href="/somepage">some page</a></li>
<li>this page</li>
<li><a href="/anotherpage">another page</a></li>
</ul>

OK, let's dive in.

First, the "active" class is added in the function "l()" in file common.inc. This is a very basic function, so playing around with it seems like a not so good idea. However, if you want ALL active links to be - well - NOT links, regardless of where they appear: Here's very the root.

Change the body of the function to look like this, and all former active links will be text only:

  if (drupal_get_normal_path($path) == $_GET['q']) {
    return $html ? $text : check_plain($text);
  }
  return '<a href="/'. check_url(url($path, $query, $fragment, $absolute)) .'"'. drupal_attributes($attributes) .'>'. ($html ? $text : check_plain($text)) .'</a>';
}

This however is kinda rough. Another possibility is to use regular expression before outputting the content. The following function should replace all occurances of <a href=".." class="active"> with <span class="active">:

function replace_active_link($text) {
  $pattern = "/<a[^>]* class=\"[^\"]*active[^\"]*\"[^>]*>([^<]*)<\/a>/";
  $replace = "<span class=\"active\">\${1}</span>";
  return preg_replace($pattern, $replace, $text);
}

You can put the function in a file, include it in your template and call it whereever you want the links to be removed, for example before outputting the menu (in phptemplate):

<div id="menu">
 <?php print replace_active_link($sidebar_left) ?> 
 ...

The regular expression has been tested against this string:

This is <a href="/some">some</a> <a href="/this" class="active">this</a> <a href="/another">another</a> <a href="/this" class="yellow active">this again</a> <a href="/this" class="active yellow">this again gain</a>

However, there is no garantuee, since regular expressions always make my head ache ;-)

------------------
Gerd Riesselmann
www.gerd-riesselmann.net

moi-1’s picture

Hi Gerd,

thanks for your tips, they bring me to a solution.
I take the first way and add inside the function "l()" an additional "span":


function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE) {
  if (drupal_get_normal_path($path) == $_GET['q']) {

return '<span class="mynewlinkclass">'. ($html ? $text : check_plain($text)) .'</span>';
  }
  return '<a href="/'. check_url(url($path, $query, $fragment, $absolute)) .'"'. drupal_attributes($attributes) .'>'. ($html ? $text : check_plain($text)) .'</a
>';
}

common.inc near line 1550

Now I need to style the new class "mynewlinkclass", for example the tab-navigation in drupal.css


.primary span {
  background-color: #ddd;
  border-color: #bbb;
  border-width: 1px;
  border-style: solid solid none solid;
  height: auto;
  padding: 0 1em;
  text-decoration: none;
  margin-right: 0.5em;
  display: inline;
  border-collapse: collapse;
}

Danke ;-)

echoz’s picture

Hi, this works great, thanks.
Ooops, I posted a question, then figured it out, sorry!

-----------------------
http://echozone.com

Marc Bijl’s picture

Hi Gerd,

Quiet a nice answer! Therefore I was just wondering if you (or someone else :-D ) can help me with creating something the other way around: how to assign active classes to all menu-items that are in fact "active". Drupal is not very consistent here...

What I mean is this. I created a website with primary links, and they're in my header. Clicking through these primary links, I can highlight the active one with css definitions, since Drupal assigns the active class to the active primary link.

However, once clicking another link, e.g. a lower level menu-item, Drupal does not assign the active class to the active primary link anymore. Okay, the page we're talking about might be a level or two lower than the primary link, but that doesn't mean that - from a hierarchic point of view - the primary link isn't active anymore...

Another post about a similar problem can be found here: http://drupal.org/node/26095

And one step further: for internationlization I use i18n.module and i18n_menu.module. But here I lose the assignment of the active class for menu-items as well.

Someone else with the same problem posted this one http://drupal.org/node/30331, while someone else, who created some kind of patch, has the same kind of trouble: http://drupal.org/node/25847.

Would be great if someone can help!

___________________
discover new oceans
lose sight of the shore

gerd riesselmann’s picture

First combining this two solutions:

Giving these, you should be able to write CSS like

a.active,
#taxonomy_page #menuitem-1,
#node_page #menuitem-2 {
   color: red;
}

which will "highlight" menuitem no. 1 for each taxonomy page, menuitem 2 on each node page etc.

Another way is to play around with function l() again. Given that a path like "node/1" should be higlighted if the current url is "node/1/edit", this means to assign the active class if the given url starts with the path passed to l().

This should work (not tested, though):

function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE) {
  $normalPath = rtrim(drupal_get_normal_path($path), "/");
  $current = rtrim($_GET['q'], "/");
  if (strpos($current, $normalPath) === 0) {
    if (isset($attributes['class'])) {
      $attributes['class'] .= ' active';
    }
    else {
      $attributes['class'] = 'active';
    }
  }
  return '<a href="/'. check_url(url($path, $query, $fragment, $absolute)) .'"'. drupal_attributes($attributes) .'>'. ($html ? $text : check_plain($text)) .'</a>';
}

Using "=== 0" is important! The function checks if the current URL ($GET["q"]) starts with the nomalized path passed. For both URLs trailing "/" are removed since "a/b/c/" and "a/b/c" are both identical URLs.

------------------
Gerd Riesselmann
www.gerd-riesselmann.net

Marc Bijl’s picture

Hi Gerd,

Just tried the second solution you suggested, but unfortunately it doesn't do the trick yet... This is the message I get:

warning: strpos(): Empty delimiter. in /home/newoceans.nl/public_html/includes/common.inc on line 1415.

Line 1415 is this one:

if (strpos($current, $normalPath) === 0) {

As I'm not a programmer, I really don't have a clue what can be wrong. I decided to make a kind of "log" to see what's happening, by adding this code:

echo '$normalPath: ' . $normalPath . ', $current: ' . $current . ' | ';

This is the result on my screen when clicking on primary menu link "webdesign" for example:

$normalPath: taxonomy/term/17, $current: node/19 |
$normalPath: taxonomy/term/4, $current: node/19 |
$normalPath: admin/themes/settings, $current: node/19 |
$normalPath: admin/themes/settings, $current: node/19 |
$normalPath: node, $current: node/19 |
$normalPath: node/19, $current: node/19 |
$normalPath: node/25, $current: node/19 |
$normalPath: node/35, $current: node/19 |
$normalPath: node/27, $current: node/19 |
$normalPath: node/28, $current: node/19 |
$normalPath: node/23, $current: node/19 |
$normalPath: , $current: node/19 |

To me, it looks like something's wrong with the last line (the empty delimiter?), but I have no idea why.

Anyway, some extra information (not sure whether it's important or not): I use i18n.module, i18n_menu.module and try to use as much URL aliases as possible - regarding SEO.

Additionally I'd like to say that my intention is to have more than just one menu option highlighted at the same time. Is that possible?

E.g. If I click on primary link "web design", that menu item should become highlighted. If I then click on submenu item "analysis", that menu item should become highlighted, but menu item "web design" should stay highlighted as well (as "analysis" is a kind of subpage of "web design").

The URL alias of page "web design" is /website-design. The URL alias of page "analysis" is /website-design/analysis. May be something can be done with these aliases. Would be great, as taxonomy and other pages are based on this structure too:

E.g. the taxonomy index page "webdesign portfolio" has the alias /website-design/portfolio and a certain site in the webdesign portfolio has the alias /website-design/portfolio/certain-site.

Hope you can help; thanks!

___________________
discover new oceans
lose sight of the shore

gerd riesselmann’s picture

There should be a check for emptyness, it seems.

Also, you're right, that checking the internal paths is not sufficient, and the function should rely on the aliases instead.

Another try (again not tested, I have no Drupal at hand right now):

function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE) {
  $normalPath = rtrim(drupal_get_path_alias($path), "/");
  $current = rtrim(drupal_get_path_alias($_GET['q']), "/");
  if (!empty($current) && 
      !empty($normalPath) && 
      strpos($current, $normalPath) === 0) {
    if (isset($attributes['class'])) {
      $attributes['class'] .= ' active';
    }
    else {
      $attributes['class'] = 'active';
    }
  }
  return '<a href="/'. check_url(url($path, $query, $fragment, $absolute)) .'"'. drupal_attributes($attributes) .'>'. ($html ? $text : check_plain($text)) .'</a>';
}

The function *should* highlight more than one menu item.

------------------
Gerd Riesselmann
www.gerd-riesselmann.net

Marc Bijl’s picture

Hi Gerd,

Thanks, this is absolutely fab! It looks very promising... As far as I can see, it will do a cool job at taxonomy index pages as well! (still have to reorganize my taxonomy a bit)

There's only one thing I cannot get working yet: highlighting the submenu's items. To display items of a submenu, I use this function in page.tpl.php: (got it somewhere at this forum)

<?php $TheMenu = theme_menu_tree(169); print $TheMenu; ?>

Where 169 is the id of the submenu - this number differs from theme to theme, as I'm using sections.module.

I guess this kind of function does not use the l() function from common.inc? Do you know if there's a solution for this?

Thanks again!
Marc
___________________
discover new oceans
lose sight of the shore

gerd riesselmann’s picture

... since after jumping around a bit it all ends up here: http://drupaldocs.org/api/4.6/function/theme_menu_item_link

Can you add the following lines just before the return statement and post the results?

  $cls = isset($attributes['class']) ? $attributes['class'] : 'NONE';
  echo '$normalPath: ' . $normalPath . ', $current: ' . $current . ', $path:  ' . $path . ', [q]: ' . $_GET['q'] . ', CLASS: ' . $cls . '<br />';

------------------
Gerd Riesselmann
www.gerd-riesselmann.net

Marc Bijl’s picture

Hi Gerd, thanks for all your effort! Below some results for both dutch site (www.newoceans.nl/nl) and english site (www.newoceans.nl/en-local):

  1. page /webdesign at dutch site
  2. page /webdesign/website-analyse at dutch site
  3. page /website-design at english site
  4. page /website-design/website-analysis at english site

I noticed that the only paths/aliases shown, seem to be the ones standard generated by Drupal. There are no paths derived from links in the submenu, from links in the block (sidebar), from links in the footer et cetera.

Can this be the reason why not all links are highlighted based upon their path/alias?

Cheers,
Marc

NOTES

  • At the english site taxonomy assignments need to be made for most nodes.
  • At the dutch site taxonomy terms do not necessarily link to the same page as the primary links do, even if they have the same name. E.g. the primary link "webdesign" links to /webdesign, whereas the taxonomy term "webdesign" links to /diensten/webdesign (which is dutch for /services/webdesign). So better forget about checking by looking to taxonomy terms for now...

1. Page /webdesign at dutch site:

$normalPath: diensten, $current: webdesign, $path: taxonomy/term/17, [q]: node/19, CLASS: NONE
$normalPath: diensten/webdesign, $current: webdesign, $path: taxonomy/term/4, [q]: node/19, CLASS: NONE
$normalPath: admin/themes/settings, $current: webdesign, $path: admin/themes/settings, [q]: node/19, CLASS: NONE
$normalPath: admin/themes/settings, $current: webdesign, $path: admin/themes/settings, [q]: node/19, CLASS: NONE
$normalPath: home, $current: webdesign, $path: node, [q]: node/19, CLASS: NONE
$normalPath: webdesign, $current: webdesign, $path: webdesign, [q]: node/19, CLASS: active
$normalPath: grafische-vormgeving, $current: webdesign, $path: grafische-vormgeving, [q]: node/19, CLASS: NONE
$normalPath: digitale-presentatie, $current: webdesign, $path: digitale-presentatie, [q]: node/19, CLASS: NONE
$normalPath: eigen-werk, $current: webdesign, $path: eigen-werk, [q]: node/19, CLASS: NONE
$normalPath: new-oceans, $current: webdesign, $path: new-oceans, [q]: node/19, CLASS: NONE
$normalPath: contact, $current: webdesign, $path: contact, [q]: node/19, CLASS: NONE
$normalPath: , $current: webdesign, $path: , [q]: node/19, CLASS: NONE

2. Page /webdesign/analyse at dutch site:

$normalPath: diensten/webdesign, $current: webdesign/website-analyse, $path: taxonomy/term/4, [q]: node/91, CLASS: NONE
$normalPath: diensten/webdesign/analyse, $current: webdesign/website-analyse, $path: taxonomy/term/9, [q]: node/91, CLASS: NONE
$normalPath: admin/themes/settings, $current: webdesign/website-analyse, $path: admin/themes/settings, [q]: node/91, CLASS: NONE
$normalPath: admin/themes/settings, $current: webdesign/website-analyse, $path: admin/themes/settings, [q]: node/91, CLASS: NONE
$normalPath: home, $current: webdesign/website-analyse, $path: node, [q]: node/91, CLASS: NONE
$normalPath: webdesign, $current: webdesign/website-analyse, $path: webdesign, [q]: node/91, CLASS: active
$normalPath: grafische-vormgeving, $current: webdesign/website-analyse, $path: grafische-vormgeving, [q]: node/91, CLASS: NONE
$normalPath: digitale-presentatie, $current: webdesign/website-analyse, $path: digitale-presentatie, [q]: node/91, CLASS: NONE
$normalPath: eigen-werk, $current: webdesign/website-analyse, $path: eigen-werk, [q]: node/91, CLASS: NONE
$normalPath: new-oceans, $current: webdesign/website-analyse, $path: new-oceans, [q]: node/91, CLASS: NONE
$normalPath: contact, $current: webdesign/website-analyse, $path: contact, [q]: node/91, CLASS: NONE
$normalPath: , $current: webdesign/website-analyse, $path: , [q]: node/91, CLASS: NONE

3. Page /website-design at english site

$normalPath: admin/themes/settings, $current: website-design, $path: admin/themes/settings, [q]: node/77, CLASS: NONE
$normalPath: admin/themes/settings, $current: website-design, $path: admin/themes/settings, [q]: node/77, CLASS: NONE
$normalPath: home, $current: website-design, $path: node, [q]: node/77, CLASS: NONE
$normalPath: website-design, $current: website-design, $path: website-design, [q]: node/77, CLASS: active
$normalPath: graphic-design, $current: website-design, $path: graphic-design, [q]: node/77, CLASS: NONE
$normalPath: multimedia-presentations, $current: website-design, $path: multimedia-presentations, [q]: node/77, CLASS: NONE
$normalPath: other-work, $current: website-design, $path: other-work, [q]: node/77, CLASS: NONE
$normalPath: discover-new-oceans, $current: website-design, $path: discover-new-oceans, [q]: node/77, CLASS: NONE
$normalPath: contact-info, $current: website-design, $path: contact-info, [q]: node/77, CLASS: NONE
$normalPath: , $current: website-design, $path: , [q]: node/77, CLASS: NONE

4. Page /website-design/website-analysis at english site

$normalPath: admin/themes/settings, $current: website-design/website-analysis, $path: admin/themes/settings, [q]: node/90, CLASS: NONE
$normalPath: admin/themes/settings, $current: website-design/website-analysis, $path: admin/themes/settings, [q]: node/90, CLASS: NONE
$normalPath: home, $current: website-design/website-analysis, $path: node, [q]: node/90, CLASS: NONE
$normalPath: website-design, $current: website-design/website-analysis, $path: website-design, [q]: node/90, CLASS: active
$normalPath: graphic-design, $current: website-design/website-analysis, $path: graphic-design, [q]: node/90, CLASS: NONE
$normalPath: multimedia-presentations, $current: website-design/website-analysis, $path: multimedia-presentations, [q]: node/90, CLASS: NONE
$normalPath: other-work, $current: website-design/website-analysis, $path: other-work, [q]: node/90, CLASS: NONE
$normalPath: discover-new-oceans, $current: website-design/website-analysis, $path: discover-new-oceans, [q]: node/90, CLASS: NONE
$normalPath: contact-info, $current: website-design/website-analysis, $path: contact-info, [q]: node/90, CLASS: NONE
$normalPath: , $current: website-design/website-analysis, $path: , [q]: node/90, CLASS: NONE

___________________
discover new oceans
lose sight of the shore

gerd riesselmann’s picture

I noticed that the only paths/aliases shown, seem to be the ones standard generated by Drupal. There are no paths derived from links in the submenu, from links in the block (sidebar), from links in the footer et cetera.

Can this be the reason why not all links are highlighted based upon their path/alias?

Yes, looks like. Strange. No idea whats up here... You haven't overloaded any of the theme_menu_xxx functions, have you?

------------------
Gerd Riesselmann
www.gerd-riesselmann.net

Marc Bijl’s picture

Hi Gerd,

No, I haven't changed anything in menu.inc (if that's what you mean). The version I use is:

$Id: menu.inc,v 1.79.2.1 2005/06/05 09:47:51 dries Exp $

Can you please try to explain what l() is for? Should every link on a page usually pass this part of the code? Not even dependant on where it's called? (e.g. by theme_menu_tree, or by php in a block, or by html in the footer, et cetera)

Cheers,
Marc
___________________
discover new oceans
lose sight of the shore

murph’s picture

I am looking to do this as well. Any luck?
I'm also struggling with friendselectric theme, as the primary link navigated to does not get attributed with "active", yet in your post earlier you stated that drupal does this for all main level links...

Marc Bijl’s picture

No, unfortunately I didn't find the answer (after a lot of coding and testing, and having e-mail contact with Gerd Riesselmann - thanks Gerd).

Eventually I decided to let it go for a while; there are other things with more priority.

However, I think it might be an i18n problem, regarding these posts:

- http://drupal.org/node/30331
- http://drupal.org/node/41629

Other people seem to struggle with the same thing. Hope these links can get you a bit closer to the answer. Good luck!

___________________
discover new oceans
lose sight of the shore

florianr’s picture

For the language menu it dosn't work, because it themes the regexp doesn't work together with img links ...

<li> <span class="i18n-link"><a href="/nl/references" class="active"><img src="/modules/i18n/flags/nl.png"  
class="i18n-icon" width="16" height="12" alt="Dutch" /></a>&nbsp;<span class="active">nl</span></span> </li>

What regexp. should I use to remove the link from the image?

wakh.ru’s picture

what about drupal 8?