Hello good people of Drupal !

As a project required me to insert links to sub-pages in each pages, I found convenient to use Drupal's primary links to save me the grim chore to include (and eventually update) manually the links to their sub-pages. I found no module having this features so I made one needing nothing more that Drupal's core as I use its menu API. Here's the PHP snippet to put in a block body to have this feature :

//source found at http://drupal.org/node/77099#comment-215118

// get the menu items that lead to the current menu item
$active_trail =_menu_get_active_trail();

// get the primary menus id
$pmid = variable_get('menu_primary_menu', 0);

//does the menu id of the active top-level link match it ?
if ($active_trail[0] == $pmid)
{
  // Retrieves the current menu item
  $menu_active = menu_get_active_nontask_item();

  //create a tree starting from the current menu item
  // Based on Drupal's menu.inc function : menu_tree and theme_menu_tree

  $pid = $menu_active;
  //______________________

  print "\n<ul class=\"menu\">\n";

  $menu = menu_get_menu();
  $output = '';

  if (isset($menu['visible'][$pid]) && $menu['visible'][$pid]['children']) {
    foreach ($menu['visible'][$pid]['children'] as $mid) {
      $type = isset($menu['visible'][$mid]['type']) ? $menu['visible'][$mid]['type'] : NULL;
      $children = isset($menu['visible'][$mid]['children']) ? $menu['visible'][$mid]['children'] : NULL;
      //$output .= theme('menu_item', $mid, menu_in_active_trail($mid) || ($type & MENU_EXPANDED) ? theme('menu_tree', $mid) : '', count($children) == 0);
      $output .= theme('menu_item', $mid, FALSE);
    }
  }

  print $output;
  print "\n</ul>\n";
}

But this would show in pages not in a menu trail or which don't have a menu children. To avoid this set the block Page specific visibility to "Show if the following PHP code returns TRUE" and insert the following snippet :

$context_menu = FALSE;

// Retrieves the current menu item
$menu_ctx=menu_get_item(menu_get_active_nontask_item());

// Does the current menu have children
if (count($menu_ctx['children'])-4 > 0) // has 4 items not in the menu
{
  $context_menu = TRUE;
}

return $context_menu;

I wonder how much use you'll get of this and if you think it's worth making a module out of it.

Thank you for your feedback and constructive criticism,
William

Comments

mikeschinkel’s picture

I've done something that I think might be similar (though with probaby 10x as much code), but I'm having trouble following what yours does. A link to a screen shot would be a great help for me to visualize...

dynv’s picture

There's a screenshot of the running page at http://picasaweb.google.com/DynVec/Screenshots/photo#5138332832959245362

You may be interested in another snippet I made : primary link bar extender.

On another matter, the Page specific visibility PHP snippet has been included in : menu trail and has children.

crashtest_’s picture

This is what I ended up doing because I couldn't get the Secondary Links block to work.

First, I set all of my Menu Settings (admin/build/menu/settings) to "Primary Links." I did this so that "children of the active primary menu link will be displayed as secondary links," as it says. Then I inserted this code into a block. This should display links to child pages of whatever primary link page you are on or under. Make sure that you set your "Input Filter" to "PHP."

<?php
  
  $arr = menu_secondary_links();
  
  if($arr){
    foreach ($arr as $value) {
      $secondary_link_title = $value['title'];
      $secondary_link_href = $value['href'];

      print '<a class="related-link" href="/'.$secondary_link_href.'">'.$secondary_link_title.'</a>';
    }
  }

?>

Then, set your "Show if the following PHP code returns TRUE (PHP-mode, experts only)" to:

<?php
  if(menu_secondary_links()): return TRUE
?>
dynv’s picture

Yes just I predicted to you on IRC. The problem is that if you hand in the site to a non-Drupaler, they might not know and even if you tell them, they will probably forget thus you will constantly have to be prepared to resolve them problem. If we find the D6 alternative problematic function _menu_get_active_trail() then replace it in this code, it will be much better.

crashtest_’s picture

So, what you are saying, is if someone inadvertently changes the "Secondary Links" to "Navigation" it would no longer produce a submenu for the current page, instead it produces the Navigation menu. So, I have changed the code to this:

<?php
  
  $arr = menu_navigation_links(variable_get('menu_primary_links_source', 'primary-links'), 1);
  
  if($arr){
    foreach ($arr as $value) {
      $secondary_link_title = $value['title'];
      $secondary_link_href = $value['href'];

      print '<a class="related-link" href="/'.$secondary_link_href.'">'.$secondary_link_title.'</a>';
    }
}

?>

Then, we must make the PHP conditional statement reflect this as well:

<?php
  if(menu_navigation_links(variable_get('menu_primary_links_source', 'primary-links'), 1)): return TRUE
?>

Thanks for catching that DynV, this should take care of that concern.

dynv’s picture

would it still work if both primary and secondary links were to something else (like navigation) ?

crashtest_’s picture

There wouldn't be a need for this code if all of the menus were switched to Navigation, would it, as this code is made to expose the child links to a Primary Links menu? So to me, that question doesn't really apply.

But, to answer your question, the code acts just exactly as it should, it produces links that are related to the Primary Links, whatever they are. In this scenario that would be the main Navigation link (top-level link would be the best I can relate) that you are currently on.

So, for example, if you were to select "Create Content" from your (now) Primary Links/Navigation menu, this code produces the following links: Book page, Page, and Story. If you select My Account, it produces a sub-menu of: Content management, Site building, Site configuration, User management, Reports, and Help. The code is meant to produce a sub-menu of child pages of whatever you have set your primary links to be.

To me, this seems like a moot point, as the menu that had been originally created would at that point be gone so you would have more to worry about then whether the extra functionality of a sub-menu was working or not.

This code works perfectly for me, even if I create a custom menu, and assign it to Primary Links, at that point it would produce child pages of that custom menu, perfect! That was what it is meant to do.

Maybe I am missing your point though. I didn't expect it to do anything other than what I outlined above, but perhaps there was supposed to be something else you thought this code would do?

dynv’s picture

The menu system doesn't need to be displayed to be in working condition, in fact I contributed to sites where it used a custom module and no primary links from the settings. So if it passes the test about both primary and secondary links, it should be fine !

Cardinals27’s picture

how do i set the link to display as active or selected when on that particular page using this function?

this code works pretty much great for me, otherwise.
thx