WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So I've searched the net and attempted to code a custom walker class that will do this, but I'm new to WordPress and although similar questions exist none fit exactly what I'm looking for, or suggest CSS, jQuery or a plugin as a solution (which is not really ideal).

I currently have the following code:

class description_walker extends Walker_Nav_Menu
      function start_el(&$output, $item, $depth, $args)
           global $wp_query;
           $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

           $class_names = $value = '';

           $classes = empty( $item->classes ) ? array() : (array) $item->classes;

           $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
           $class_names = ' class="'. esc_attr( $class_names ) . '"';       

           $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';     

           $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
           $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
           $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
           $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

           $prepend = '<em>';
           $append = '</em>';
           $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';

           if($depth != 0)
                     $description = $append = $prepend = "";

            $item_output = $args->before;
            $item_output .= '<a'. $attributes .'>';
            $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
            $item_output .= $description.$args->link_after;
            $item_output .= '</a>';
            $item_output .= $args->after;            

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );


What I'm trying to do is have it so that only the children (sub-menus) of the active navigation are shown, including all of the first level parent items.

For example if you visit http://windows.microsoft.com/en-us/windows/home the "Download & Shop" link has no sub menu options, but once you navigate to that page, a sub-menu is present.

Any help would be greatly appreciated!

Many Thanks

share|improve this question
I am trying to understand your question. Do you mean only when someone clicks on page three and thereby making it "active" is when you want to show the sub-menu for page 3 parent? – user23654 Sep 3 '13 at 18:48
Yes, or if anyone were to view any sub-page of page 3 the submenu and parent would still need to be present. For example if you visit windows.microsoft.com/en-us/windows/home the "Download & Shop" link has no sub menu options, but once you navigate to that page, a sub-menu is present – Mac Sep 3 '13 at 18:51
Not sure how you mean but perhaps wordpress.org/plugins/codepress-menu – BoBoz Sep 3 '13 at 19:12
or wordpress.org/plugins/nice-navigation – BoBoz Sep 3 '13 at 19:12
Thanks for the links but they don't really do what I'm looking for. I've edited my question so hopefully it's now clearer. – Mac Sep 3 '13 at 19:30

Ok based on what I think you want from your description, you can accomplish this via CSS. You don't need to create a custom walker for this unless you have other reasons to do so.

If you look carefully, when a menu item is active it will apply the following CSS to the "li" element


So with that information, you can write your CSS rule to show/hide the sub-menus for that "li" item.

For example:

li > ul {

li.current-menu-item > ul, li.current-menu-ancestor > ul {
share|improve this answer

This can be done easily with CSS. Follow the next steps:

1- Add this code into the tag BODY:

<?php body_class(); ?>

Like this:

<body <?php body_class(); ?>>

*This step will add a class to the current page. (It is usually used when we want to leave a button as marked when we are in its page).

2- Wordpress generates a dinamic code for the menus, which has its own classes. With this code we can access to the classes for the current page:

.menu li.current_page_item
.menu li.current-menu-item

3- So we can use something like this:

.menu li ul{opacity:0;visibility:hidden}
.menu li.current_page_item > ul, .menu li.current-menu-item > ul {display:block;opacity:1;visibility:visible}

Tested :)

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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