logo
Ask your WordPress questions! Pay money and get answers fast! (more info)

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.

$70
How do I create a multi-tiered wp_nav_menu?

I'm in the middle of making my own theme, but I have run into some trouble. I'm using the new wp_nav_menu function, and I'm running WP 3.0.1.

As you might already know, wp_nav_menu is nesting the sub-menus into the parent ul. This seems to be the main problem. If I could find out how to write a custom walker that would output ONLY the active menu's sub-menu (if any), and output it below the parent menu, I could get this to work.

Here's how I want it to look:
http://www.alekstef.com/rot/Skjermbilde%202010-09-18%20kl.%2015.53.55.png

The menu you can see in the screenshot is achieved with alot of dirty CSS tweaking. As you can see, the page title is not affected by the sub-menu due to the position, which is set to absolute. That's the only way I get it to look the way I want. However, this does not work satisfactory in IE, and, like I mentioned, other items don't move according to it.

SO - to summarise: I need someone to (help me) write a custom wp_nav_menu walker that removes the nesting, puts every sub menu in its own div below the main menu, and shows only the active page's subpages in the menu.

I think that was all.. Be sure to ask if something is unclear, or if you have a question. Thanks in advance!

Best regards,
Aleksander Steffensen

This question has been answered.

attachment image View Attachment

Aleksander Steffensen | 09/18/10 at 10:03am Edit


(10) Possible Answers Submitted...

See a chronological view of answers?

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

  • avatar
    Last edited:
    09/18/10
    10:12am
    Baki Goxhaj says:

    I can achieve that through CSS, making IE happy too - would you like to hire me?

    • 09/18/10 10:19am

      Aleksander Steffensen says:

      Hello.

      I'm sorry, but I want a non-CSS solution for this :) Thanks anyway!

    • 09/18/10 10:27am

      Baki Goxhaj says:

      Thanks and good luck with it :)

  • avatar
    Last edited:
    09/18/10
    10:31am
    akosipau says:

    I think you don't need a custom walker for wp_nav_menu to achieve that. just css and javascript will do the trick. let me know if your interested

    • 09/18/10 10:37am

      Aleksander Steffensen says:

      Thanks for your answer. You might be right, it might be possible with CSS and JavaScript, however I want a solution that is as "clean" as possible. It's possible that I'm too fixed on this, but.. yeah, that's my request :)

    • 09/18/10 11:33am

      akosipau says:

      if you want to hands-on with it, the easiest way is to follow this tutorial

      http://www.alistapart.com/articles/hybrid

      to form the menu and then, add a javascript to complete it:

      ex. using jquery

      jQuery(document).ready(function(){
      jQuery('#access li ul').mouseover(function(){
      if(! jQuery(this).parent().hasClass('on')){
      jQuery(this).parent().addClass('on');
      }
      });
      jQuery('#access li ul').mouseleave(function(){
      if(jQuery(this).parent().hasClass('on')){
      jQuery(this).parent().removeClass('on');
      }
      });
      jQuery('#access ul > li > ul').each(function(){

      jQuery(this).parent('li').addClass('off');

      });

      jQuery('#access ul > li > ul > li > ul').each(function(){

      jQuery(this).parent('li').addClass('off');

      });

      jQuery('#access li.current_page_item, #access li.current_page_ancestor').each(function(){
      jQuery(this).addClass('active');
      });
      });


      hope this will give you a good start :)


    • 09/18/10 11:35am

      akosipau says:

      oh my bad. change the #access to #nav

    • 09/18/10 11:58am

      akosipau says:

      oh i forgot. it should be declared like this

      <div id="nav">
      <?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); ?>
      </div>

      and just copy the css from

      http://www.alistapart.com/articles/hybrid

      then add the javascript code posted above

    • 09/18/10 8:31pm

      akosipau says:

      Hello Aleksander,

      This can't be done using CSS only. Possibly yes but will not look good in all major browsers especially on IE. You need a custom walker if you want DIV not UL for submenu but still you need CSS and JAVASCRIPT ( i prefer JQUERY ) to fully achieve a horizonal menu with horizontal submenu

    • 09/18/10 8:37pm

      Aleksander Steffensen says:

      Hello again!

      Thank you for acknowledging that. That has been my opinion all along, although I am not quite sure if javascript/jQuery is necessary? Do you have a complete or partial solution?

    • 09/18/10 9:13pm

      akosipau says:

      Yes i believe its necessary to keep it clean and make it compatible in all other browsers rather than using pure css which i doubt it will have a good looking menu in all major browsers.

      i have coded a sample using CSS/JQUERY but submenu is not on DIV but in UL so you wont have to waste some time creating a walker

      here have a look: http://wpcrunchy.com/demo/?preview=1&template=testla&stylesheet=testla&

      not yet complete though (active or selected page not yet coded)

    • 09/18/10 9:15pm

      akosipau says:

      my bad again. here's the right link:

      http://wpcrunchy.com/demo/?wptheme=testla

    • 09/18/10 9:18pm

      Aleksander Steffensen says:

      Ok. In your example, the submenu doesn't hide as standard.. I suppose that's easy to achieve? Also, did you look at the attachment in my first post, just for reference?

    • 09/18/10 9:34pm

      akosipau says:

      Yes i did. i just create a quick sample how you can achieve it using jquery and css. anyways, i just push the updates on the demo which i think this is what you want.

      DEMO HERE: http://wpcrunchy.com/demo/?wptheme=testla

    • 09/18/10 9:40pm

      Aleksander Steffensen says:

      Well, it's getting better... Now if you get the sub menu to show up on click, not hover...? And if there is content just beneath the menu, how will the content, for instance a page title, behave when the sub menu appears? Ideally it would be pushed down to maintain the space between menu and content.

    • 09/18/10 10:16pm

      akosipau says:

      patch the javascript so it activate when click not hover. well, since submenu it set to absolute then it will just cover the content below and no space will be added

      DEMO: http://wpcrunchy.com/demo/?wptheme=testla

  • avatar
    Last edited:
    09/18/10
    10:49am
    Denzel Chia says:

    Hi,

    I had taken a look at your attachment.

    Are you trying to achieve the navigation as shown in this link?
    http://users.tpg.com.au/j_birch/plugins/superfish/#sample4
    click on the examples tab and nav-bar style tab to see the example.

    If yes, you can use this superfish to style your menu, it works with wp_nav_menu()

    If not I will try to write you a walker class.

    Thanks.

    Previous versions of this answer: 09/18/10 at 10:48am | 09/18/10 at 10:49am

    • 09/18/10 10:52am

      Aleksander Steffensen says:

      Hello, and thank you for your answer!

      The superfish-thing is close to what I want.. I want no drop-down menus, though. It might work ok like a backup-solution in case nothing else works out.

      You're the only one who has actually offered to solve the problem the way I want to, so I'll take that. If you manage to write a walker that does what I want, that would've been awesome! :) Please ask if something is unclear regarding the functionality I requested.

    • 09/18/10 12:20pm

      Denzel Chia says:

      Hi,

      If you want to use the superfish menu that I recommend,
      There is no need to write a new walker for this.
      As long as you tag only sub menu item to a parent item and no sub sub menu item,
      The dropdown list will not appear.
      What I mean is you tag only second level menu item in wordpress menu and the drop down will not appear.

      If you want me to set up for you the whole menu in your theme, you can email a zip copy of your theme to me. I can setup it up the menu system for you.

      You can find my website and contact in my profile page.
      http://www.wpquestions.com/user/profile/id/1709

      Members are not allow to post their contact email here.

      Hope you understand.

      Thanks.

    • 09/18/10 12:36pm

      Denzel Chia says:

      By the way,

      You don't need to pay me if it don't work.

      Let me code it into your theme, if it works, then you select my answer and pay me,
      If it don't, you get someone else to help. :)

      Thanks.

    • 09/18/10 1:03pm

      Aleksander Steffensen says:

      Hi.

      Like I said to the others, I'm not really interested in a jQuery/CSS solution. It would have to be a last resort. Thank you, though.

    • 09/18/10 1:30pm

      Denzel Chia says:

      What I told you is to use wp_nav_menu(),
      So that you can set up your theme menu in wordpress admin easily.
      wp_nav_menu will print out a list of your menu on you theme,

      Then you use jQuery superfish, including its CSS to style it to the menu you want.

      There is no walker that can style your menu without the help of at least CSS!
      PHP is server side, javascript, css, html is client side. You use javascript or css to style elements.

      Maybe you can write a walker with inline css to style the menu, but you still need inline css!

      I doubt you know anything about programming.

      Thanks and I would not waste my time here anymore.

    • 09/18/10 1:39pm

      Aleksander Steffensen says:

      Denzel,

      I did not mean to upset you. I know a thing or two about programming, and of course I will need to style the menu using CSS. I will not, however, use dirty CSS solutions that is posted here by some, to make it look good.

      What I need is for someone to change the way the menu is output. No nesting of ul's! Only one sub-menu should be shown at a time, and it would have to be in an own div beneath the main menu.

      I do not want to use the superfish-thing, as I'd prefer staying away from plugins and stuff like that, AND I don't want jQuery-stuff on this website.

    • 09/18/10 1:48pm

      Aleksander Steffensen says:

      What I meant to say is, I will not use dirty CSS fixes to help place the menus correctly when this can and should be done by changing the HTML-output.

    • 09/19/10 3:56am

      Denzel Chia says:


      I do not want to use the superfish-thing, as I'd prefer staying away from plugins and stuff like that, AND I don't want jQuery-stuff on this website.


      You rejected my proposal on using jQuery Superfish, but you accepted akosipau's demo?
      Oh come on, view the source! Its what I am offering to do for you! wp_nav_menu styled by jQuery superfish!

      Well thought you said you know programming and insist on not using jQuery stuff!
      Come on, you should be fair!

    • 09/19/10 4:42am

      Aleksander Steffensen says:

      Yes, I almost gave in, but I'm not going to. I'm sorry if I was being unfair, there's just so many proposals and so few of them actually is what I want. Looks like someone's finally getting there, though. Thanks for your efforts!

  • avatar
    Last edited:
    09/18/10
    10:43am
    Nilesh shiragave says:

    Hi

    Yes possible with some css and jquery.
    just send me design colors which you want i will create code using wp_nav_menu compatible with IE,mozilla,chrome,safari.

    Give me some time i will give you all the code..

    Thanks
    :)

    • 09/18/10 10:54am

      Aleksander Steffensen says:

      Thanks for your answer. I've decided to go for a non-css/jQuery solution if this is possible. :)

    • 09/18/10 10:58am

      Nilesh shiragave says:

      Yes but how you can show sub pages hide show without jquery or any javascript library or CSS. I have a code which works perfect using jquery and CSS.

    • 09/18/10 11:14am

      Nilesh shiragave says:

      In one answer you are saying you dont want CSS/jquery and in other answer you are looking to use jquery superfish code.

    • 09/18/10 11:17am

      Nilesh shiragave says:

      Final output will be similar to this..

      http://css-trends.com/demo/horizontal_menu/

    • 09/18/10 11:18am

      Aleksander Steffensen says:

      Not really. I said it might be an acceptable backup solution. I'm not looking to use jQuery superfish code.

    • 09/18/10 11:19am

      Aleksander Steffensen says:

      In the example you posted, the sub-menu disappears when trying to hover over the sub-menu items...

    • 09/18/10 11:28am

      Nilesh shiragave says:

      Sorry, yes you was right there was some CSS issues. as this is still not final code..

      Just clarify. you want to use wp_nav_menu() and in second div you want to show all the subpages added to the current page in menu or you want to display all the child pages for that current page.

      as you can display all the child pages of current page using wp_list_pages()

      just add this code in second div


      <?php
      wp_list_pages("title_li=&child_of=".$post->ID."&echo=0$sort_column=menu_order");
      ?>

    • 09/18/10 11:37am

      Aleksander Steffensen says:

      Thanks. I'm aware of this solution, but I want a wp_nav_menu-only solution, if you understand?

      The sub-menu (/second div) is supposed to show the sub pages / child pages of the current page.

  • avatar
    Last edited:
    09/18/10
    10:58am
    Pippin Williamson says:

    It seems as though Sushicodeur, over in the WordPress forms has already done this:

    http://wordpress.org/support/topic/wp_nav_menu-list-only-2nd-level-separate-submenu?replies=23

    His code might take a little bit of modification, which I'd be happy to help you with, but it's a really good start.

    • 09/18/10 11:03am

      Pippin Williamson says:

      Make sure you read all the way through that forum post as there are a lot of little tweaks throughout.

    • 09/18/10 11:09am

      Aleksander Steffensen says:

      Thank you.

      I've actually seen that thread in the WP forums, but like the PHP-novice I am, I did not know what to do with it.

      I feel like it would be unfair if I didn't give Mr. Chia a chance first, so I will definitely come back to you if it doesn't work out.

    • 09/18/10 11:11am

      Pippin Williamson says:

      Sounds great. Let me know and I'll work with you to get it all setup.

    • 09/18/10 12:35pm

      Aleksander Steffensen says:

      Hello again. I'd appreciate your help. Before we start, is anything vague, or do you understand exactly what I want?

    • 09/18/10 3:12pm

      Pippin Williamson says:

      I'm a little iffy on the exact structure you need. Could you outline it? Is the sub menu suppose to be inside of its own div within the main menu ul?

    • 09/18/10 3:21pm

      Aleksander Steffensen says:


      <div id="nav-container">
      <div class="main-menu">
      <ul class="horizontalnav primarynav strong">
      <li><a href="#">Hjem</a></li>
      <li><a href="#">Hytter</a></li>
      <li><a href="#">Bilder</a></li>
      <li><a href="#">Priser</a></li>
      <li><a href="#">Booking</a></li>
      <li><a href="#">Informasjon</a></li>
      <li><a href="#">Ofte stilte spørsmål</a></li>
      <li><a href="#">Kontakt</a></li>
      </ul>
      </div>

      <div class="sub-menu">
      <ul class="horizontalnav secondarynav">
      <li><a href="#">Panorama</a></li>
      <li><a href="#">Irenes</a></li>
      <li><a href="#">Kapteinens</a></li>
      </ul>
      </div>
      </div>


      Something like this is the ideal output :) Unlike the standard walker, which outputs everything (and uses CSS and/or jQuery to hide the other sub-pages), I want this to only output one sub-menu at a time. I hope that covers your questions.

    • 09/18/10 3:22pm

      Aleksander Steffensen says:

      So basically, in the code I just posted, the sub-menu div contains the sub-pages of the "Hytter"-page, which is linked to in the main menu.

    • 09/18/10 4:41pm

      Pippin Williamson says:

      I'm not really sure why you don't do it with CSS? I know you've said you don't want to, but there is no reason not to. I can give you a solution that is perfectly clean and works great.

    • 09/18/10 4:44pm

      Pippin Williamson says:

      The site that Ryan Riatno gave is done purely with CSS and the regular menu structure.

    • 09/18/10 4:54pm

      Aleksander Steffensen says:

      Well, I've tried for days to do it with CSS without getting it to work satisfactory in IE. I'd really prefer the custom walker solution.. I realise I'm being extremely picky, but the "job" description is pretty clear to me. And I'm not sure if I want to spend $70 on some CSS fix...

      How about this, if you manage to do it, if it looks good, and everything works like it's supposed to, you have me convinced.

    • 09/18/10 4:55pm

      Aleksander Steffensen says:

      Oh, and one more thing.. The sub-menu is not supposed to be shown when there is no sub pages. It needs to disappear, and the content will have to move upwards accordingly.

    • 09/18/10 5:19pm

      Pippin Williamson says:

      So unlike the WooTheme's link, you do not want the sub menu container present at all times. Correct?

    • 09/18/10 5:27pm

      Aleksander Steffensen says:

      That is correct :)

    • 09/18/10 6:03pm

      Pippin Williamson says:

      I've made everything work except the "move the content down", which I"m sure could be accomplished with jQuery, but I'm no jQuery guru;)

      Would you like the code or are you going with a different solution?

    • 09/18/10 7:38pm

      Aleksander Steffensen says:

      I appreciate your efforts, that goes for all of you.

      You're about as far as I got, except you got it looking good in IE... I still need the content to move according to the menu, or the title will be partly hidden. I can accept a CSS solution that works in all major browser, but I really want to stay away from jQuery on this website, for several reasons.

      Thanks for understanding, and let me know if you find a solution.

  • avatar
    Last edited:
    09/18/10
    11:35am
    Utkarsh Kukreti says:

    Add this code to functions.php

    function my_custom_nav($items) {
    global $wp_query;
    $queried_id = $wp_query->queried_object_id;
    $child_items = array();
    $parents = array();
    foreach( $items as $key => $item )
    {
    if( $item->object_id == $queried_id )
    $parents[] = $item->ID;
    if( in_array($item->menu_item_parent, $parents) )
    $child_items [] = $item;
    }
    return $child_items;

    }

    function enable_custom_nav() { add_filter('wp_get_nav_menu_items', 'my_custom_nav'); }
    function disable_custom_nav() { remove_filter('wp_get_nav_menu_items', 'my_custom_nav'); }



    This to your theme header

    				<?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'depth' => 1 ) ); ?>
    <br/>
    <?php enable_custom_nav() ?>
    <?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); ?>
    <?php disable_custom_nav() ?>


    It'll output one Top Level menu, and if a menu item is selected, all its child menu items in a separate div.

  • avatar
    Last edited:
    09/18/10
    11:42am
    Tobias Nyholm says:

    No problem. I can do it with some regex.

    Send me the theme source code and I can write a regex that works for you.

    • 09/18/10 11:47am

      Aleksander Steffensen says:

      Would you care to elaborate what your solution is all about? :)

    • 09/18/10 12:04pm

      Tobias Nyholm says:

      sure, sorry.

      I'll get the menu content from the wp_nav_menu. Then I "search" with regex to extract the submenu.
      Then I echo/return the menu with a wrapper and later the submenu with an other wrapper.

      As far as I know, you don't what the submenu to show when you hover a top menu item, right? You what the submenu to show when you are at a particular page?

      If not, I'm afraid that superfish or some other nasty jQuery/CSS is your solution...

    • 09/18/10 12:29pm

      Aleksander Steffensen says:

      Thank you.

      There's kind of a "line" of people waiting their turn to help, lol.. So I'd have to get back to you if the other "candidates" fail. :)

  • avatar
    Last edited:
    09/19/10
    7:36am
    Khanh Cao says:

    Not sure how are you going to deal with the CSS and jQuery but here is a quick and dirty walker to use with a 2-level menu:


    class My_Walker extends Walker_Nav_Menu {

    function walk( $elements, $max_depth) {

    $tops = array(); // top level menu items
    $subs = array(); // sub menu items

    foreach ($elements as $element) {
    if (0 == $element->menu_item_parent)
    $tops[] = $element;
    else
    $subs[] = $element;
    }

    // group sub items by their parents
    $real_subs = array();
    foreach ($subs as $item) {
    $real_subs[$item->menu_item_parent][] = $item;
    }

    // show top level elements
    $s = '<ul id="tops">';
    foreach ($tops as $item) {
    $classes = join(' ', $item->classes);
    $s .= "<li id='menu-{$item->db_id}' class='$classes'>{$item->title}</li>";
    }
    $s .= "</ul>";

    // show sub menu items
    foreach ($real_subs as $k => $items) {
    $s .= "<ul class='hidden menu-$k'>";
    foreach ($items as $item) {
    $classes = join(' ', $item->classes);
    $s .= "<li id='menu-{$item->db_id}' class='$classes'>{$item->title}</li>";
    }
    $s .= '</ul>';
    }

    return $s;
    }
    }


    The output is:


    <ul id="tops">
    <li id="menu-527" class=" menu-item menu-item-type-">Parent 1</li>
    <li id="menu-741" class=" menu-item menu-item-type-post_type">Parent 2</li>
    <li id="menu-742" class=" menu-item menu-item-type-post_type">Parent 3</li>
    <li id="menu-743" class=" menu-item menu-item-type-post_type">Parent 4</li>
    </ul>

    <ul class="hidden menu-527">
    <li id="menu-738" class=" menu-item menu-item-type-post_type">Child 1-1</li>
    <li id="menu-739" class=" menu-item menu-item-type-post_type">Child 1-2</li>
    <li id="menu-740" class=" menu-item menu-item-type-post_type">Child 1-3</li>
    </ul>

    <ul class="hidden menu-741">
    <li id="menu-786" class=" menu-item menu-item-type-post_type">Child 2-1</li>
    <li id="menu-791" class=" menu-item menu-item-type-post_type">Child 2-2</li>
    <li id="menu-793" class=" menu-item menu-item-type-post_type">Child 2-3</li>
    </ul>



    This gets the sub menu items of a top level item:

    var menu_id = $('#top li:first-child').id(); // first item's id
    var sub = $('.hidden').hasClass(id);


    But it's up to you to arrange the menu items, this only shows how create a simple walker.

    • 09/18/10 7:26pm

      Aleksander Steffensen says:

      Thanks.

      This is actually quite close. I would need it to output links, not only the names of the menu items... And it should only output the sub menu related to the currently active top-level page. Please note that I only want to list the sub-items that are added to the nav menu admin panel. Even if the parent page has sub-pages, I don't want them to show unless they are added as sub pages in the admin panel. This also means that if the current active menu item is a top level menu item with no sub-level items, the sub menu should not show at all.

      If you can manage to do this, I'd be happy to select you as winner.

      Just out of curiosity, when I look in the source when using this walker... The menu HTML is a total mess, but the WP standard actually looks quite good in the source when browsing. Don't take this the wrong way, it doesn't really mean that much, but.. Would have been nice if it was a bit more organised when looking at it in the source code. Quite a lot easier to do debugging...

    • 09/18/10 11:02pm

      Khanh Cao says:

      My bad, I thought you wanted to show all sub menu items and manipulate them with jQuery, here is a js-less version, it shows the top level menu items as a UL then another UL as the sub menu items of the current menu item:


      class My_Walker extends Walker_Nav_Menu {

      function walk( $elements, $max_depth) {

      global $wp_query;
      $current_page = (int) $wp_query->queried_object_id;

      $tops = array(); // top level menu items
      $subs = array(); // sub menu items
      _wp_menu_item_classes_by_context($elements);

      foreach ($elements as $element) {
      if (0 == $element->menu_item_parent) {
      $tops[] = $element;
      if ($element->object_id == $current_page)
      {
      $current_parent = $element;
      }
      }
      else
      $subs[] = $element;
      }

      if ($current_parent) {
      $real_subs = array();
      foreach ($subs as $item) {
      if ($item->menu_item_parent == $current_parent->db_id)
      $real_subs[] = $item;
      }
      }

      // show top level elements
      $s = '<ul id="tops">';
      foreach ($tops as $item) {
      $s .= $this->display_item($item, $current_page);
      }
      $s .= "</ul>";

      // show sub menu items
      if (sizeof($real_subs) > 0) {
      $s .= "<ul id='subs'>";
      foreach ($real_subs as $item) {
      $s .= $this->display_item($item, $current_page);
      }
      $s .= '</ul>';
      }
      return $s;
      }

      function display_item($item, $current_page) {
      $classes = join(' ', $item->classes);
      $item_url = strpos( $item->url, '#' ) ? substr( $item->url, 0, strpos( $menu_item->url, '#' ) ) : $item->url;
      if (!$item_url)
      $item_url = home_url();

      $link = "<a href='$item_url'>{$item->title}</a>";
      return "<li id='menu-{$item->db_id}' class='$classes'>$link</li>";
      }
      }

    • 09/19/10 4:55am

      Aleksander Steffensen says:

      Thank you! We're closing in on it now, this is very close. There's just a few small things.

      - When clicking on a sub-page, I want the sub-menu for the parent item to still show... It disappears now because the current item (sub-page item) does not have any sub-pages itself.

      - Does the links have all the flexibility they need to, according to what you can do in the nav menu admin panel? Like alt, target etc?

      - I don't know if you have seen the output, but there is being output one ul, in which the other two ul's are output. Like this:


      <ul id="primary-navigation" class="horizontalnav">
      <ul id="tops">
      <!-- MENU ITEMS -->
      </ul>
      <ul id="subs">
      <!-- SUBMENU ITEMS -->
      </ul>


      How do I get rid of the wrapping ul that Wordpress adds?

    • 09/19/10 7:20am

      Khanh Cao says:

      This one should include menu attributes from the menu editor and show the sub menu items when a sub menu item is the current page. I don't know any good way to remove the default UL tag so I think it's best to either make the two menus into DIVs or wrap each of them with a LI:



      class My_Walker extends Walker_Nav_Menu {

      function walk( $elements, $max_depth) {

      global $wp_query;
      $current_page = (int) $wp_query->queried_object_id;

      $tops = array(); // top level menu items
      $subs = array(); // sub menu items
      _wp_menu_item_classes_by_context($elements);

      foreach ($elements as $element) {
      if (0 == $element->menu_item_parent) {
      $tops[] = $element;
      if ($element->object_id == $current_page) {
      $current_parent = $element;
      }
      }
      else
      {
      $subs[] = $element;
      if ($element->object_id == $current_page) {
      $current_child = $element;
      }
      }
      }

      if (!$current_parent)
      $current_parent = $this->get_current_parent_from_sub($elements, $current_child);

      if ($current_parent) {
      $real_subs = array();
      foreach ($subs as $item) {
      if ($item->menu_item_parent == $current_parent->db_id)
      $real_subs[] = $item;
      }
      }

      // show top level elements
      $s = '<li><ul id="tops">';
      foreach ($tops as $item) {
      $s .= $this->display_item($item);
      }
      $s .= "</ul></li>";

      // show sub menu items
      if (sizeof($real_subs) > 0) {
      $s .= "<li><ul id='subs'>";
      foreach ($real_subs as $item) {
      $s .= $this->display_item($item);
      }
      $s .= '</ul></li>';
      }
      return $s;
      }

      // get the parent page when a sub page is the current page
      function get_current_parent_from_sub($elements, $current_child) {
      foreach ($elements as $element) {
      if ($element->db_id == $current_child->menu_item_parent) {
      return $element;
      }
      }
      return false;
      }

      function display_item($item) {
      $i = '';
      $this->start_el( $i, $item, 0, array() );
      $this->end_el( $i, $item, 0, array() );
      return $i;
      }


    • 09/19/10 7:30am

      Aleksander Steffensen says:

      Could you check the code once more? I get this syntax error:


      Parse error: syntax error, unexpected ';', expecting T_FUNCTION in /home/stmm/www-0012/wp-content/themes/koloyshytteutleie/functions.php on line 137


      Line 137 is the last line, and contains "?>"

    • 09/19/10 7:34am

      Aleksander Steffensen says:

      Nevermind. It was just missing a } closing the class at the end. Thanks you so much, it works fantastic! :)

  • avatar
    Last edited:
    09/18/10
    12:39pm
    Ryan Riatno says:

    The output should be like this http://www.woothemes.com/demo/?name=crisp ?

    Previous versions of this answer: 09/18/10 at 12:39pm

    • 09/18/10 1:02pm

      Aleksander Steffensen says:

      Yes - without the jQuery-thingy :) How is this made? CSS/jQuery only, or via a custom walker?

    • 09/18/10 10:43pm

      Ryan Riatno says:

      Well, unfortunately this is only use the simple wp_nav_menu and jQuery.
      Here's the code:
      Functions:

      if ( function_exists('wp_nav_menu') ) {
      add_theme_support( 'nav-menus' );
      register_nav_menus( array( 'primary-menu' => __( 'Primary Menu' ) ) );
      }

      The Output:
      wp_nav_menu( array( 'depth' => 6, 'sort_column' => 'menu_order', 'container' => 'ul', 'menu_id' => 'main-nav', 'menu_class' => 'nav fl', 'theme_location' => 'primary-menu' ) );

      jQuery :

      jQuery(document).ready(function(){

      //NAVIGATION - Keep parent item highlighted while hovering dropdown

      jQuery('.nav li ul').mouseover(function(){

      if(! jQuery(this).parent().hasClass('fake')){
      jQuery(this).parent().addClass('fake');
      }

      });
      jQuery('.nav li ul').mouseleave(function(){

      if(jQuery(this).parent().hasClass('fake')){
      jQuery(this).parent().removeClass('fake');
      }
      });

      //NAVIGATION - Display second level menu for current page

      jQuery('.nav > li.current_page_item > ul, .nav > li.current_page_ancestor > ul').css('left', '75px');

      jQuery('.nav > li:not(.current_page_item,.current_page_ancestor)').mouseover(function(){
      //alert('what');
      jQuery('.nav > li.current_page_item > ul, .nav > li.current_page_ancestor > ul').css('left', '-9999px');
      });


      jQuery('.nav > li:not(.current_page_item,.current_page_ancestor)').mouseout(function(){
      //alert('what');
      jQuery('.nav > li.current_page_item > ul, .nav > li.current_page_ancestor > ul').css('left', '75px');
      });

      //NAVIGATION - Sub-nav indicator

      jQuery('.nav > li > ul').each(function(){

      jQuery(this).parent('li').addClass('has-dropdown');

      });

      jQuery('.nav > li > ul > li > ul').each(function(){

      jQuery(this).parent('li').addClass('has-sub-dropdown');

      });

      });


      I know it's not what you want to achieve, but at least you don't need the complex custom walker to make this thing work :)

  • avatar
    Last edited:
    09/18/10
    10:09pm
    Duncan O'Neill says:

    Why not just make your current theme a child theme of the default Twenty-Ten theme? Then you have all the functionality you need already built in for the multi-tiered menu.

    Creating a child theme is fairly easy;

    http://codex.wordpress.org/Child_Themes

    You should be able to make some simple alterations to your current styles.css to call in Twenty-Ten as the default theme, and over-ride Twenty-Ten's css with your own.

    Then it's just a matter of adding some css rules to show the current menu item's children, rather than hide them and show them on hover;

    For example, this in your style.css will show the current menu item's children;

    #access ul li.current_page_item ul {
    display:block;
    }

    Then it's just a matter of stopping the hover over other menu items showing their child lists. This should be fairly easily achieved, using either css, or by turning off the relevant javascript.

    Let me know if you want to further explore this route.

    regards,

    Duncan

This question has expired.





Current status of this question: Completed



Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.