Hi Everyone,

I'm new to drupal and this is my first post in the forum. I've searched long and hard for an answer to this and I haven't found anything. I apologize in advance if maybe I didn't search long enough or used the proper keywords to get the answer I'm looking for.

Here is what I'm trying to do.

I'm using 4.7, apache, and a MySQL database, I'm developing my own theme and have based it on the phptemlate engine. For this theme I've got a menu and I've customized the menu_tree, menu_item, and menu_item_link functions to return my menu in an unordered list (so I can style it to the design I've been presented with).

What I'd like to do is be able to find out where I am in the menu array each time the menu_item function gets called. I need to know if I'm at the first index of the array, in the middle or at the end of the array (because I need to spit out different HTML code depending on where I am).

Here is an attempt at an example of what I'm trying to get as an end result:

I've got a menu I've called Main_Nav, simple enough array.. should be something like:

Main_Nav["Home","About Us","Forum","News","Contact Us"]; (though I'm sure it's multi-dimensional and significantly more complicated than that, but you know what I mean)

Drupal builds this:

      <ul>
           <li>Home</li>
           <li>About Us</li>
           ...
          <li>Contact Us</li>
     </ul>

As Drupal builds each <li>NAME</li> I would like to know which index of the array I'm on so I can grab that number and stick in into either a class or id attribute of the li tag, so ultimately I can have:

      <ul>
           <li id="nav_item_0">Home</li>
           <li id="nav_item_1">About Us</li>
           ...
          <li id="nav_item_4">Contact Us</li>
     </ul>

For the life of me I can't figure out how to get this information. My custom functions are as follows (and as you'll see.. they aren't even that custom):


    function my_theme_menu_tree($pid = 1) {
	  if ($tree = menu_tree($pid)) {
		return "\n<ul>\n". $tree ."\n</ul>\n";
	  }
	}
	
	function my_theme_menu_item($mid, $children = '', $leaf = TRUE) {
	   return'<li id="tab'.$mid.'">'. menu_item_link($mid) . $children ."</li>\n";
	}
	
	function my_theme_menu_item_link($item, $link_item) {
	  //return $output;
	  $output = l($item['title'], $link_item['path'], isset($item['description']) ? array('title' => $item['description']) : array());
	  return $output;
	}

Once I get this figured out I'll be able to post a nice "tutorial" on how to build horizontal navigation with horizontal dropdowns. This is really the last thing left to get the design all straightened away.

Thanks in advance!

Pat

Comments

coreyp_1’s picture

  1. What does your code produce so far?
  2. What do you want your code to produce?
  3. If you are patterning the code after something, what are you patterning it after?

I'll see what I can do when I get back in town tomorrow.

Before we get too far into this, though, I must ask you to consider something: What if the index changes when the menu changes, whether by manually changing the items, or by enabling/disabling modules? If this is a concern, it might be better to use the query string as the id, or something along those lines.

Just a thought...

-Corey

thatpatguy’s picture

Hi Corey,

So far this is what I'm getting code wise:

<ul>
  <li class="off" id="tab29"><a href="/drupal/?q=/" title="">Home</a></li>
  <li class="off" id="tab30"><a href="/drupal/?q=node/2" title="">About Us</a></li>
  <li class="off" id="tab31"><a href="/drupal/?q=node/3" title="">Forum</a></li>
  <li class="off" id="tab32"><a href="/drupal/?q=node/4" title="">News</a></li>
  <li class="off" id="tab33"><a href="/drupal/?q=node/5" title="">Contact Us</a></li>
</ul>

in terms of that id attribute what I've done is set up my menu_item as follows:

function olo_theme_menu_item($mid, $children = '', $leaf = TRUE) {
  return'<li class="off" id="tab'.$mid.'">'. menu_item_link($mid) . $children ."</li>\n";
}

by using the $mid variable in my id attribute I'm able to create unique ids for each li tag, however, if I could see where I was in the menu array then I could set up something like this:

function olo_theme_menu_item($mid, $children = '', $leaf = TRUE) {
  return'<li class="off" id="tab'.$which_index.'">'. menu_item_link($mid) . $children ."</li>\n";
}

where the variable $which_index would be my position in the array.

If I had that then I could set up something like this:

function olo_theme_menu_item($mid, $children = '', $leaf = TRUE) {
  if ($which_index == 0){
    return'<div id="first_button"><li class="off" id="tab'.$which_index.'">'. menu_item_link($mid) . $children ."</li></div>\n";
  }elseif ($which_index == ($length_of_menu_array - 1)){
    return'<div id="last_button"><li class="off" id="tab'.$which_index.'">'. menu_item_link($mid) . $children ."</li></div>\n";
  }else{
    return'<div class="middle_button"><li class="off" id="tab'.$which_index.'">'. menu_item_link($mid) . $children ."</li></div>\n";
  }
}

where $which_index was my position in the array and $length_of_menu_array would be the length of the menu array.

By doing something like this it doesn't matter of if the menu changes in length. I only need to know when I'm at the first and last position in the array. Everything else in the middle will all be treated the same. The only problem for scaleability would be if the menu only had one item I guess, but for this project that's not going to be an issue. The above code would work if the menu was anywhere from 2 to 2000 items in length.

I hope that provided more information for you. Thanks again.

Pat

coreyp_1’s picture

one function should do the trick:


function olo_theme_menu_item($mid, $children = '', $leaf = TRUE) {
  // load the menu structure for reference
  $menu = menu_get_menu();
  
  // find out who the parent is
  $pid = $menu['visible'][$mid][$pid];
  // count number of children in this group
  $total_menu_items = count($menu['visible'][$pid]['children']);
  // see where the requested item is in the group
  $which_index = array_search($mid, $menu['visible'][$pid]['children']) + 1;

  // a quick, single return
  return'<div id="'.
    ($which_index == 1 ? 'first_button' :
    ($which_index == $total_menu_items ? 'last_button' : 'middle_button')).
    '"><li class="off" id="tab'.$which_index.'">'. menu_item_link($mid) . $children ."</li></div>\n";
}

sorry, but I like to use the ternary operator to condense code ;o)

you don't have to have the other theming functions, unless you need them for something else

I didn't get to test this, so let me know if it does something weird, OK?

-Corey

thatpatguy’s picture

hey Corey, that looks great.

No worries about the ternary operator, I just wrote it all out to make sure I was being as clear as possible to what I was looking to do :)

I'm going to give that function a try tomorrow and I'll let you know how it works out. Thanks again!

Pat