How to create a block that will display any sub-menu links to the page you are on

Drupal Version
7

If you have nested menu links (sub-menus) in your Drupal menu system then sometime you may want to display any menu items that are children of the page you are currently on. This code will create a Drupal block that you can position within any of your theme's regions and it will automatically display an HTML list of sub-menu items.

NOTE: the following code will go into your custom module. If you're not sure how to create a custom module we've created a guide to creating a basic Drupal module.

First create your hook_block_info() that will tell Drupal about your new block. Be sure to give it a proper machine name and description.

<?php
/**
 * Implements hook_block_info().
 */
function YOUR_MODULE_NAME_block_info() {
 
$blocks = array();
 
$blocks['YOUR_MODULE_NAME_submenu'] = array(
   
'info' => t('Submenu Block'),
  );
  return
$blocks;
}
?>

Next, create your hook_block_view() that will be called when your block is viewed. Be sure to use your block's machine name in the switch statement.

$block['content'] will be the function name that contains the logic of the block.

<?php
/**
 * Implements hook_block_view().
 */
function YOUR_MODULE_NAME_block_view($delta='') {
 
$block = array();
 
  switch(
$delta) {
    case
'YOUR_MODULE_NAME_submenu' :
     
$block['content'] = YOUR_MODULE_NAME_submenu();
      break;
  }
  return
$block;
}
?>

The following is the callback function that will handle most of the logic of building the sub-menu and returning the HTML for the block output.

<?php
function YOUR_MODULE_NAME_block_view_create() {
 
$block = array();
 
$menus = menu_tree('main-menu'); 
 
$output = drupal_render(YOUR_MODULE_NAME_menu_tree_below($menus));
 
 
$block = array(
   
'submenu' => array(
     
'#prefix' => '<div class="submenu">',
     
'#type' => 'markup',
     
'#markup' => $output,
     
'#suffix' => '</div>',
    ),   
  );
  return
$block;
}

// Recursive function to build sub-menu
function YOUR_MODULE_NAME_menu_tree_below($tree) {
  foreach (
$tree as $menu) {
    if(!empty(
$menu['#original_link']['in_active_trail']) && $menu['#below']) {
     
$r = YOUR_MODULE_NAME_menu_tree_below($menu['#below']);
      if (
$r==0) { return $menu['#below']; }
      else { return
$r; }
    }
  }
  return
0;
}
?>

Once you modify the code as needed and place it all within your custom mode you should now see a new block listed in Drupal's block listing page. If you don't see it then clear the Drupal caches. You can now place this block where you'd like it on your site and theme it as desired. The sub-menu will be automatically rendered when available.

Drupal automatic submenus

Author Information

Written by: Shawn Ostermann

Shawn is a Drupal Specialists with over 12 years of experiencing building and developing Drupal websites including custom module development and e-commerce websites.