Set active menu trail CSS selectors - backport to 6.x-1.3

Mark B - May 18, 2009 - 09:51
Project:Nice Menus
Version:6.x-1.3
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:reviewed & tested by the community
Description

I really need the active trail classes to be applied to my menus, as discussed in 219804, but I don't want to use the dev branch of the module for a production site. Issue 219804 includes a patch for 6.x-2.x (http://drupal.org/node/219804#comment-1131533) which I've backported to 6.x-1.3

#1

Mark B - May 18, 2009 - 09:52
Status:active» needs review
AttachmentSize
nice_menus-active-path_465738-1.patch 3.07 KB

#2

fei - May 19, 2009 - 16:29

Thank you! I'll drop a msg if I run across any problems with this patch.

The site I'm using this for will be going up in a week or two and this is one of the few issues left. Thanks!

#3

peterjmag - May 27, 2009 - 17:06

This is exactly what I needed for a couple of sites that I'm getting ready to launch. I was even considering launching them with the 2.x dev version of nice_menus installed just for this capability, which is just bad form.

I applied the patch successfully on one of my simpler D6 sites. I'll try it out on my larger almost-launched sites and let you know if I have any problems.

Many thanks to you and add1sun!

#4

asak - June 16, 2009 - 15:40

Mark, this is strange. I've applied the patch - but nothing changes. everything works as it did. cleared all caches and saved the modules page, but nothing. I would expect it not to work if something was wrong - not to work as it did before the patch ;)

Clues...?

I'll play around some more...

#5

asak - June 17, 2009 - 12:10

Ok found it...

This patch successfully adds an 'active' class to menuparents - but not to menu items which are not parents.

To fix, i added these line:

<?php
+        // check if this item is in the active trail
+        if ($trail && in_array($mlid, $trail)) {
+         
$trail_class = 'active-trail ';
+        }
+        else {
+         
$trail_class = '';
+        }
?>

again just before the second output in the file, which after applying the patch above becomes line 365, so the function now looks as such:

<?php
function theme_nice_menu_build($menu, $trail) {
 
$output = '';

  foreach (
$menu as $menu_item) {
   
$mlid = $menu_item['link']['mlid'];
   
// Check to see if it is a visible menu item.
   
if ($menu_item['link']['hidden'] == 0) {
     
// Build class name based on menu path
      // e.g. to give each menu item individual style.
      // Strip funny symbols.
     
$clean_path = str_replace(array('http://', '<', '>', '&', '=', '?', ':'), '', $menu_item['link']['href']);
     
// Convert slashes to dashes.
     
$clean_path = str_replace('/', '-', $clean_path);
     
$path_class = 'menu-path-'. $clean_path;
     
// If it has children build a nice little tree under it.
     
if ((!empty($menu_item['link']['has_children'])) && (!empty($menu_item['below']))) {
       
// Keep passing children into the function 'til we get them all.
       
$children = theme('nice_menu_build', $menu_item['below'], $trail);       
       
// Set the class to parent only of children are displayed.
       
$parent_class = $children ? 'menuparent ' : '';
       
// check if this item is in the active trail
       
if ($trail && in_array($mlid, $trail)) {
         
$trail_class = 'active ';
        }
        else {
         
$trail_class = '';
        }
       
$output .= '<li id="menu-'. $mlid .'" class="'. $parent_class . $trail_class . $path_class .'">'. theme('menu_item_link', $menu_item['link']);
       
// Build the child UL only if children are displayed for the user.
       
if ($children) {
         
$output .= '<ul>';
         
$output .= $children;
         
$output .= "</ul>\n";
        }
       
$output .= "</li>\n";
      }
      else {
        if (
$trail && in_array($mlid, $trail)) {
         
$trail_class = 'active ';
        }
        else {
         
$trail_class = '';
        }
       
$output .= '<li id="menu-'. $mlid .'" class="'. $trail_class . $path_class .'">'. theme('menu_item_link', $menu_item['link']) .'</li>'."\n";
      }
    }
  }
  return
$output;
}
?>

#6

smautf - July 14, 2009 - 19:54

For anyone wondering, the change made in #5 by asak is included in the patch in #1.

This works fine for me. Thank you asak and Mark B!

#7

jacobkdavis - July 22, 2009 - 19:07

Thanks a lot for this patch, I was surprised this wasn't included in the module.

Contrary to #6's comment, when I just patched using #1 it was still only setting the active class on menu items that were parents / had submenu items. I had to replace the entire function with the function from #5 to get it to work for menu items that didnt have any children.

Thanks again everybody!

#8

echoz - July 23, 2009 - 22:08

For my use, I didn't need the additional change added in #5 because on non menuparent items, we still have the active class on the anchor tag itself, and I'm targeting the anchor tag anyway. This might explain why some users didn't need this.

#9

rockdw - August 28, 2009 - 21:17

I have to apologize in advance, I don't really know the correct way to comment on this. :-)

I had to add the $trail_class to the final output to get it to work, otherwise, the info in #5 doesn't ever use it:

Old line:
$output .= '<li id="menu-'. $mlid .'" class="'. $path_class .'">'. theme('menu_item_link', $menu_item['link']) .'</li>'."\n";

New line:
$output .= '<li id="menu-'. $mlid .'" class="'. $trail_class . $path_class .'">'. theme('menu_item_link', $menu_item['link']) .'</li>'."\n";

There seems to be a discrepency between what's in the patch and what's in #5. but when I added the first part of #5 and then also the updated output line to the patched code from #1, it worked for me.

#10

add1sun - September 9, 2009 - 21:19
Status:needs review» needs work

this needs an updated patch then

#11

ositoblanco - September 10, 2009 - 16:03
Status:needs work» needs review

The patch above and the changes in #5 (and #9) are working fine for me.

I've created a patch. Please review and hopefully commit it to the next stable 6.x-1.4 release. Thanks.

AttachmentSize
nice_menus-465738-11.patch 3.41 KB

#12

amogiz - September 16, 2009 - 15:20

Wonderfful ! I was exactly looking for this for many weeks. Thanx :)

#13

John_Kenney - October 2, 2009 - 04:28

i gather other people have successfully gotten these patches to work, but i tried both tonight and neither one worked for me.

1st patch resulted in entire menu disappearing completely.

2nd patch resulted in no visible change to existing menus.

i think i am doing it correctly, but i'm no whiz at patching.

i get no hunk fails. looks to patch correctly. i checked the physical file and the changes appear to have been made (though I didn't examine every single line).

am using cygwin on windows vista 64 machine.

perhaps i will just upgrade to the dev version.

#14

VladRM - October 15, 2009 - 06:34

Thanks for the patch ositoblanco. It works great. Hope to see it in 6.x-1.4.

#15

John_Kenney - November 1, 2009 - 02:06

tried again. worked!!

i'm a patching newbie, so must have done something wrong in earlier attempt.

#16

nicholas.alipaz - November 4, 2009 - 00:50
Status:needs review» reviewed & tested by the community

Great patch, works wonderfully! even when using in one's own theme's template.php doing some overrides.

#17

nicholas.alipaz - November 4, 2009 - 18:34
Status:reviewed & tested by the community» needs work

just looking a bit more, it seems that it does not work when items are more than one level deep.

Example 1:

link1
--link2
--link3
----link4
----link5

Example 2:

link1
--link2
--link3
----link4
----link5

Example 1 displays the proper active trails when the bolded item is active, but example 2 does not display correct active trails when the bolded menu item is active.

#18

John_Kenney - November 4, 2009 - 18:57

might be a CSS issue. i had to fiddle with mine to get it to work properly at each level, but now it does. i have 3 level menus like you.

you can look at mine in case that helps: http://www.aboutcallingcards.com/callingcard-review

as with other nice_menu css, it was a bit of a project to get it exactly right.

#19

nicholas.alipaz - November 4, 2009 - 20:14

I doubt it would be a css issue as the active-trail and active classes are output via php.

#20

John_Kenney - November 4, 2009 - 20:27

oh, you are saying the classes are simply not present to style against. i misunderstood.

#21

nicholas.alipaz - November 4, 2009 - 21:11

It is however interesting that your site seems to be outputting the classes. It may have to do with some sort of difference between placing the theme function within one's template.php file or not. I have it in my template.php so that I could add an extra span to each link.

#22

John_Kenney - November 4, 2009 - 21:28

i simply patched the module. perhaps try that to see if it works? putting it in template.php is well beyond my technical know how, so can't help you there.

#23

nicholas.alipaz - November 5, 2009 - 04:30

well, I applied the patch to my module already. Then I copied out the modified/patched theme function and put it in my template.php. It doesn't seem to be working correctly when doing that.

#24

greg.harvey - November 8, 2009 - 14:40
Status:needs work» reviewed & tested by the community

Works fine for me. I suspect something else is interfering with your active trail, nicholas. =/

Are you overriding any of the theme functions in template.php of your theme, by any chance? Could have old copies sticking in there?

Setting back to R&TBC, since it works for amogiz, VladRM, John and it works for me.

#25

nicholas.alipaz - November 9, 2009 - 17:31

Can anyone confirm that the menuitems show "activetrail" classes when the "active" menuitem is two levels deep? Like my previous example:

Example 1 (works, all classes show within my links properly):

link1 [active-trail]
--link2
--link3 [active]
----link4
----link5

Example 2 (doesn't work, active-trail classes are not shown on any parents):

link1 [active-trail]
--link2
--link3 [active-trail]
----link4 [active]
----link5

#26

greg.harvey - November 9, 2009 - 17:45

@nicholas.alipaz I can confirm Example 2 works for me. I'm going to load that on to our client preview server later - I'll send you a link via the contact form so you can see for yourself. Your problem is very strange... I don't have it at all. =/

#27

John_Kenney - November 9, 2009 - 18:05

likewise, #2 works for me -- as you saw on the link i gave you earlier.

i am not clear if, at this point, you have installed only the module -- or are still making modifications to template.php, as well. and i'm sure you've tried clearing caches and so forth to ensure you are seeing the thing clean. otherwise, no idea.

#28

nicholas.alipaz - November 10, 2009 - 01:17

I am actually using this modified theme function, but don't really expect any help on it, since it has been pretty heavily modified. This is in my theme's template.php

BTW, wouldn't it be better if the theme function we have here did more like what I have done in my theme function? classes[] = .... instead of concatenating them together as a string as we go along?

<?php
function mytheme_nice_menu_build($menu, $trail) {
 
$output = ''; //the output menu
 
$i = 0; //the indexed menuitem
 
$c = 0; //the total count of menuitems
  // find out the count for the non-disabled links
 
foreach ($menu as $menu_count) {
    if (
$menu_count['link']['hidden'] == 0) {
     
$c++;
    }
  }
  foreach (
$menu as $menu_item) {
   
$mlid = $menu_item['link']['mlid'];
   
$classes = array();
   
// Check to see if it is a visible menu item.
   
if ($menu_item['link']['hidden'] == 0) {
     
$i++;
     
// setup first/last/even/odd/active classes
     
$classes[] = ($i == 1) ? 'first' : '';
     
$classes[] = ($i == $c) ? 'last' : '';
     
$classes[] = ($i % 2 == 0) ? 'even' : 'odd';
     
$classes[] = (preg_match("/class=\"active\"/", theme('menu_item_link', $menu_item['link']))) ? 'active' : '';
     
$classes[] = 'menu-path-'. mytheme_id_safe($menu_item['link']['href']);
     
// If it has children build a nice little tree under it.
     
if ((!empty($menu_item['link']['has_children'])) && (!empty($menu_item['below']))) {
       
// Keep passing children into the function 'til we get them all.
       
$children = mytheme_nice_menu_build($menu_item['below'], $trail);
       
// Set the class to parent only of children are displayed.
       
$classes[] = $children ? 'menuparent' : '';
       
// check if this item is in the active trail
       
if ($trail && in_array($mlid, $trail)) {
         
$classes[] = 'active-trail';
        }
        else {
         
$classes[] = '';
        }
      }
      else {
       
// check if this item is in the active trail
       
if ($trail && in_array($mlid, $trail)) {
         
$classes[] = 'active-trail';
        }
        else {
         
$classes[] = '';
        }
      }
     
$classes = array_filter($classes);
     
$classes = implode(' ', $classes);
     
$output .= '<li id="menu-'. $mlid .'" class="'. $classes .'"><span>'. theme('menu_item_link', $menu_item['link']) .'</span>';
     
// Build the child UL only if children are displayed for the user.
     
if ((!empty($menu_item['link']['has_children'])) && (!empty($menu_item['below']))) {
        if (
$children) {
         
$output .= '<ul>';
         
$output .= $children;
         
$output .= "</ul>\n";
        }
      }
     
$output .= "</li>\n";
    }
  }
  return
$output;
}
?>

 
 

Drupal is a registered trademark of Dries Buytaert.