Remove the Homepage Query

The posts_request filter

Skimming through the WP_Query we find this part of interest:

if ( !$q['suppress_filters'] ) {
    /**
     * Filter the completed SQL query before sending.
     *
     * @since 2.0.0
     *
     * @param array    $request The complete SQL query.
     * @param WP_Query &$this   The WP_Query instance (passed by reference).
     */
      $this->request = apply_filters_ref_array( 'posts_request', 
          array( $this->request, &$this ) );
   }

   if ( 'ids' == $q['fields'] ) {
       $this->posts = $wpdb->get_col( $this->request );
       $this->posts = array_map( 'intval', $this->posts );
       $this->post_count = count( $this->posts );
       $this->set_found_posts( $q, $limits );
       return $this->posts;
   }

We might try to eliminate the main home request through the posts_request filter. Here’s an example:

add_filter( 'posts_request', function( $request, \WP_Query $q )
{
    // Target main home query
    if ( $q->is_home() && $q->is_main_query() )
    {
        // Our early exit
        $q->set( 'fields', 'ids' );

        // No request
        $request="";
    }

    return $request;    

}, PHP_INT_MAX, 2 );

where we force the 'fields' => 'ids' for early exit.

The posts_pre_query filter (WP 4.6+)

We could also use the new posts_pre_querysrc filter available in WordPress 4.6+

add_filter( 'posts_pre_query', function( $posts, \WP_Query $q )
{
    if( $q->is_home() && $q->is_main_query() )
    {
        $posts = [];
        $q->found_posts = 0;
    }
    return $posts;
}, 10, 2 );

This filter makes it possible to skip the usual database queries to implement a custom posts injection instead.

I just tested this and noticed that this will not prevent sticky posts, opposite to the posts_request approach.

Check out the ticket #36687 for more info and the example there by @boonebgorges.

Leave a Comment