Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.


I'm using the function wp_nav_menu like this:

<?php wp_nav_menu( array( 
                         'container' => false,
                         'echo' => true,
                         'before' => '',
                         'after' => '',
                         'link_before' => '',
                         'link_after' => '',
                         'depth' => 0,
                         'walker' => new my_walker())
                         ); ?>



class my_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 class="menu-item-'. $item->ID . '"' . $value . '>';

           $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 = '<div>';
           $append = '</div>';
           $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 .= '<p>'.$args->link_before .apply_filters( 'the_title', $item->title, $item->ID );
            $item_output .= $description.$args->link_after.'</p>';
            $item_output .= $prepend;
            $item_output .= $append;
            $item_output .= '</a>';
            $item_output .= $args->after;

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

But in this menu the class current_page_item is missing. Is there something wrong in my code? How can I add this class?
Thanks!

share|improve this question
    
So, you have the current_page_item class if you use the default walker? –  s_ha_dum Apr 23 at 14:14
    
No, the opposite. –  DamianFox Apr 23 at 20:02

1 Answer 1

If you're not actually using a custom nav menu, why are you not just outputting wp_page_menu() directly?

Problem

As-implemented, your walker will never be executed (or, more accurately, you can't control whether or not it is executed), because you're not passing 'theme_location' (correct usage) or 'menu' (sub-optimal usage) to the args array.

Here's how the wp_nav_menu() output works:

  1. WordPress looks for 'menu' defined in the args array. This value corresponds to the slug of a user-created custom nav menu. So if the user creates a Menu named "Short Header Menu", the slug would be 'short-header-menu', which would correspond to 'menu' => 'short-header'menu'. If the menu is found, it is used.
  2. WordPress looks for 'theme_location' defined in the args array. This value corresponds to the user-defined custom nav menu assigned by the user to the Theme Location. So, if the user creates a Menu named "Short Header Menu", and assigns it to the (Theme-defined) Theme Location "Primary Menu" (defined by the Theme via register_nav_menus( array( 'primary-menu' => "Primary Menu 0 0), the 'short-header-menu' would be the menu returned. If found, it is used.
  3. If neither 'menu' nor 'theme_location' is defined the args array, WordPress queries all of the user-created custom nav menus. If the user has created custom nav menus, WordPress uses the first one that has menu items.
  4. If all of the above fail, WordPress outputs the fallback menu, as defined via 'fallback_cb'.

So, in your example, you're not passing either 'menu' or 'theme_location' to the args array. If the user (e.g. you) hasn't created any custom nav menus, then WordPress is outputting the 'fallback_cb', which by definition is wp_page_menu().

Now, wp_nav_menu() passes its $args array to the fallback function, but wp_page_menu() doesn't accept a 'walker' parameter. So your custom walker is being ignored.

Solution

  1. Properly register custom nav menu Theme locations, via register_nav_menus()
  2. Create custom nav menus, via Appearance -> Menus
  3. Assign a custom nav menu to a registered Theme Location
  4. Pass the 'theme_location' parameter to your wp_nav_menu() $args array

Addendum

Note, if the sole purpose of your custom walker is to add the .current-page-item class, then you don't need your custom walker at all. The wp_nav_menu() classes are backwards-compatible with wp_page_menu(), which means that the .current-page-item class is already output by wp_nav_menu().

share|improve this answer
    
Thus the Walker class is wrong? –  DamianFox Apr 24 at 9:47
    
More accurately, the Walker class is irrelevant. –  Chip Bennett Apr 24 at 11:38
    
But I need this class, because it allows me to customize the menu. Anyway, before adding that class the menu worked perfectly, namely the css class current_page_item were present. –  DamianFox Apr 25 at 8:57
    
"But I need this class" - wp_nav_menu(), by default, outputs the .current-page-item class. You don't need a Walker to add it. –  Chip Bennett Apr 25 at 10:31
    
I used the Walker class because I had to modify the menu, namely I added a div in every li tag.. –  DamianFox Apr 25 at 11:25

Your Answer

 
discard

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.