Post Get Post veya WP_Query Kullanmalı mıyım


29

Taxonomy.php şablonum üzerinden çağırdığım aşağıdaki sorgu var query_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);

Bu fonksiyon mükemmel çalışıyor. Ancak, sorgu gönderileri için kodeksi okuduktan sonra, varsayılan sorguyu değiştirmek için tercih edilen bir yol olarak pre_get_posts'tan bahsetti. Pre_get_posts aşağıdaki wp_query işlevimden daha verimli olur mu?

Öyleyse, pre_get_posts'u nasıl oluşturabilirim ve değişkenimi ve sorgumu aşağıya nasıl geçebilirim?

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

Yanıtlar:


14

pre_get_postsAynı sorguyu çalıştıracağından, her ikisi de aynı zamanı alacaktır. Ancak, pre_get_postseylem kullanırsanız, bir veya daha fazla SQL sorgusu kaydedersiniz. Şu anda, WordPress varsayılan sorguyu çalıştırıyor ve ardından sorgunuzu varsayılan sorgunun sonuçlarını değiştiren bu işlevle çalıştırıyorsunuz (sonuçta, varsayılan sorgunun faydası yok). Aşağıda, taşıyabilirsiniz nasıl $argsTo

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

Cevap için çok teşekkür ederim. Çok yardımcı oldu. Hızlı bir soru. Fonksiyonu benim tema function.php dosyasına yerleştirdim. Custom_pre_get_posts ($ query) 'ı taxonomy.php adresimden çalıştırıyorum. Taxonomy.php'de $ posttype, $ post_status, $ geo, $ brands, $ taxtype değişkenlerini kurdum ve bu değişkeni değiştiren iki döngü çalıştırdım. Taxonomy.php dosyasında değişkenlere yukarıdaki fonksiyona geçmenin bir yolu var mı? Custom_pre_get_posts ($ query, 'dealers', 'publish', '1', $ taxtype, $ geo, $ brands) denediğimde; Custom_pre_get_posts () için 2 ile 7 arasındaki argüman eksik. Add_action nedeniyle tahmin ediyorum ???
user1609391

1
Kalan argümanları kabul etmek için custom_pre_get_posts 'u değiştirdiğinizi farz ediyorum. Evet, add_action nedeniyle hata alıyorsunuz. add_action bu işlevi tek bir argümanla çağırır (yani $ query), eksik argüman hatalarını önlemek için diğer argümanlara varsayılan değerler vermelisiniz. like ($ posttype = null, $ poststatus = null ...) bu yüzden düzgün bir şekilde add_action tarafından çağrılabilir.
MR

MR Cevabınız için teşekkürler. Ekleme eylemini okudum ve bir öncelik ve argüman numarası atamam gerektiğini görüyorum. Bu yüzden ekleme eylemimi <code> add_action ('pre_get_posts', 'custom_pre_get_posts', 10,7); </code> olarak değiştirdim. Sonra taxonomy.php sayfamda <code> do_action ('pre_get_post', $ query, ' bayiler ',' yayınla ',' 1 ', $ taxtype, $ geo, $ markalar); </code>. Ama yine de aynı hatayı alıyorum. Varsayılan değerleri nereye koyacağımı bilmiyordum. Google'ı denedim ama referans bulamadım. Bununla nasıl başa çıkılacağı konusunda bana biraz daha bilgi verebilir misiniz?
user1609391

Cevap ve örnek için teşekkür ederiz. Ancak, sadece yeni bir wordpress sorgusu yapmam gerektiğinde pre_get_posts kullanmaya çalıştığımı düşünüyorum. Bir sorgu kaydetmeye çalışıyordum, ancak benim durumumda bu mümkün olmayabilir. Sebep, parametrede ayarladığınız tüm argümanlardır, fonksiyona taxonomy.php dosyamdan geçmek istedim. Yani $ paidvalue = ”1” taxonomy.php içinde hangi koşulu çalıştırdığıma bağlı olarak 1 veya 0 olabilir. Taxonomy.php dosyamdaki işlevi çağırmasam bile, sayfa yüklendiğinde pre_get_posts yukarıda doğru görünüyor. Bunu doğru görüyor muyum?
user1609391

3
Bu cevap şu anda yazıldığı gibi mantıklı değil. Nesnenin içindeki herhangi bir değerin üzerine etkin bir şekilde yazacaksınız$wp_query ve işler tamamen başarısız olacaktır. Bunun dışında, ek bir sorgu çalıştırmanın doğru olmadığı pre_get_posts...
kaiser

10

En çok oy alan cevap olarak geç cevap sorgunuzu kıracak ve sadece bazı önemli noktalarda doğru değil.

Ana WP_Query ve 's filtreleri

Birincisi, WordPress dahili olarak kullanır query_posts()(etrafında ince bir sarıcı WP_Queryo olmamalı temaları veya eklentileri kullanılacak) bir yapmak WP_Query. Bu WP_Queryana döngü / sorgu görevi görüyor. Bu sorgu, asıl SQL sorgu dizesi kuruluncaya kadar bir çok filtre ve eylemle çalışacaktır. Bunlardan biri pre_get_posts. Diğerleri şunlardır posts_clauses, posts_wherevb o da sorgu dizesi bina sürecini durdurmak için izin verir.

Çekirdeğin içinde olanlara derinlemesine bir bakış

WordPress çalışan wp()fonksiyonu (içinde wp-includes/functions.phparamaları), $wp->main()( $wpde tanımlandığı sınıfı WP, bir amacı, wp-includes/class-wp.php). Bu, WordPress'e şunları söyler:

  1. URL'yi WP->parse_request()aşağıdakiler üzerinde daha fazlasını kullanarak bir sorgu belirtiminde ayrıştırın .
  2. Koşullu Etiketler tarafından kullanılan tüm is_ değişkenlerini $wp_query->parse_query()( $wp_queryiçinde class WP_Querytanımlanmış bir nesnedir wp-includes/query.php) kullanarak ayarlayın. Bu işlevin adına rağmen, bu durumda WP_Query->parse_queryelimizden gelenin en iyisini yaptığımızdan, bizim için herhangi bir ayrıştırma yapılmadığını unutmayın WP->parse_request().
  3. Sorgu belirtimini bir MySQL veritabanı sorgusuna dönüştürün ve WP_Query-> get_posts () işlevinde yayınların listesini almak için veritabanı sorgusunu çalıştırın. Gönderileri, WordPress Döngüsünde kullanılacak $ wp_query nesnesine kaydedin.

Kaynak Kodeksi

Sonuç

Ana sorguyu gerçekten değiştirmek istiyorsanız, çok çeşitli filtreler kullanabilirsiniz. Basitçe kullanmak $query->set( 'some_key', 'some_value' );için değiştirmek verileri var ya kullanımını$query->get( 'some_key' ); için almak şartlı kontrolleri yapmak verileri. Bu, yalnızca SQL sorgusunu değiştirdiğiniz için sizi ikinci bir sorgu yapmaktan kurtaracaktır .

Yapmak zorundaysan Ek bir sorgu gerekiyorsa, bir WP_Querynesneyle gidin . Bu, DB'ye başka bir sorgu ekleyecektir.

Örnek

Cevaplar her zaman bir örnekle daha iyi çalıştığı için, burada gerçekten iyi bir tane bulmuşsunuzdur (Brad Touesnard'a aittir).

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

Daha sonra aşağıdaki örnekte gördüğünüz gibi ikinci / ek sorgunuzu çalıştırabilirsiniz . Sorgunuzu daha sonra sıfırlamayı unutmayın.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.