0

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

5
  • 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, 2013 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
    – Ross
    Sep 3, 2013 at 18:51
  • Not sure how you mean but perhaps wordpress.org/plugins/codepress-menu
    – BoBoz
    Sep 3, 2013 at 19:12
  • or wordpress.org/plugins/nice-navigation
    – BoBoz
    Sep 3, 2013 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.
    – Ross
    Sep 3, 2013 at 19:30

2 Answers 2

1

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

current-menu-item
current-menu-ancestor

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

For example:

li > ul {
     display:none;
}

li.current-menu-item > ul, li.current-menu-ancestor > ul {
     display:block;
}
1

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 :)

Your Answer

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

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