web-dev-qa-db-ja.com

Pre_get_postsを使用して投稿をフィルタリングする

Status = currentの調査のみを表示するようにarchive_research.phpをフィルタリングしようとしています。

Functions.phpで:

add_action( 'pre_get_posts', 'only_current' );

function only_current( $query ) {
    if ( $query->is_main_query() ) {
        $args = array(
            'post_type' => 'research',
            'tax_query' => array(
                array(
                    'taxonomy' => 'status',
                    'field'    => 'slug',
                    'terms'    => 'current',
                ),
             ),
        );
        $query = new WP_Query( $args );
    }
}

Archive-research.phpでは、

        // theloop
        if ( have_posts() ) : while ( have_posts() ) : the_post();
            // print title etc

結果:research archiveはすべての研究を表示します。

私はこれの多くのわずかな変更を試みました。読みやすさのために、私はたくさんの冗長なコードを貼り付けることなくここでそれらを合計しようとします:

  • tax_queryを削除しています..同じ結果(予想)
  • tax_queryを、存在しない分類用語に変更します。同じ結果
  • $query = new WP_Query( $args )$query->set('meta_query', $args)または$query->set($args)と置き換えます。同じ結果
  • archive-researchのhave_posts()the_post()$wp_query->have_posts()$wp_query->the_post()に置き換えます。同じ結果
  • // theloopの前にdo_action('only_current')への呼び出しを追加する..同じ結果

したがって、ここでの共通のテーマは、私が何をしても同じ結果が得られるということです。私には欠けている非常に明白な解決策がなければなりません、そして誰かがそれを指摘できれば私は本当にそれを感謝するでしょう。

有用なデバッグ情報の最後の部分:

string(222) "SELECT SQL_CALC_FOUND_ROWS wp_posts.ID wp_posts WHERE 1 = 1 AND wp_posts.post_type = 'research' AND(wp_posts.post_status = 'パブリッシュ' OR wp_posts.post_status = 'プライベート' BY BY wp_posts.post_date DESC LIMIT 0、10 "

これは// theloopの前にecho var_dump($wp_query->request)を呼び出した結果です。

2
Kristina

既存のクエリを変更するのではなく、新しいクエリを作成しています。

pre_get_postsコーデックスページ には、$ query引数が参照渡しであることを説明しているので、直接変更する必要があります。グローバルを宣言したり値を返したりする必要はありません。関数を次のように更新してください。

add_action( 'pre_get_posts', 'only_current' );
function only_current( $query ) {

    if ( is_admin() ) {
        return;
    }

    if ( ! $query->is_main_query() ) {
        return;
    }

    if ( ! is_post_type_archive( 'research' ) ) {
        return;
    }

    $tax_query = array(
        array(
            'taxonomy' => 'status',
            'field'    => 'slug',
            'terms'    => 'current',
        ),
    );
    $query->set( 'tax_query', $tax_query );
}

pre_get_postsフィルタは管理者内のクエリにも適用されるので、サイトのフロントエンドにいるかどうかを確認するために別のifステートメントを追加しました。

私たちがresearchアーカイブページにいることを確認するためのステートメントも追加しました。

上記の関数はあなたのfunctions.phpファイル、またはサイト固有のプラグインに入れる必要があります。 archive-research.phpファイルに配置しても、archive-research.phpテンプレートがロードされるまでにクエリが実行されるため、うまくいきません。

1
Andrew