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');

2 Answers 2


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

  • 1
    That's exactly what I was looking for. Three days of searching and I never once came across that function. Thanks a million! Commented May 17, 2012 at 11:35

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

Your Answer

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

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