hello.

With Context menu you can set menu items to "active". This does not work for me in a menu_block.

I have Three levels of Primary Links, and secondary Links is set to come from primary. I print out the primary and secodary (second lvl from primary) in my theme and the third llv by menu_block. When I set a menu item active with "Context" Module, it will only show primary and secondary menu. In primary and secondary the menu items get "active-trail" style. The block is not printed.

I hope you understand what I try to explain. Is this a bug in the module or am I doing something wrong?

THX in advance.

CommentFileSizeAuthor
#7 mbcontext.tgz1.6 KBNikLP
#4 menu_block_context.tgz1.26 KBNikLP
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

nauthiz693’s picture

I had the same problem.. I fixed it by creating a module with the following code:


/**
 * Handles the menu block alter hook, and makes modifications to the menu tree
 *
 * @param Tree $tree
 * @param Configuration options $config
 */
function MODULENAME_menu_block_tree_alter(&$tree, $config) {
	
	$activeTrailSet = false;
	
	foreach ($tree as $item) {
		$activeTrailSet |= $item['link']['in_active_trail'];	
	}	
	
	if (!$activeTrailSet) {
	  require_once('sites/all/modules/context/context.core.inc');
	  MODULENAME_add_active_path_by_context($tree, context_active_values('menu'));
	}
	
}


/**
 * This method sets the active trail on a menu tree by the context that it's in.
 * Requires the context module for this to work properly.
 *
 * @param array $tree - the tree of links
 * @param array $active_paths - the paths that should be set active in the menu
 */
function MODULENAME_add_active_path_by_context(&$tree, $active_paths) {
	
	// Loop through all the items in the current level of the tree
	foreach (array_keys($tree) AS $key) {	
		if (!empty($tree[$key]['link']['href']) && in_array($tree[$key]['link']['href'], $active_paths)) {
			$tree[$key]['link']['in_active_trail'] = true;
			$tree[$key]['link']['localized_options']['attributes']['class'] .= " active";
			return true; // Don't want to keep looking, only want one active trail
		} elseif (!empty($tree[$key]['below'])) {
			$tree[$key]['link']['in_active_trail'] = MODULENAME_add_active_path_by_context($tree[$key]['below'], $active_paths);		
			
			// Stop looking and return true if an item below the current one is active.
			if ($tree[$key]['link']['in_active_trail']) { 
				return true; 
			}
		}
	}
	
	// If we didn't find an active item, return false;
	return false;
	
}

I should probably create and submit a module that does the above, but I don't have time / motivation to go through the rigamarole.

Just create a module, and replace MODULENAME with the name of your module.

JThan’s picture

Wow, thx. I will definitly try this.

NikLP’s picture

Will this fix the issue where when the active menu is set with context, unless the *actual menu* item that is set to trigger the block is active, no block is shown?

ie secondary menu item block shows up on "aar" but not on "aar/groups" ? Is that what this is about? Didn't quite follow the initial post...

NikLP’s picture

FileSize
1.26 KB

I have had success with this module, and attached is a version with module folder, info file and dependencies sorted out. Hope it helps someone.

I've only tested it with showing the children of primary menu items in one block.

BrightBold’s picture

@NikLP -
That functionality is exactly what I was looking for, but when I enabled your module I got the following error:

Fatal error: Call to undefined function context_active_values() in .../sites/all/modules/menu_block_context/menu_block_context.module on line 18

Let me know if I can provide you with any additional information that will help troubleshoot.

NikLP’s picture

Hmm... this is likely caused by the include on line 17. Suggest you try removing line 17 and replacing with the following - it's probably not finding the required context module include as you likely have it in a different location to the one that is (incorrectly) hard coded into this module.

require_once(drupal_get_path('module', 'context') . '/context.core.inc');
NikLP’s picture

FileSize
1.6 KB

Here's a slightly improved version of the module with better code style and the hard coded module directory taken out.

Mark Trapp’s picture

Thanks for this: it works perfectly, with one caveat. Let's say you have a menu block that is linked to the following menu:

Item 1
- Subitem 1
Item 2
Item 3
Item 4

And you set up a context reaction to set "Subitem 1" as the active menu item. Unless "Expand all children of this tree" is checked in the block's configuration, the 'below' array in the menu tree is never populated for "Item 1" and thus, the menu item is never matched.

This could have implications for people who don't want to expand out the entire menu, and likely could be solved with a different matching algorithm, but the solution here works great outside of that problem.

Mark Trapp’s picture

Also, context_active_values() doesn't exist in Context 3, so you need to define the active paths a different way. Based on the solution in #15 from #586396: Context Active menu problem, I replicated the function as such:

 function _menu_block_context_active_values($context_name) {
  $contexts = context_get();
  $active_paths = array();

  // If there aren't any contexts available, then there aren't any
  // context-defined active paths.
  if (!is_array($contexts['context'])) {
    return $active_paths;
  }

  foreach ($contexts['context'] as $context) {
    if (array_key_exists($context_name, $context->reactions)) {
      $active_paths[$context->reactions[$context_name]] = $context->reactions[$context_name];
    }
  }
  
  return $active_paths;
} 

There may be a conflict with Context Contrib 3 as well, but I haven't isolated whether it's actually a conflict or a general problem with Context Contrib 3 yet.

If you guys are cool with it, I can wrap up these modules and my additions into a project on Drupal Contrib and maintain it so you guys don't have to. I'd like to explore how to get around the "Expand all children of this tree" requirement in the future anyway.

nauthiz693’s picture

Yeah of course, that'd be awesome. I'd do it myself, but I'm going to law school in a couple months, so I don't think I'd be able to maintain it :-) That's why the drupal community (and open source in general) is so great.

BrightBold’s picture

@amorfati - will you post in this issue to let us know if you release a contrib version? This would be a really useful module.

Mark Trapp’s picture

Status: Active » Fixed

@BrightBold: done and done.

I just released Context: Menu Block, which contains the code here, a few bug fixes, and a Context 3 release. If you're running Context 2, use the 6.x-2.x branch; otherwise use 6.x-3.x. Bad Things™ happen when you mix the versions due to Context's API change.

Let me know if there's any problems using it.

Status: Fixed » Closed (fixed)

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

nauthiz693’s picture

@amorfati - Sweet, works brilliantly. Thanks for maintaining this!

jedihe’s picture

[Sorry for waking this up, but I think this can be useful for someone trying to solve this problem]

I think a better fit for getting menu blocks to behave this way is by using Menu Position. Although it does not have so much conditions as context, the integration with menu block seems to be complete; also, it is possible to write plugins... so maybe it could have many types of conditions as in context.

Nicolas Bouteille’s picture

Thank you so much the Menu Position module saved my day !