WordPress Menu Disappears when $query->query_vars is set

I’ve set some meta variables on my WP posts. I want to be able to sort by these variables, and everything is working great except when I sort by either “views” or “likes”. When I sort by either of those two fields, WP doesn’t generate my nav (wp_nav_menu).

I’ve tried “resetting” the $wp_query variable surrounding my wp_nav_menu call:

$old_query = $wp_query; 
$wp_query = new WP_Query( array('post_type' => 'any') ); 
wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); 
$wp_query = $old_query;

But that does not solve it. The only thing that does work is commenting out the line starting $query->query_vars[‘meta_key’], but obviously that negates the sort as well.

Any help would be appreciated.

// Before a query is run, modify the sort order
function jh_popularity_sort_query($query) {
  $sort = $_GET['sort']; 
  if ($sort == "title") {
    $query->query_vars['orderby'] = 'title';
    $query->query_vars['order'] = 'ASC';
  } else if ($sort == "date") {
    $query->query_vars['orderby'] = 'date';
  } else if ($sort == "views") {
    $query->query_vars['meta_key'] = 'jh_page_views';
    $query->query_vars['orderby'] = 'meta_value';
    $query->query_vars['order'] = 'DESC';
  } else if ($sort == "likes") {
    $query->query_vars['meta_key'] = 'jh_page_likes';
    $query->query_vars['orderby'] = 'meta_value';
    $query->query_vars['order'] = 'DESC';
  }

  return $query;
} add_action('pre_get_posts', 'jh_popularity_sort_query');

Solutions Collecting From Web of "WordPress Menu Disappears when $query->query_vars is set"

Nav menus are also generated by a WP_Query, so in your pre_get_posts callback function you need to check if the $query you’re altering is the main query. The easiest way to do this would probably be to do this right at the beginning of the function:

if ( ! $query->is_main_query() )
    return $query;

Also note that in your jh_popularity_sort_query() callback function, you should probably use the set() method instead, e.g. $query->set( 'orderby', 'date' ). The method does exactly what you’re doing above with changing the $query_vars array, but it’ll keep you safer going forward. I think it also makes for slightly prettier code 🙂

Try this code:

function fix_missing_menu( $query ) {
        $query->set( 'post_type', array(
       'post', 'nav_menu_item'
           ));
} 
add_filter( 'pre_get_posts', 'fix_missing_menu' );

Put that in functions.php, see if it works.

nav_menu_item is also a custom post type in wordpress