Haruskah saya menggunakan Pre Get Posts atau WP_Query

29

Saya memiliki pertanyaan berikut yang saya panggil di templat taxonomy.php saya via query_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);

Fungsi ini berfungsi dengan sempurna. Namun setelah membaca kodeks untuk posting kueri disebutkan pre_get_posts sebagai cara yang disukai untuk mengubah kueri default. Apakah pre_get_posts lebih efisien daripada fungsi wp_query saya di bawah?

Jika demikian, bagaimana saya membangun pre_get_posts dan meneruskan variabel dan kueri saya di bawah ini?

function my_custom_query($posttype, $poststatus, $paidvalue, $taxtype, $geo, $brands) {
   global $wp_query; 
   $wp_query = new WP_Query();
   $args = array( 
      'post_type' => $posttype, 
      'post_status' => array($poststatus), 
      'orderby' => 'rand', 
      'posts_per_page' => 30, 
      'meta_query' => array( 
         array( 
            'key' => 'wpcf-paid', 
            'value' => array($paidvalue), 
            'compare' => 'IN', 
            ) 
      ), 
      'tax_query' => array( 
         'relation' => 'AND', 
         array( 
            'taxonomy' => $taxtype, 
            'field' => 'slug', 
            'terms' => $geo 
         ), 
         array( 
            'taxonomy' => 'brands', 
            'field' => 'slug', 
            'terms' => $brands 
         ) 
      ) 
   ); 

   return $wp_query->query($args); 
} 
pengguna1609391
sumber

Jawaban:

14

pre_get_postsakan menjalankan kueri yang sama, sehingga keduanya akan membutuhkan waktu yang sama. Tetapi, jika Anda menggunakan pre_get_poststindakan Anda akan menyimpan satu atau lebih query SQL. Saat ini, WordPress menjalankan kueri default dan kemudian Anda menjalankan kueri Anda dengan fungsi ini yang menggantikan hasil kueri default (yang menghasilkan, kueri default tidak ada gunanya). Di bawah ini adalah bagaimana Anda dapat memindahkan $argske

function custom_pre_get_posts($query, $posttype='dealers', $poststatus='publish', $paidvalue='1', $taxtype='any_default_value', $geo='any_default_value', $brands='any_default_value') {

    // filter your request here.
    if($query->is_category) {

        $args = array(
            'post_type' => $posttype,
            'post_status' => array($poststatus),
            'orderby' => 'rand',
            'posts_per_page' => 30,
            'meta_query' => array(
                array(
                    'key' => 'wpcf-paid',
                    'value' => array($paidvalue),
                    'compare' => 'IN',
                )
            ),
            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => $taxtype,
                    'field' => 'slug',
                    'terms' => $geo
                ),
                array(
                    'taxonomy' => 'brands',
                    'field' => 'slug',
                    'terms' => $brands
                )
            )
        );
        $query->query_vars = $args;
    }
}
add_action('pre_get_posts', 'custom_pre_get_posts');
BAPAK
sumber
Terimakasih banyak untuk balasannya. Ini sangat membantu. Satu pertanyaan singkat. Saya menempatkan fungsi dalam file function.php tema saya. Saya menjalankan fungsi ini custom_pre_get_posts ($ query) dari taxonomy.php saya. Di taxonomy.php saya mengatur variabel, $ posttype, $ post_status, $ geo, $ brand, $ taxtype dan menjalankan dua loop mengubah variabel ini. Apakah ada cara untuk meneruskan variabel ke fungsi di atas dari taxonomy.php? Ketika saya mencoba custom_pre_get_posts ($ query, 'dealer', 'publish', '1', $ taxtype, $ geo, $ brand); Saya mendapatkan argumen Hilang 2 hingga 7 untuk custom_pre_get_posts (). Saya berasumsi karena add_action ???
user1609391
1
Saya berasumsi Anda mengubah custom_pre_get_posts untuk menerima argumen yang tersisa. Ya, Anda mendapatkan kesalahan karena add_action. add_action memanggil fungsi ini dengan argumen tunggal (yaitu $ query), Anda harus memberikan nilai default ke argumen lain untuk menghindari kesalahan argumen yang hilang. seperti ($ posttype = null, $ poststatus = null ...) sehingga dapat dipanggil dengan benar oleh add_action.
MR
MR Terima kasih atas jawabannya. Saya membaca tentang tindakan add dan saya melihat saya harus menetapkan nomor prioritas dan argumen. Jadi saya mengubah tindakan tambahkan saya menjadi <code> add_action ('pre_get_posts', 'custom_pre_get_posts', 10,7); </code> Kemudian di halaman taxonomy.php saya, saya <code> do_action ('pre_get_post', $ query, ' dealer ',' publikasikan ',' 1 ', $ jenis pajak, $ geo, $ merek); </code>. Tapi saya masih mendapatkan kesalahan yang sama. Saya tidak yakin di mana harus meletakkan nilai default. Saya mencoba google tetapi tidak dapat menemukan referensi. Bisakah Anda memberi saya sedikit informasi lebih lanjut tentang di mana cara menangani ini?
user1609391
Terima kasih atas balasan dan contohnya. Tapi saya pikir saya mungkin mencoba menggunakan pre_get_posts ketika saya seharusnya hanya melakukan permintaan wordpress baru. Saya mencoba untuk menyimpan kueri, tetapi dalam kasus saya itu tidak mungkin. Alasannya adalah semua argumen yang Anda atur di parameter, saya ingin meneruskan ke fungsi dari file taxonomy.php saya. Jadi $ paidvalue = ”1” mungkin 1 atau 0 tergantung pada kondisi yang saya jalankan di taxonomy.php. Tampaknya pre_get_posts di atas menyala tepat ketika halaman dibuka bahkan jika saya tidak memanggil fungsi dalam file taxonomy.php saya. Apakah saya melihat ini benar?
user1609391
3
Jawaban ini tidak masuk akal karena saat ini ditulis. Anda akan secara efektif menimpa nilai apa pun di dalam $wp_queryobjek dan semuanya akan gagal total. Selain itu tidak benar bahwa pre_get_postsakan menjalankan kueri tambahan ...
kaiser
10

Jawaban yang terlambat karena jawaban yang paling banyak dipilih akan memecah kueri Anda dan tidak benar dalam beberapa poin utama.

The utama WP_Query dan filter itu

Pertama, WordPress menggunakan internal query_posts()(pembungkus tipis di sekitar WP_Queryyang tidak boleh digunakan dalam tema atau plugin) untuk melakukan WP_Query. Ini WP_Querybertindak sebagai loop / query utama. Kueri ini akan berjalan melalui banyak filter dan tindakan hingga string kueri SQL yang sebenarnya dibuat. Salah satunya adalah pre_get_posts. Lainnya adalah posts_clauses, posts_where, dll yang juga memungkinkan Anda untuk mencegat proses pembangunan string kueri.

Pandangan mendalam tentang apa yang terjadi di dalam inti

WordPress menjalankan wp()fungsi (dalam wp-includes/functions.php), yang memanggil $wp->main()( $wpadalah objek WP kelas, yang didefinisikan dalam wp-includes/class-wp.php). Ini memberitahu WordPress untuk:

  1. Parsing URL ke dalam spesifikasi permintaan menggunakan WP->parse_request()- lebih lanjut tentang itu di bawah ini.
  2. Setel semua variabel is_ yang digunakan oleh Conditional Tag menggunakan $wp_query->parse_query()( $wp_queryadalah objek class WP_Query, yang didefinisikan dalam wp-includes/query.php). Perhatikan bahwa terlepas dari nama fungsi ini, dalam hal WP_Query->parse_queryini tidak benar-benar melakukan parsing untuk kita, karena itu dilakukan sebelumnya WP->parse_request().
  3. Ubah spesifikasi kueri menjadi kueri basis data MySQL, dan jalankan kueri basis data untuk mendapatkan daftar kiriman, dalam fungsi WP_Query-> get_posts (). Simpan tulisan di objek $ wp_query untuk digunakan di WordPress Loop.

Source Codex

Kesimpulan

Jika Anda benar-benar ingin memodifikasi kueri utama, maka Anda dapat menggunakan berbagai macam filter. Cukup gunakan $query->set( 'some_key', 'some_value' );untuk mengubah data di sana atau gunakan $query->get( 'some_key' );untuk mengambil data untuk melakukan pemeriksaan bersyarat. Ini akan menyelamatkan Anda dari melakukan kueri kedua, karena Anda hanya mengubah kueri SQL.

Jika Anda harus melakukan kueri tambahan , maka pergi dengan WP_Queryobjek. Ini akan menambahkan permintaan lain ke DB.

Contoh

Karena jawaban selalu bekerja lebih baik dengan contoh, Anda di sini punya satu yang sangat bagus (alat bantu untuk Brad Touesnard), yang hanya memperluas objek inti dan karena itu cukup dapat digunakan kembali (buat plugin darinya):

class My_Book_Query extends WP_Query
{
    function __construct( $args = array() )
    {
        // Forced/default args
        $args = array_merge( $args, array(
            'posts_per_page' => -1
        ) );

        add_filter( 'posts_fields', array( $this, 'posts_fields' ) );

        parent::__construct( $args );
    }

    public function posts_fields( $sql )
    {
        return "{$sql}, {$GLOBALS['wpdb']->terms}.name AS 'book_category'";
    }
}

Anda kemudian dapat menjalankan kueri kedua / tambahan seperti yang Anda lihat pada contoh berikut. Jangan lupa untuk mereset kueri Anda sesudahnya.

$book_query = new My_Book_Query();
if ( $book_query->have_posts() )
{
    while ( $book_query->have_posts() )
    {
        $book_query->the_post();
        # ...do stuff...
    } // endwhile;
    wp_reset_postdata();
} // endif;
kaisar
sumber