WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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');
share|improve this question
up vote 7 down vote accepted

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

share|improve this answer
That's exactly what I was looking for. Three days of searching and I never once came across that function. Thanks a million! – Josh Hudnall May 17 '12 at 11:35
You girl are my hero, thanks a lot! – jepser Aug 12 '13 at 16:57

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

share|improve this answer

Your Answer


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.