Soll ich Pre Get Posts oder WP_Query verwenden?


29

Ich habe folgende Abfrage, die ich in meiner taxonomy.php-Vorlage über aufrufe query_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);

Diese Funktion funktioniert einwandfrei. Nach dem Lesen des Codex für Abfrageposts wurden jedoch pre_get_posts als bevorzugte Methode zum Ändern der Standardabfrage angegeben. Wären die pre_get_posts effizienter als meine unten stehende wp_query-Funktion?

Wenn ja, wie würde ich die pre_get_posts konstruieren und meine Variable und Abfrage unten übergeben?

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

Antworten:


14

pre_get_postswird dieselbe Abfrage ausführen, sodass beide dieselbe Zeit benötigen. Wenn Sie jedoch pre_get_postsaction verwenden, speichern Sie eine oder mehrere SQL-Abfragen. Im Moment führt WordPress eine Standardabfrage aus und Sie führen Ihre Abfrage mit dieser Funktion aus, die die Ergebnisse der Standardabfrage ersetzt (die resultierende Standardabfrage ist nutzlos). Im Folgenden erfahren Sie, wie Sie Ihre $argsnach verschieben können

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

Vielen Dank für die Antwort. Es ist sehr hilfreich. Eine kurze Frage. Ich habe die Funktion in die Datei function.php meines Themas eingefügt. Ich führe diese Funktion custom_pre_get_posts ($ query) aus meiner taxonomy.php aus. In der taxonomy.php habe ich die Variablen $ posttype, $ post_status, $ geo, $ brands, $ taxtype eingerichtet und zwei Schleifen ausgeführt, um diese Variable zu ändern. Gibt es eine Möglichkeit, eine Variable aus taxonomy.php in die obige Funktion zu übergeben? Wenn ich custom_pre_get_posts versuche ($ query, 'dealer', 'publish', '1', $ taxtype, $ geo, $ brands); Ich erhalte die Argumente 2 bis 7 für custom_pre_get_posts (). Ich nehme wegen add_action an ???
user1609391

1
Ich gehe davon aus, dass Sie die custom_pre_get_posts geändert haben, um die verbleibenden Argumente zu akzeptieren. Ja, Sie erhalten eine Fehlermeldung wegen add_action. Wenn add_action diese Funktion mit einem einzelnen Argument aufruft (zB $ query), sollten Sie anderen Argumenten Standardwerte zuweisen, um fehlende Argumentfehler zu vermeiden. wie ($ posttype = null, $ poststatus = null ...), damit es ordnungsgemäß von add_action aufgerufen werden kann.
MR

MR Danke für die Antwort. Ich habe nachgeschaut, wie man eine Aktion hinzufügt, und sehe, dass ich eine Prioritäts- und Argumentationsnummer zuweisen sollte. Also habe ich meine Add-Aktion in <code> add_action ('pre_get_posts', 'custom_pre_get_posts', 10,7) geändert. </ Code> Dann habe ich in meiner taxonomy.php-Seite <code> do_action ('pre_get_post', $ query, ' Händler ',' Veröffentlichen ',' 1 ', $ Steuertyp, $ Geo, $ Marken); </ code>. Aber ich bekomme immer noch den gleichen Fehler. Ich war mir nicht sicher, wo ich die Standardwerte setzen sollte. Ich habe Google ausprobiert, konnte aber keine Referenz finden. Können Sie mir ein bisschen mehr Informationen darüber geben, wie ich damit umgehen soll?
user1609391

Vielen Dank für die Antwort und das Beispiel. Aber ich denke, ich könnte versuchen, pre_get_posts zu verwenden, wenn ich nur eine neue WordPress-Abfrage machen sollte. Ich habe versucht, eine Abfrage zu speichern, aber in meinem Fall ist dies möglicherweise nicht möglich. Der Grund dafür sind all die Argumente, die Sie in dem Parameter festgelegt haben, den ich aus meiner taxonomy.php-Datei an die Funktion übergeben wollte. $ Paidvalue = ”1” kann also 1 oder 0 sein, abhängig davon, welche Bedingung ich in taxonomy.php ausführe. Es scheint, als ob pre_get_posts oben beim Laden der Seite ausgelöst werden, auch wenn ich die Funktion in meiner taxonomy.php-Datei nicht aufrufe. Sehe ich das richtig?
user1609391

3
Diese Antwort ist nicht sinnvoll, wie es derzeit geschrieben wird. Sie werden jeden Wert innerhalb des Objekts überschreiben$wp_query und die Dinge werden vollständig fehlschlagen. Abgesehen davon ist es einfach nicht wahr, dass pre_get_postseine zusätzliche Abfrage ausgeführt wird ...
Kaiser

10

Eine verspätete Antwort als die am häufigsten gewählte Antwort wird Ihre Anfrage unterbrechen und ist in einigen wichtigen Punkten einfach nicht wahr.

Die Haupt- WP_Query und ihre Filter

Erstens verwendet WordPress intern query_posts()(ein dünner Wrapper WP_Query, der nicht in Themes oder Plugins verwendet werden sollte), um Folgendes zu tun:WP_Query : Dies WP_Queryist die Hauptschleife / Abfrage. Diese Abfrage durchläuft eine Vielzahl von Filtern und Aktionen, bis die eigentliche SQL-Abfragezeichenfolge erstellt wurde. Eine davon ist pre_get_posts. Andere sind posts_clauses, posts_whereusw. , die auch Ihnen erlauben , die Query - String - Bauprozess abzufangen.

Ein genauer Blick auf das, was im Inneren des Kerns passiert

WordPress führt die wp()Funktion (inwp-includes/functions.php ) aus, die aufruft $wp->main()( $wpist ein Objekt der Klasse WP, das in definiert ist wp-includes/class-wp.php). Dies weist WordPress an:

  1. Analysieren Sie die URL in einer Abfragespezifikation mit WP->parse_request()- dazu weiter unten.
  2. Setzen Sie alle is_-Variablen, die von Conditional Tags verwendet werden, mit $wp_query->parse_query()( $wp_queryist ein Objekt vonclass WP_Query , das in definiert ist wp-includes/query.php). Beachten Sie, dass in diesem Fall trotz des Namens dieser Funktion WP_Query->parse_querykein Parsing für uns durchgeführt wird, da dies zuvor von ausgeführt wurde WP->parse_request().
  3. Konvertieren Sie die Abfragespezifikation in eine MySQL-Datenbankabfrage und führen Sie die Datenbankabfrage aus, um die Liste der Beiträge in der Funktion WP_Query-> get_posts () abzurufen. Speichern Sie die Beiträge im Objekt $ wp_query, um sie in der WordPress-Schleife zu verwenden.

Quelle Codex

Fazit

Wenn Sie die Hauptabfrage wirklich ändern möchten, können Sie eine Vielzahl von Filtern verwenden. Verwenden Sie einfach $query->set( 'some_key', 'some_value' );, um Daten dort zu ändern , oder $query->get( 'some_key' );, um Daten abzurufen , um bedingte Prüfungen durchzuführen. Dies erspart Ihnen das Ausführen einer zweiten Abfrage, da Sie nur die SQL-Abfrage ändern .

Wenn Sie eine zusätzliche Abfrage durchführen müssen, gehen Sie mit einem WP_QueryObjekt. Dadurch wird der Datenbank eine weitere Abfrage hinzugefügt.

Beispiel

Da Antworten mit einem Beispiel immer besser funktionieren, haben Sie hier ein wirklich nettes (Requisiten an Brad Touesnard), das das Kernobjekt einfach erweitert und daher ziemlich wiederverwendbar ist (machen Sie ein Plugin daraus):

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

Sie können dann Ihre zweite / zusätzliche Abfrage ausführen, wie Sie im folgenden Beispiel sehen können. Vergessen Sie nicht, Ihre Anfrage danach zurückzusetzen.

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.