This has been very difficult to track and I have enabled only the plugins I need (ACF and my own plugins that deal with content type creation).

I noticed that on some pages, my menus were gone, this are menus loaded from header.php so it's the same code.

I do modify the main query, by hooking onto pre_get_posts. For instance, when a post type is of a certain type, I modify the main query like so:

else if ( is_post_type_archive( 'people' ) ) {
    $query->set( 'orderby', 'meta_value' );
    // Bug: Line below causes the menu not to show.
    $query->set( 'meta_key', 'display_order' );
    $query->set( 'order', 'ASC' );

As the comment suggests, this line is the one that causes the whole menu to disappear:

    // Bug: Line below causes the menu not to show.
    $query->set( 'meta_key', 'display_order' );

I then went over to my wp_nav_menu invocation and drilled onto it with the debugger. It came down to post.php in these two line (around line number 1960 as of 25 Apr 2019) :

$get_posts = new WP_Query;
return $get_posts->query( $r );

When I enable the line that causes the bug, $get_posts->query( $r ); brings nothing back, when I disable it, it brings the menus back.

I compared the contents if $get_posts in its creation and of $r when bug is present and when bug is not present and the contents are exactly the same, which baffles the hell out of me.

This must be a global variable that is dirty b/c of my code and it messes up the query, so I'm probably missing a wp_reset_query() somewhere but I cannot figure where.

Any pointers would be greatly appreciated.

For reference, here are the output I mention of the variables:

Working Output

Bug Output


The reason for that is pretty straight forward...

In you code (at least in the part you’ve showed) the only condition you check is:

if ( is_post_type_archive( 'people' ) )

So when you’re on archive for people, this condition will be true for every WP_Query on that page.

Let’s say you have some “Latest news” section in the footer and they’re retrieved with WP_Query. pre_get_post filter will get run for such WP_Query too and the condition above will be still true.

And menu is another example, because it’s also retrieved using WP_Query...

That’s why it’s important to check if $query->is_main_query() also, if you want to modify only the main query.

So your code should look something like this:

else if ( $query->is_main_query() && is_post_type_archive( 'people' ) ) {
    $query->set( 'orderby', 'meta_value' );
// Bug: Line below causes the menu not to show.
    $query->set( 'meta_key', 'display_order' );
    $query->set( 'order', 'ASC' );

PS. Of course there is possibility that the same should be applied for other parts of that if statement, so the structure of that if may get changed...

| improve this answer | |
  • Thanks for the response. I thought of that and tried it as soon as I posted my question but the menu keeps disappearing even when I use $query->is_main_query(). In case you'd like to see my entire query code, it's here-> link.scorpiotek.com/p5y – csaborio Apr 25 '19 at 4:46
  • 1
    You were absolutely right, not sure what I was testing when I wrote the code, thanks! – csaborio May 3 '19 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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