Hapus Permintaan Beranda

8

Saya memiliki beranda yang menampilkan home.phptemplat, berisi 2 sidebars dengan widget di dalamnya.

Kueri utama masih menarik di posting 10 standar, tapi karena saya tidak menampilkan ini, saya ingin menghilangkan permintaan yang dibuat ke database sepenuhnya. Jika perlu, loop posting kosong akan dilakukan karena saya tidak menggunakan loop utama dalam home.phptemplate saya .

Bagaimana saya melakukan ini? Saya bisa menggunakan pre_get_postsuntuk meminimalkan dan mengurangi kueri, tapi itu masih membuat saya dengan kueri yang sangat cepat, bagaimana cara menghilangkannya sama sekali?

Tom J Nowell
sumber
1
Pertanyaan ini sepertinya layak dibaca. Tetapi jika Anda bertanya kepada saya, saya akan menggunakan template saya sendiri dan menjadikannya sebagai halaman rumah statis dari pengaturan, karena sementara itu mungkin, itu tidak layak. Baca lebih menarik di sini . Entah semua itu atau saya benar-benar merindukan inti pertanyaan Anda.
N00b

Jawaban:

7

The posts_requestfilter

Memilah-milah bagian yang menurut WP_Querykami menarik:

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

Kami mungkin mencoba menghilangkan permintaan rumah utama melalui posts_requestfilter. Ini sebuah contoh:

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

tempat kami memaksa 'fields' => 'ids'untuk keluar lebih awal.

The posts_pre_queryFilter (WP 4.6+)

Kita juga bisa menggunakan posts_pre_querysrc filter baru yang tersedia di 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 );

Filter ini memungkinkan untuk melompati kueri basis data yang biasa untuk mengimplementasikan injeksi posting khusus sebagai gantinya.

Saya baru saja menguji ini dan memperhatikan bahwa ini tidak akan mencegah posting yang lengket, berlawanan dengan posts_requestpendekatan.

Lihatlah tiket # 36687 untuk info lebih lanjut dan contoh di sana oleh @boonebgorges.

birgire
sumber
Sangat mirip dengan apa yang baru saja saya tulis, tetapi saya tidak melihat bagian field id, yang membuat 2 pertanyaan lagi, terima kasih!
Tom J Nowell
1
ok hebat, kadang-kadang terlintas dalam pikiran betapa menyenangkannya memiliki cara mudah untuk keluar WP_Querylebih awal, misalnya melalui argumen seperti 'skip_query' => trueatau bahkan melalui filter, tapi kemudian saya menyadari betapa mudahnya itu dapat mengacaukan situs-situs di internet, jadi banyak cara ;-) @ TomJNowell
birgire
Ada filter split_the_querytepat di bawah garis, melakukan hal yang persis sama tetapi saya ingin tahu itu tidak mengurangi jumlah permintaan!
Sumit
Solusi hebat, bahkan saya ketinggalan 'fields' => 'ids', dan saya sering menggunakannya ;-)
Pieter Goosen
2

Berikut adalah trik rapi yang saya pelajari dari @birgire, kita dapat menghentikan permintaan utama dengan menambahkan AND where 0=1ke WHEREklausa dari permintaan SQL. Ini mungkin masih menghasilkan satu permintaan db, tetapi pasti akan menghentikan permintaan utama dari posting permintaan

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

Anda juga dapat mencoba mengganti WHEREklausa denganwhere 0 = 1

$where = ' where 0 = 1';

dari pada

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

Sayangnya, saya tidak punya waktu untuk menguji apa pun, tetapi ini harus menjadi titik awal yang bagus

Pieter Goosen
sumber
Ini kedengarannya paling dekat dengan apa yang saya minta, atau paling tidak, kueri yang paling dioptimalkan, saya akan mempertimbangkan ini ketika menyelidiki apakah kueri itu sendiri dapat dihapuskan
Tom J Nowell
+1 untuk membagikan gagasan ini. Tapi saya mengujinya dan mengurangi waktu dengan 2 ms :)
Sumit
Saya berharap saya bisa mengingat dari mana saya mempelajarinya, tetapi ini juga digunakan oleh core ;-) Saya pikir akan lebih baik juga mengabaikan perekat untuk $q->set( 'ignore_sticky_posts', true );berjaga-jaga.
birgire
@Birgire Bintik besar. Bahkan dengan solusi saya, Anda masih mendapatkan perekat kembali dari permintaan utama ;-)
Pieter Goosen
2

Untuk referensi, sebelum: 45q, setelah: 42q

Kode ini sangat mirip dengan kode yang digunakan oleh @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 );
Tom J Nowell
sumber