1
votes

I just updated a menu on a site of mine to utilize wp_nav_menu. Setting this up with WP was fairly straight forward however I've run into one small snag with the the way wordpress is outputting its parent/ancestor classes for use in highlighting the current page that the content belongs to, particularly with single post pages...

Highlighting the current page with .current_page_item a and .current_page_parent a works perfect as long as its just on a normal page with children, however as soon as you visit a post from events or media, the blog link in the menu is highlighted instead which is incorrect obviously.

*One thing noticeably wrong when looking at Wordpress' output is that the current page classes are not even being generated on the correct li tag that the post belongs to which seems to be the root of the problem.

For future reference, the Events, Media, & Blog pages all use a special query I've written to only grab the respective category for that page, ie.

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts("category_name=media&paged=$paged");

if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div class="post">
</div>
<?php
endwhile;
else:
endif;

Hope thats enough info, if not let me know. Best, SB


EDIT - August 3, 2011


Below is a screen shot of what Im referring to when I say that wp_nav_menu is generating the current classes on the wrong li tag. Highlighted in Blue is the menu item that the post actually belongs to. Hightlighted in Grey is the incorrect li tag that wordpress has decided to add the current classes to instead.

Examplehttp://img688.imageshack.us/img688/4180/picture2zo.png



EDIT - August 4, 2011


Maybe this will help demonstrate how I have the menu setup thus far a little better w/ Hadvig's assistance?

In my functions.php template I have -

<?php
// Add Custom Menu Support
if ( function_exists( 'register_nav_menu' ) ) {
    register_nav_menu( 'epr_menu', 'EPR Main Menu' );
}

function my_menu_items_hook($items, $menu, $args) {

  if ( 'epr_menu' == $menu->slug ) { // check if it is process your top menu
    if ( is_single() ) { // check if single post loaded

      if ( in_category('events') || in_category('media') ) {
        foreach ( $items as $key => $value ) {
          if ( 'blog' == $value->ID ) {
            $items[$key]->classes[] = array(); //unset classes for blog item
          }

          // add class if post from event category
          if ( in_category('events') && 'events' == $value->ID ) {
            $items[$key]->classes[] = 'current-menu-item';
          }

          // add class if post from media category
          if ( in_category('media') && 'media' == $value->ID ) {
            $items[$key]->classes[] = 'current-menu-item';
          }
        }
      }
    }
  }

  return $items;
}

add_action('wp_get_nav_menu_items', 'my_menu_items_hook', 10, 3);
?>

In my header.php template I'm calling the menu like so -

<div id="nav_wrapper">
    <ul id="nav">
        <?php wp_nav_menu( array( 'container' => '', 'items_wrap' => '%3$s' ) ); ?>
    </ul>
</div>

1
Do you have Events, Media and Blog categories?hadvig
Yes, each page shows 1 category via a custom query exactly like the one displayed above...and in settings > reading > I have front page set to Events, and posts page set to Blog. Everything works as expected except wp_nav_menu is incorrectly generating current classes on the wrong li tags when visiting a single post from either media or events. Ill upload a screenshot from firebug to demonstrate what I mean and place it in my original post.Mr.Brown

1 Answers

0
votes

I suppose problem because you set post page as Blog and wordpress set it as parent(in your menu) for all post. You can try to change this behaviour with wp_get_nav_menu_items hook. Example:

function my_menu_items_hook($items, $menu, $args) {

  if ( 'my-menu-slug' == $menu->slug ) { // check if it is process your top menu
    if ( is_single() ) { // check if single post loaded

      if ( in_category(EVENT_CATEGORY_ID) || in_category(MEDIA_CATEGORY_ID) ) {
        foreach ( $items as $key => $value ) {
          if ( BLOG_PAGE_ID == $value->object_id ) {
            $items[$key]->classes[] = array(); //unset classes for blog item
          }

          // add class if post from event category
          if ( in_category(EVENT_CATEGORY_ID) && EVENT_PAGE_ID == $value->object_id ) {
            $items[$key]->classes[] = 'current-menu-item';
          }

          // add class if post from media category
          if ( in_category(MEDIA_CATEGORY_ID) && MEDIA_PAGE_ID == $value->object_id ) {
            $items[$key]->classes[] = 'current-menu-item';
          }
        }
      }
    }
  }

  return $items;
}

add_action('wp_get_nav_menu_items', 'my_menu_items_hook', 10, 3);

You should replace EVENT_CATEGORY_ID and MEDIA_CATEGORY_ID with your category ids(or names). Also replace EVENT_PAGE_ID and MEDIA_PAGE_ID with your page ids. Replace 'my-menu-slug' with your menu slug.

Of course this would work only if you attach post to only one category from Events, Media or Blog.

Updated.