Pre Get PostsまたはWP_Queryを使用する必要があります


29

私はtaxonomy.phpテンプレートで次のクエリを呼び出しています query_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);

この機能は完全に機能します。ただし、クエリ投稿のコーデックスを読んだ後、デフォルトのクエリを変更する好ましい方法としてpre_get_postsに言及しました。pre_get_postsは、以下のwp_query関数よりも効率的ですか?

もしそうなら、どのようにpre_get_postsを構築し、変数とクエリを渡しますか?

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

回答:


14

pre_get_posts同じクエリを実行するため、両方に同じ時間がかかります。ただし、pre_get_postsアクションを利用する場合は、1つ以上のSQLクエリを保存します。現在、WordPressはデフォルトのクエリを実行しています。次に、この関数を使用してクエリを実行し、デフォルトのクエリの結果を置き換えます(結果、デフォルトのクエリは使用できません)。以下は、あなたが移動することができる方法である$argsとし

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

返信ありがとうございます。とても助かります。簡単な質問。関数をテーマのfunction.phpファイルに配置しました。この関数custom_pre_get_posts($ query)をtaxonomy.phpから実行します。taxonomy.phpでは、変数$ posttype、$ post_status、$ geo、$ brands、$ taxtypeを設定し、これらの変数を変更する2つのループを実行します。taxonomy.phpから上記の関数に変数を渡す方法はありますか?custom_pre_get_posts($ query、 'dealers'、 'publish'、 '1'、$ taxtype、$ geo、$ brands);を試すとき custom_pre_get_posts()の引数2から7が欠落しています。私はadd_actionが原因だと思いますか???
user1609391

1
残りの引数を受け入れるようにcustom_pre_get_postsを変更したと仮定しています。はい、add_actionが原因でエラーが発生しています。add_actionは、単一の引数(つまり$ query)でこの関数を呼び出します。引数の欠落エラーを回避するには、他の引数にデフォルト値を指定する必要があります。($ posttype = null、$ poststatus = null ...)のように、add_actionによって適切に呼び出すことができます。
MR

MR返信ありがとうございます。アクションの追加について読んだところ、優先順位と引数番号を割り当てる必要があることがわかりました。そこで、addアクションを<code> add_action( 'pre_get_posts'、 'custom_pre_get_posts'、10,7);に変更しました。</ code>次に、taxonomy.phpページで<code> do_action( 'pre_get_post'、$ query、 'ディーラー」、「公開」、「1」、$ taxtype、$ geo、$ brands)</ code>。しかし、私はまだ同じエラーを受け取っています。デフォルト値をどこに置くかわからなかった。Googleを試してみましたが、参照が見つかりませんでした。これを処理する方法についてもう少し情報を教えていただけますか?
user1609391

返信と例に感謝します。しかし、新しいワードプレスクエリを実行する必要があるときにpre_get_postsを使用しようとしているのではないかと思います。クエリを保存しようとしていましたが、私の場合は不可能な場合があります。その理由は、パラメーターに設定したすべての引数であるため、taxonomy.phpファイルから関数に渡したいと思ったからです。そのため、taxonomy.phpで実行している条件に応じて、$ paidvalue =” 1”は1または0になります。taxonomy.phpファイルの関数を呼び出さなくても、ページがロードされるとすぐに上記のpre_get_postsが起動するようです。これは正しいですか?
user1609391

3
この答えは現在書かれているので意味がありません。オブジェクト内の値を効果的に上書きする$wp_queryと、完全に失敗します。それ以外の点では、追加のクエリを実行することは事実pre_get_postsはありません
...-kaiser

10

最も支持された回答としての遅い回答は、あなたの質問を破り、いくつかの主要な点で単に真実ではありません。

メイン WP_Queryとそれのフィルター

まず、WordPressは内部的に使用していますquery_posts()(薄いラッパWP_Queryことはないはず行うにはテーマやプラグインで使用されます)WP_Query。これWP_Queryはメインループ/クエリとして機能しています。このクエリは、実際のSQLクエリ文字列が構築されるまで、多くのフィルターとアクションを実行します。それらの1つですpre_get_posts。その他にはposts_clauses、クエリ文字列構築プロセスをインターセプトできるようにするposts_where、などがあります。

コア内部で何が起こるかを詳しく見る

ワードプレスは、実行wp()機能(でwp-includes/functions.php呼び出し)、 $wp->main()$wpで定義されたクラスWPの目的であるがwp-includes/class-wp.php)。これはWordPressに次のことを伝えます。

  1. WP->parse_request()以下を使用して、URLをクエリ仕様に解析します。
  2. 使用条件タグによって使用されるすべてのis_変数を設定する$wp_query->parse_query()$wp_query対象となるclass WP_Queryで定義されています、wp-includes/query.php)。この関数の名前にもかかわらず、この場合、WP_Query->parse_query実際には解析は行われないことに注意してくださいWP->parse_request()
  3. 関数WP_Query-> get_posts()で、クエリ仕様をMySQLデータベースクエリに変換し、データベースクエリを実行して投稿のリストを取得します。WordPressループで使用される投稿を$ wp_queryオブジェクトに保存します。

ソースコーデックス

結論

メインクエリを本当に変更する場合は、さまざまなフィルターを使用できます。単にデータ$query->set( 'some_key', 'some_value' );変更するために使用するか、データを取得して条件付きチェックを行うために使用$query->get( 'some_key' );ます。これにより、SQLクエリのみを変更するため、2番目のクエリを実行する必要がなくなります。

追加のクエリを実行する必要がある場合は、WP_Queryオブジェクトを使用します。これにより、DBに別のクエリが追加されます。

例では答えが常にうまくいくので、ここで本当に良いもの(Brad Touesnardの小道具)を手に入れました。

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

その後、次の例に示すように、2番目の / additionalクエリを実行できます。後でクエリをリセットすることを忘れないでください。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.