Is it possible to keep a primary-link active when URLs below the specified entry are active? While the active-trail is applied when child links are active, this does not work when subsequent navigations happen within that URL.

For example: An primary link is defined to point to: /group/

Which lists all the current user groups. From here navigation to a specific group page, e.g. /group/1 results in the deactivation of the primary link. The only way to make it remain active is to add a child entry in the primary links hierarchy, although this isn't practical.

Is it possible to have the primary link remain active for it's own URL and any that are "under" it?

(Drupal 6.8)

Comments

Screenack’s picture

If I read you correctly, the latest nice-menus does this quite nicely:

http://drupal.org/node/95964

mafitzpatrick’s picture

Thanks figgles. Not sure if that is what I'm looking for - I don't need dropdown/flyout menus just to keep a primary link active when the current url is for something below the specified value. For example a primary link of /group will remain active when viewing /group/1 group/1/edit and so on.

I'll take a look anyway in case I'm missing something obvious. Thanks for your reply!

Screenack’s picture

Currently, if I am on the page "Albermerle" below, only the li a item "Albermerle" has the appropriate markup. With the dev package on Nice Menus, the containing "Cod" li a item now includes the necessary markup for CSS definitions. Is that what you mean?

Fish
|---Tuna
|--Salmon
|--Cod
   |--Cape
   |--Scranton
   |--	Albemerle
|--Pike
mafitzpatrick’s picture

I want the item "Cod" to be activated, but for all urls following it's defined path - without creating sub-entries in the hierarchy. For example, in your example above remove Cape, Scranton and Albemerle and then imagine a path like below:

/fish/cod/cape

With your definition above (including the child entries) it will keep Fish and Cod activated. However, if you do not create those entries Fish and Cod will show inactive once you navigate downwards.

This probably seems like a bizarre thing to want, but the reason for this is that I have an url /group under which all group-related pages appear. Navigating to this point with a primary link (point to /group) highlights the group tab (correctly). However, once you navigate to a specific group (e.g. /group/1 ) that highlight is lost and the tab becomes inactive. The only way to make it work is creating multiple dummy entries in the primary links for each and ever group (not practical).

A similar thing could be imagined by having a /node tab, and wanting it to remain active when viewing /node/1.

I'm kind of surprised that the primary-link active/inactive doesn't simply search for the given path at the beginning of the URL as it would be pretty strange to have pages under a hierarchy in the URL that are not also under the hierarchy in a menu sense (why would you bother). I'm rambling now, but hopefully that's clear up what I'm after!

mafitzpatrick’s picture

I've solved this by using a modified version of the code available here:

function mytheme_activelink($links) {
    $alias = explode('/', request_uri());
    $alias = $alias[1];  //note this only checks the first path element so will not match multi-slash primary links
    foreach ($links as $key => $link) {
      if ($link['href'] == $alias) { 
        $linksactive[$key . ' active-trail'] = $links[$key];
      } 
      else {
        $linksactive[$key] = $links[$key];
      }
    }
    return $linksactive;
}

Changes made include dropping the module_exists check and putting the active-trail into the key of the links. This is required to output the active-trail into the class definition for the <li> tag, rather than the <a>. If someone else wants to add the active-trail to the a tag, simply add the following:

$linksactive[$key . ' active-trail']['attributes']['class'] = 'active';

As mentioned, if your primary links point to a location with multiple slashes this will not work. It would be fairly straightforward to instead search for the links url against the current path (removing leading / etc.) using strpos: if it returns 0 you know the current url begins with that given by the link definition.

Hope this helps somebody!

miquil’s picture

Hi mafitzpatrick,

I'm trying to get the active class in my primary links for a couple of days now.
Can you please assist me in how to do just that. I don't have a pull down menu just a tab menu for my primary links. I don't know were to put the modified version of the above code.

Thanks,
Miquil

Coornail’s picture

Hi!

Here is my solution:

/**
 * Selects the parent item if it's in the url
 */
function yourtheme_activelink($links) {
        $segments = explode('/', drupal_get_path_alias($_GET['q']));
        $parent = strtolower($segments[0]);
        foreach ($links as $key => $link) {
                if (strtolower($link['title']) == $parent) {
                         $links[$key]['attributes']['class'] = 'active';
                         break;
                }
        }
        return $links;
}

ludo1960’s picture

Subscribing

Been fighting with this for a while now. Coornail, where exactly did you place your code?

Coornail’s picture

I put this into the template.php, and also in your node.tpl.php you have to change your theme function from
print theme('links', $primary_links);
to
print theme('links', yourtheme_activelink($primary_links));

And also you should change yourtheme to your theme's name everywhere.

vthirteen’s picture

it's pretty obvious, but just for clarity sake:

- insert this code in page.tpl.php, not node.tpl.php

- if you want your secondary links to behave exactly in the same way just change your theme function accordingly:
from
print theme('links', $secondary_links);
to
print theme('links', yourtheme_activelink($secondary_links));

mordonez’s picture

I think it's better to work with href attribute

replace

strtolower($link['title']

by

drupal_get_path_alias($link['href'])

Drupal dreamer at Ymbra

Coornail’s picture

$parent is the title of the parent menu item, href won't work for it.

But it's a good idea to restructure like that. Can you post the full working code?

vthirteen’s picture

this works for me, thanks to vaserqno's post:

/**
* Selects the parent item if it's in the url
*/
function yourtheme_activelink($links) {
        $segments = explode('/', drupal_get_path_alias($_GET['q']));
        $parent = strtolower($segments[0]);
        foreach ($links as $key => $link) {
                if (drupal_get_path_alias($link['href']) == $parent) {
                         $links[$key]['attributes']['class'] = 'active';
                         break;
                }
        }
        return $links;
}
Anonymous’s picture

I tested this code with Zen and it works just fine. However when applying it to a Fusion theme, it does not work. Any ideas why?

jenlampton’s picture

Hi,

I'm having the same problem. Only in my case my menu is Primary Links, and my Secondary links disappear when my third level of links don't trigger the active trail in their parents. I tried all the suggestions above, and though I *can* get the active-trail to show up on the correct primary link (using href, not title) I still can't get my secondary navigation to even appear. Here is my structure...

some-category
some-category/some-sub-category
some-category/some-sub-category/a
some-category/some-sub-category/whole
some-category/some-sub-category/lot
some-category/some-sub-category/of
some-category/some-sub-category/individual
some-category/some-sub-category/nodes

In drupal 5 the active trail and breadcrumbs were determined by the path alias (a WONDERFUL thing IMO because it kept people from trying to disassociate one from the other - something that's all too possible in drupal - but very bad form in web dev - and terribly confusing to end users who's brains are trained to recognize the folder/sub-folder/file navigation structure).

I guess my question is two fold: why on earth did drupal stray from this pattern, and how on earth can we get back there?

~saddened and confused~ Jen

wilgrace’s picture

jenlampton, did you manage to make the Secondary navigation appear? Active trail on primary links are working fine, but without the ability to surface the Secondary menu I can't go deeper than second level.

Any ideas?

jenlampton’s picture

I think this is a problem with drupal core and needs to be fixed there, but the immediate solution I used was to install the menu trails module (http://drupal.org/project/menutrails).

blasthaus’s picture

I tried the snippets here but no luck for me in D6, not sure why. Also tried menutrails. Ended up using the context module (http://drupal.org/project/context) where you can set the active menu for node views within specific "sections" of your site. Pretty slick module for anyone wanting to keep a lean template.php file.

alexfisher’s picture

Great find blasthaus... The Context Module works perfectly!

EurekaLiz’s picture

I tried every possible module to achieve this, but there was always a dead end or they never worked as expected. Sometimes some modules worked and sometimes they didn't because each website I made was always different in content and configuration. For example, Context didn't worked for me at all last time and Menutrails only worked for content types and not with taxonomies. The best solution for me now is CSS Injector: http://drupal.org/project/css_injector. With this, it doesn't matter which drupal configuration I have. My active-trail headaches are gone :)

ludo1960’s picture

Thanks for that, nice find!

sumaiyajaved’s picture

The solution to use css injector was not very obvious to me at the start so if someone else is having the same issue do the following:

After installing css injector go to admin - site configuration - css injector.

Note: I am highlighting the menu for my catalog using taxonomy, i tried multiple options but nothing worked in creating the active trail. The only solution i was left with was to create individual css injector rules for the main catalog or menu items.

create rule

#nice-menu-1 li.menu-520 {
background:none repeat scroll 0 0 #015696;
font-weight:bold;
}
#nice-menu-1 li.menu-520 a {
color:#ffffff;
}
#nice-menu-1 li.menu-520 ul li a {
color:#000000;
font-weight:normal;
}
#nice-menu-1 li.menu-520 ul li a:hover {
font-weight:bold;
color:#ffffff;
}

select: Add if the following PHP code returns TRUE (PHP-mode, experts only).

$match = FALSE;

$url = request_uri();
if (strpos($url, "/bpa/")) 
{ $match = TRUE;}

return $match;

Note: The number 520 is the menu class of the parent menu item (use to firebug to get the value)

Regards,

Sumaiya Javed
Web Developer
www.sumaiyajaved.com
www.phpjavascript.com

SonamSdiwate’s picture

Hi,
i am also having same problem can some one give me solution of that because i am using bluemarine theme.
sonam diwate

nightlife2008’s picture

Perhaps this will work from a custom module?

//Sets the active menu item to foo/bar
$path = drupal_get_normal_path('foo/bar');
$menu_item = menu_get_item($path);
if($path && $menu_item) {
menu_set_item(NULL, $menu_item);
}