3

I have a wp_nav_menu "Main Menu" such as the following:

  • Top Level (#menu-item-1)
    • Sub Item
    • Sub Item
  • Top Level (#menu-item-2)
    • Sub Item
  • Top Level (#menu-item-3)
    • Sub Item A
    • Sub Item B
      • Sub Item a.1
    • Sub Item C

Then in my template I want to be able to echo wp_nav_menu Main Menu sub items for say top level with id of menu-item-3 where menu-item-3 is the current menu top item.

So something like this: (but that would actually work of course)

wp_nav_menu( array('menu' => 'Main Menu' 'menu-item-id' => '3' ));

And that would return:

  • Sub Item A
  • Sub Item B
    • Sub Item a.1
  • Sub Item C

If it matters this is so I can show the sub items as side menu interior based on which main menu item section your in dynamically. Thanks in advance!

To note, this is not a duplicate of, "http://wordpress.stackexchange.com/questions/2802/display-a-portion-branch-of-the-menu-tree-using-wp-nav-menu". Though that page has several similar answers, none work as expected with the current version of WordPress. That is showing on particular submenu item and all of its, children, their children and so on (unlimited depth).

5
  • 1
    possible duplicate of Display a portion/ branch of the menu tree using wp_nav_menu()
    – Jan Fabry
    Commented May 18, 2011 at 6:17
  • I think you can solve this question by reading the answer to this question. If you can't solve it after reading that question, please edit your question to clarify what you tried and what did not work. (Use @Jan when you reply in a comment and I get a notification)
    – Jan Fabry
    Commented May 18, 2011 at 6:19
  • This looks perfect! I'll be trying it out this morning as I read through those comments and see if it works. Thanks Jan! Commented May 18, 2011 at 12:48
  • So unfortunately, after trying out those options on that link, I have not found a workable solution. The first walker class simply outputs all the menu items, meaning it does not work. The third one in the list appeared to work, but it shows the top menu item, and only goes one depth down, where is I need all depths. Tried the plugin option, but does not work either, just shows all the menu items. The next one answered by Alp, shows the side menu, and no top level which is great, but does show their children. And the last one on the page does not work at all. Suggestions? Commented May 18, 2011 at 14:26
  • @heavymark, did you ever find a solution to this?
    – Ian Dunn
    Commented Jul 9, 2011 at 16:19

3 Answers 3

3

If I understand what you want correctly, you can do this with CSS. You'll call wp_nav_menu normally and let it generate all of the links, but then you'll hide all of them except for the submenu of the current page.

You're CSS would look something like this,

#sidebar ul.menu li
{
    display: none;
}

    #sidebar ul.menu li.current-page-parent,
    #sidebar ul.menu li.current-page-parent ul,
    #sidebar ul.menu li.current-page-parent ul.li
    {
        display: block;
    }

Update: You can check out http://thataboycreative.com to see an example of where I've used this before. Here's the relevant CSS from that example:

ul.sub-menu
{
    display: none;
}

    #menu-main-navigation > li.current-menu-item ul.sub-menu,
    #menu-main-navigation > li.current-menu-ancestor ul.sub-menu
    {
        display: block;
    }
6
  • @Ian This does not work. I haven't seen, "current-page-parent" used before. I believe WP generates, "current-menu-item", and "current_page_item". But even using those it does not appear to work and simply hides the entire menu. I have you done it this was successfully on a site before you could reference? Commented May 18, 2011 at 14:40
  • current-page-parent also exists, but it may only be in some versions. WP hasn't been very consistent w/ class naming. I'll edit the answer to show an example of where I've done it before.
    – Ian Dunn
    Commented May 18, 2011 at 15:40
  • I will try your new css code to see if it will work as a temporary option until I determine a way to do it in the code. Since with CSS way, the page would still need to load all the menu items, increasing load time and resources, and simply hiding it. But do to a time crunch, certainly an option to consider. Thank you. Commented May 18, 2011 at 21:24
  • Actually, I don't think it would, because Wordpress caches database reads. So, if you've already called wp_nav_menu() once for your primary menu, calling it a second time for your secondary nav won't result in a second database query.
    – Ian Dunn
    Commented May 19, 2011 at 0:13
  • @Ian, that is a good point if that's how presumably works. Commented May 20, 2011 at 15:08
3

I created a plugin for this - make sure to pass the ID in as a STRING and not an Integer. Please rate my plugin - it is my first one! :)

Download Here

1
  • 2
    The prefix for your custom function is wp_? That will break one day.
    – fuxia
    Commented Nov 2, 2012 at 20:54
2

Another way I've done this is grabbing the posts directly, instead of using wp_nav_menu. This is based on the actual page structure, though, not the menu.

functions.php:

function __construct()
{
    $this->currentPageID    = $this->getCurrentPageID();
    $this->sectionChildren    = $this->getSectionChildren();
}

function getCurrentPageID()
{
    $currentPage = $_SERVER['REQUEST_URI'];

    if($currentPage == '/')
        $currentPage = '/home';
    $currentPage = get_page_by_path($currentPage);

    if($currentPage)
        return $currentPage->ID;
    else
        return -1;
}

function getSectionID()
{
    global $wpdb;

    $currentSectionID = $wpdb->get_var("
        SELECT post_parent
        FROM ". $wpdb->posts ."
        WHERE ID = ". $this->currentPageID
    );

    if($currentSectionID == 0)
        return $this->currentPageID;
    else
        return $currentSectionID;
}

function getSectionChildren()
{
    global $wpdb;

    $children = $wpdb->get_results("
        SELECT ID, post_title
        FROM ". $wpdb->posts ."
        WHERE
            post_parent = ". $this->getSectionID() ." AND
            post_type = 'page' AND
            post_status = 'publish'
    ", ARRAY_A);

    return $children;
}

sidebar.php:

<ul id="sub-navigation">
    <?php foreach($dc->sectionChildren as $c) : ?>
        <li <?php if($dc->currentPageID == $c['ID']) echo 'class="active"'; ?>><a href="<?php echo get_permalink($c['ID']); ?>"><?php echo $c['post_title']; ?></a></li>
    <?php endforeach; ?>
</ul>
1
  • I initially had it setup using pages, which only took a few lines of code from WordPress's site however when on a sub sub page, it showed the sub sub menu, rather than the first sub level and its descendents. Also when the user updates the main menu, it wouldn't reflect in the interior side menu if using the page structure way, which is why I choose the menu way. But thank you. Commented May 18, 2011 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.