Blogs  Work culture, passion and sharing ideas

You are here: 

You are here

Home  »  Blogs  »  How to theme Nice Menus as Table Based Menu

How to theme Nice Menus as Table Based Menu

First things first, Drupal gives great amount of flexibility to both Module Developers and Site Developers, whether its about theming or creating your own little module that integrates into Drupal. For any thing to be themed ie. anything uses or calls Drupal theme() function there is an opening for developers to change default theming. So, for Nice Menus just check out the source code of this module where we have the theme() function call or lets say the theme hook, it takes place exactly at these two functions which are of our interest:

function theme_nice_menu($id, $menu_name, $mlid, $direction = 'right', $menu = NULL)

and

function theme_nice_menu_build($menu)

So, well use them as our starting point; in whichever theme youre working on there's template.php file designed specially for this kind of purpose. Open it up and place the two code segments below into it:

/*
  NOTE: BEFORE YOU ACTUALLY DO THIS PLEASE CLEAR ALL CACHES FROM YOUR DRUPAL SITE
  This is the point when Nice Menus renders a fully build Tree menu to the $output variable
  We change it here to be wrapped inside a table instead of UL elements
*/

function YOURTHEMENAME_nice_menu($id, $menu_name, $mlid, $direction = 'right', $menu = NULL) {
  $output = array();
  if ($menu_tree = theme('nice_menu_tree', $menu_name, $mlid, $menu)) {
    if ($menu_tree['content']) {
      $output['content'] = '<table width="100%" class="site-menu"><tr>' .$menu_tree['content'] .'</tr></table>'."n";
      $output['subject'] = $menu_tree['subject'];
    }
  }
  return $output;
}
}

and the consequent theme function that actually builds the menu tree:

function YOURTHEMENAME_nice_menu_build($menu) {
  $output = '';
  global $is_child;
  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);
      $current_node = str_replace('node-', '', $clean_path);
      $path_class = 'menu-path-'. $clean_path;
      if ($current_node == $GLOBALS['active_node']) {
          $path_class.= ' active-content';
      }
      // If it has children build a nice little tree under it.
      if ((!empty($menu_item['link']['has_children'])) && (!empty($menu_item['below']))) {
        $is_child = true;
        // Keep passing children into the function 'til we get them all.
        $children = theme('nice_menu_build', $menu_item['below']);
        // Set the class to parent only of children are displayed.
        $parent_class = $children ? 'menuparent ' : '';
        if (isset($parent_class)):
          $output .= '<td id="menu-'. $mlid .'" class="'. $parent_class . $path_class .'">'. theme('menu_item_link', $menu_item['link']);
        else:
          $output .= '<li id="menu-'. $mlid .'" class="'. $parent_class . $path_class .'">'. theme('menu_item_link', $menu_item['link']);
        endif;
        // Build the child UL only if there is a child menu
        if ($children) {
          $output .= '<ul>';
          $output .= $children;
          $output .= "</ul>n";
        }
        /* Notice that we have used <td> if we find a parent class otherwise it goes into <LI> elements WHY? Here's Why, All the parent menu items will be rendered inside table cells so our idea is to create a menu system that can resize proportionally and horizontally to the browser's full width, the subsequent child elements can be placed into <UL><LI> elements which can be themed easily */
        if (isset($parent_class)):
          $output .= "</td>";
          //Adds some extra separators after each td
          $output .= '<td><span class="sep1"></span></td>'."n";
        else:
          $output .= "</li>n";
        endif;
      }
      else {
        if ($is_child == false) {
          $output .= '<td id="menu-'. $mlid .'" class="'. $path_class .'">'. theme('menu_item_link', $menu_item['link']) .'</td>'."n";
          //Adds some extra separators after each td
          $output .= '<td><span class="sep1"></span></td>'."n";
        }
        else
        {
          $output .= '<li id="menu-'. $mlid .'" class="'. $path_class .'">'. theme('menu_item_link', $menu_item['link']) .'</li>'."n";
        }
      }
    }
  }
  $is_child = false;
  return $output;
}

And there you have it output would turn out to be a table based menu like below:

Nice menu as table

And the HTML / XHTML code output for the menu would turn out to be like:

<table width="100%" class="site-menu">
  <tr>
    <td id="menu-262" class=""><a class="highlighted icon-bullet1 f-none" href="/content/our-views">Our Views</a></td>
    <td><span class="sep1"></span></td>
    <td id="menu-264" class="menu-path-node-4"><a href="/content/greater-depression" title="A Greater Depression">A Greater Depression</a></td>
    <td><span class="sep1"></span></td>
    <td id="menu-265" class="menuparent menu-path-node-5"><a href="/content/what-we-see" title="What we see">What we see</a>
      <ul>
        <li id="menu-266" class="menu-path-node-9"><a href="/content/too-much-growth" title="Too much growth...">Too much growth...</a></li>
        <li id="menu-267" class="menu-path-node-10"><a href="/content/too-much-money" title="..too much money..">..too much money..</a></li>
        <li id="menu-268" class="menu-path-node-13"><a href="/content/and-exits-closed" title="..and exits closed.">..and exits closed.</a></li>
      </ul></td>
    <td><span class="sep1"></span></td>
    <td id="menu-269" class="menuparent menu-path-node-14"><a href="/content/what-we-expect" title="What we expect">What we expect</a>
      <ul>
        <li id="menu-270" class="menu-path-node-15"><a href="/content/5-years-out" title="5 years out">5 years out</a></li>
        <li id="menu-271" class="menu-path-node-16"><a href="/content/what-we-foresee-next-3-6-months-nov-19-2008-updated-nov-25-2008" title="What we foresee for the next 3-6 months">3-6 months</a></li>
        <li id="menu-272" class="menu-path-node-17"><a href="/content/our-1-month-outlook-nov-19-2008" title="Our 1 month outlook (Nov-19, 2008)">1 month outlook</a></li>
      </ul></td>
    <td><span class="sep1"></span></td>
    <td id="menu-273" class="menuparent menu-path-node-18"><a href="/content/cures" title="The cures">The cures</a>
      <ul>
        <li id="menu-292" class="menu-path-node-28"><a href="/content/credit-default-swaps-undoing-nightmare-first-ideas" title="Credit Default Swaps - Undoing a Nightmare - First Ideas">CDS/CDO cleanup</a></li>
      </ul></td>
    <td><span class="sep1"></span></td>
  </tr>
</table>

Copyrights © 2007-2020 Raven Developers. All rights reserved.

Powered by: Drupal 7 and Foundation 4

preliminary