Eliminar la consulta de la página de inicio

8

Tengo una página de inicio que muestra la plantilla home.php , que contiene 2 barras laterales con widgets.

La consulta principal aún incluye las 10 publicaciones estándar, pero como no las estoy mostrando, me gustaría eliminar la consulta realizada en la base de datos por completo. Si es necesario, un bucle de publicación vacío funcionará ya que no estoy utilizando el bucle principal en mi plantilla home.php .

¿Cómo haría esto? Podría usar pre_get_posts para minimizar y reducir la consulta, pero eso me deja con una consulta muy rápida, ¿cómo puedo eliminarla por completo?

    
pregunta Tom J Nowell 09.05.2016 - 15:03

3 respuestas

7

El filtro posts_request

Hojeando el WP_Query encontramos esta parte de interés:

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;
   }

Podríamos intentar eliminar la solicitud de inicio principal a través del filtro posts_request . Aquí hay un ejemplo:

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

donde forzamos el 'fields' => 'ids' para salir temprano.

El filtro posts_pre_query (WP 4.6+)

También podríamos usar el nuevo posts_pre_query disponible en 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 );

Este filtro permite omitir las consultas habituales de la base de datos para implementar una inyección de publicaciones personalizada en su lugar.

Acabo de probar esto y me di cuenta de que esto no evitará las publicaciones pegajosas, al contrario del enfoque posts_request .

Consulte el boleto # 36687 para obtener más información y example there por @boonebgorges.

    
respondido por el birgire 09.05.2016 - 17:24
2

Aquí hay un buen truco que aprendí de @birgire, podemos detener la consulta principal agregando AND where 0=1 a la cláusula WHERE de la consulta SQL. Esto todavía puede resultar en una consulta de db, pero seguramente detendrá la consulta principal de las publicaciones

add_filter( 'posts_where', function ( $where, \WP_Query $q )
{
    if (    $q->is_home()
         && $q->is_main_query()
    ) {
        $where .= ' AND where 0 = 1';
    }

    return $where;
}, 10, 2 ); 

También puedes intentar reemplazar la cláusula WHERE con where 0 = 1

$where = ' where 0 = 1';

en lugar de

$where .= ' AND where 0 = 1';

Lamentablemente, no tengo tiempo para probar nada, pero este debería ser un buen punto de partida

    
respondido por el Pieter Goosen 09.05.2016 - 16:08
2

Para referencia, antes: 45q, después: 42q

El código es muy similar al código utilizado por @birgire

function _tomjn_home_cancel_query( $query, \WP_Query $q ) {
    if ( !$q->is_admin() && !$q->is_feed() && $q->is_home() && $q->is_main_query() ) {
        $query = false;
        $q->set( 'fields', 'ids' );
    }
    return $query;
}
add_filter( 'posts_request', '_tomjn_home_cancel_query', 100, 2 );
    
respondido por el Tom J Nowell 09.05.2016 - 17:32

Lea otras preguntas en las etiquetas