1

I am modifying the query for custom archive pages. I am using the pre_get_posts action. I need to catch some GET variables to modify my query. It is working great on the archive page for one custom post type but not the rest. It is breaking my navigation menus.

add_action( 'pre_get_posts', 'search_provider');
function search_provider($query){
if(is_post_type_archive(array('provider'))){
   $query->set( 'posts_per_page', -1 );
   $query->set( 'orderby', 'title' );
    $query->set( 'order', 'ASC' );
    if(isset($_GET['providersearch']) && $_GET['providersearch'] == 'Y'){
        if(!empty($_GET['s']))
        $query->set( 's', $_GET['s'] );
    } else {
        $query->set ('exclude', array(10054, 10068));
    }
  }
}

Do I need to clear the query variables after the content is returned?

3

pre_get_posts runs for every query. That includes the main query, secondary queries, and menus. The problem is that is_post_type_archive(array('provider')) is checking if the main query is the post type archive, not a specific query going through pre_get_posts.

So when you check for that and then modify the current query going through pre_get_posts you're going to modify all queries based on a condition of the main query.

To do what you want properly you need to check each query in pre_get_posts to check that the particular query that is being passed to the action callback is for the post type archive. In other words the same query that you are setting the arguments on with $query->set().

You can do that by using the $query->is_post_type_archive() method.

add_action( 'pre_get_posts', 'search_provider'); 
function search_provider( $query ) {
    if ( $query->is_post_type_archive( array( 'provider' ) ) ) {
        $query->set( 'posts_per_page', -1 );
        $query->set( 'orderby', 'title' );
        $query->set( 'order', 'ASC' );

        if ( isset( $_GET['providersearch'] ) && $_GET['providersearch'] == 'Y' ) {
            if ( ! empty( $_GET['s'] ) ) {
                $query->set( 's', $_GET['s'] );
            }
        } else {
            $query->set( 'exclude', array( 10054, 10068 ) );
        }
    }
}

Now $query->set() will only set values if that specific query is a post type archive.

  • 1
    It's worth noting that using the above method also applied to admin screens. If this is undesirable, then the following can be used: if ( $query->is_post_type_archive( array( 'post_type' ) ) && !is_admin() ) { – user319940 Jul 30 '18 at 10:30

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.