It seems like megamenu strips out all the active-trail classes in my menus. It leaves an "active" class, but only on the top-level parent "li" tag, and on the leaf-node "a" tag. So in a three-tier menu, the middle tier has no active attributes to target my css to.

A regular (non-megamenu) version of the same menu gets all its active-trail classes properly inserted by core. What is megamenu doing to remove these?

<ul id="megamenu-menu-portfolio" class="megamenu-menu stacking megamenu-skin-myskin">
	<li id="megamenu-mlid-875" class="megamenu-parent megamenu-parent-0 odd half-1 leaf-0 first menu-875 first last active">
		<h2 class="megamenu-parent-title">
		<a href="/portfolio/work">Portfolio</a>
		</h2>
		<ul class="megamenu-bin megamenu-slots-stacking" style="top: -9000px; left: 0px; width: 200px;">
			<li id="megamenu-mlid-876" class="megamenu-slot megamenu-slot-0 odd half-1 leaf-0 first first">
				<h3 class="megamenu-slot-title">
				<a href="/portfolio/work">Work</a>
				</h3>
				<ul class="megamenu-items ">
					<li id="megamenu-mlid-935" class="megamenu-item megamenu-item-0 odd half-1 leaf-0 first first">
						<a class="active" href="/portfolio/work/hp">Company 1</a>
					</li>
					<li id="megamenu-mlid-939" class="megamenu-item megamenu-item-1 even half-1 leaf-1 ">
					<li id="megamenu-mlid-941" class="megamenu-item megamenu-item-2 odd half-1 leaf-2 ">
					<li id="megamenu-mlid-945" class="megamenu-item megamenu-item-3 even half-1 leaf-3 ">
					<li id="megamenu-mlid-946" class="megamenu-item megamenu-item-4 odd half-2 leaf-4 ">
					<li id="megamenu-mlid-947" class="megamenu-item megamenu-item-5 even half-2 leaf-5 ">
					<li id="megamenu-mlid-943" class="megamenu-item megamenu-item-6 odd half-2 leaf-6 last last">
				</ul>
			</li>
			<li id="megamenu-mlid-880" class="megamenu-slot megamenu-slot-1 even half-2 leaf-1 last last">
		</ul>
	</li>
</ul>

Comments

squeakyferret_sf’s picture

I think I found my answer. I don't know how to do a patch, so here are the changed functions below. Both are in megamenus.utilities.inc:

/**
 * Retrieve a menu and pre-style before theming
 *
 * This function currently removes all "hidden" items, which could be
 * handled in the single iteration of the theme function.  But, I forsee
 * a need for other prep work that might be simmplfied with this second function
 *
 * Will be used in the future to add/alter attributes prior to theming
 *
 * @param $menuname
 *    The name of the menu to extract
 *
 * @return
 *    The pre-styled menu tree
 */
function _megamenu_get_menu_tree($menuname) {
  $menutree = menu_tree_all_data($menuname);
  $menutree_page = menu_tree_page_data($menuname); // Contains active trail
  foreach($menutree as $tier_1_key => $tier_1_item) {
		if ($menutree_page[$tier_1_key]['link']['in_active_trail']) {
			$menutree[$tier_1_key]['link']['in_active_trail'] = TRUE;
		}
    
		if ($tier_1_item['link']['hidden'] == 1 || empty($tier_1_item['link']['link_title'])) {
      unset($menutree[$tier_1_key]);
    }
    else {
			if ($tier_1_item['below']) {
				foreach($tier_1_item['below'] as $tier_2_key => $tier_2_item) {
					if ($menutree_page[$tier_1_key]['below'][$tier_2_key]['link']['in_active_trail']) {
						$menutree[$tier_1_key]['below'][$tier_2_key]['link']['in_active_trail'] = TRUE;
					}
					if ($tier_2_item['link']['hidden'] == 1 || empty($tier_2_item['link']['link_title'])) {
	        	unset($menutree[$tier_1_key]['below'][$tier_2_key]);
	        }
					else {
						if ($tier_2_item['below']) {
							foreach($tier_2_item['below'] as $tier_3_key => $tier_3_item) {
								if ($menutree_page[$tier_1_key]['below'][$tier_2_key]['below'][$tier_3_key]['link']['in_active_trail']) {
									$menutree[$tier_1_key]['below'][$tier_2_key]['below'][$tier_3_key]['link']['in_active_trail'] = TRUE;
								}
								
								if ($tier_3_item['link']['hidden'] ==1 || empty($tier_3_item['link']['link_title'])) {
		                unset($menutree[$tier_1_key]['below'][$tier_2_key]['below'][$tier_3_key]);
		            }
		            else if ($tier_3_item['below']){
                	unset($menutree[$tier_1_key]['below'][$tier_2_key]['below'][$tier_3_key]['below']);
            		}	
							} // end level 3 loop
						}
					}
				} // end level 2 loop
			}
		}
  } // end level 1 loop
  return $menutree;
}

/**
 * Determine if a particular mega menu item is active.
 *
 * TODO: make it better
 *
 * @param <string> $branch (of mega menu)
 */
function _megamenu_active_classes($branch) {
	if (!is_array($branch)) return '';
	
	$active = '';
	
	if ($branch['link']['in_active_trail']) {
		if  (array_key_exists('below', $branch)) {
			$active = ' active active-trail';
		}
		else {
			$active = ' active-trail';
		}
	}
	
	return $active;
}

In the original, menu_tree_page_data() is used to pull a menu array that contains active_trail info, and then it is never referenced again. My assumption is the author intended to use that active trail data. The new version references that active trail information, inserting it into the $menutree array. _megamenu_active_classes() needed modification as well to properly reference the 'below' array key.

This works, and I get active trails now in all my menus.

zd370’s picture

Status: Active » Needs review
StatusFileSize
new896 bytes

I basically ended up doing what you have done. The megamenu was not keeping an active trail for pages that are beyond tertiary level.

jumoke’s picture

Great fix, thanks all. This needs to be committed to head.

thekatic’s picture

StatusFileSize
new914 bytes

First to thank you for this very useful patch, but I had to extend it a bit.
Without this extension, "Page not found" will through you an error.
Maybe this is not the best way to do it, but it works.

  • ram4nd committed 61068ba on 7.x-1.x authored by thekatic
    Issue #1405812 by kris84, thekatic: How to get active-trail classes in a...
ram4nd’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.