サポート » 使い方全般 » WP_queryで複数タームごとに記事を指定して一覧を表示

  • WP_queryで複数のタームの一覧を表示して、さらにターム毎に取得する記事数を指定したいのですが、posts_per_page では、全ての一覧の記事数指定しか出来なく、他の方法がないのか調べているのですが、、、どういった方法があるのでしょうか?

    ちなみにターム毎取得コードは以下を記述しております。

    <?php
    	  $args = array(
    	  'tax_query' => array(
    	  'relation' => 'OR',
          array(
            'taxonomy' => '◯◯◯◯◯◯',
            'field' => 'slug',
            'terms' => array( 'タームA' ),
          ),
    	  array(
            'taxonomy' => 'auther',
            'field' => 'slug',
            'terms' => array( 'タームB' ),
          ),
    	  array(
            'taxonomy' => 'auther',
            'field' => 'slug',
            'terms' => array( 'タームC' ),
          )
        )
    );
2件の返信を表示中 - 1 - 2件目 (全2件中)
  • WP_query を一度だけ使うという前提条件だと、ご希望の方法はありません。

    強引な方法ですが、タームAが付いた投稿を取得して配列Aに入れ、タームBが付いたのを取得して配列Bに入れ、タームCのは配列Cに入れ、配列AとBとCを array_merge で一つにまとめる位しか思いつかないです。

    データベースからの記事取得は、お示しのコードでやって、表示をするときに調整するというはどうでしょう。どのように表示したいかによりますが、同じページに表示するという前提で考えました。途中でページが変わると、データが入れ替わってしまうので、うまく動きません。add_filter の無名関数は、PHP 5.3 より前のバージョンではエラーになります。

    考え方は、こうです。$wp_query は普通、ループの終わりに、ループポインタを最初に戻します。途中でループを抜けると、ポインタをそのまま保持するのですが、rewind_posts() メソッドで、ポインタを最初に戻すことができます。これを利用して、ひとつのデータを複数回のループで利用するというものです。それぞれのループの中でタームを判定できるように取得するデータを通常とは違ったものにしてあります。ループ1回ごとに投稿 ID からタームを得ると、結局毎回 WP_Query が実行されるようなことになるので、まとめてデータを取り、表示部分で調整をするという感じです。

    ソートについては、すべて共通のフィールドを使うことになります。pre_get_posts フックの中で指定してください。デフォルトは投稿日順です。それぞれのタームでソートアルゴリズムが違う場合は、PHP を使う必要があります。

    functions.php

    function term_filtered_query($query) {
        if (is_admin() && !$query->is_main_query()) return;
        if (...ページの条件...) {
            add_filter('posts_join_request', function($join) {
                $join .= ' INNER JOIN wp_term_taxonomy AS tt ON wp_term_relationships.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN wp_terms AS t ON tt.term_id = t.term_id';
                return $join;
            }, 10, 1);
            add_filter('posts_fields_request', function($fields) {
                $fields .= ', t.name AS term_name';
                return $fields;
            }, 10, 1);
            $query->set('tax_query', array(
                'relation' => 'OR',
                array(
                    'taxonomy' => 'taxonomy',
                    'field'    => 'slug',
                    'terms'    => array('term1')
                ),
                array(
                     ....,
                )));
        }
    }
    add_action('pre_get_posts', 'term_filtered_query');

    テンプレート

    // 1回目の処理
    global $wp_query; // 念のため
    $counter = 0;
    if (have_posts()) {
        while (have_posts()) {
            the_post();
            if ($post->term_name == 'term1') { // term1 以外を読み飛ばす
                term1 を処理;
                if (++$counter > 3) break; // 投稿3つでループを抜ける
            }
        }
    }
    $wp_query->rewind_posts(); // ポインタを戻す
    $counter = 0; // カウンタも戻す
    while (have_posts()) {
        the_post();
        if ($post->term_name == 'term2') {
            term2 を処理;
            if (++$counter < 4) break; // 投稿4つで終了
        }
    }
    // ここで再びリワインドとポンタのリセット
    $wp_query->rewind_posts();
    $counter = 0;
    while (have_posts()) {
        the_post();
        if ($post->term_name == 'term3') {
            term3 を処理;
            if (++$counter < 5) break; // 投稿5つで終了
        }
    }
    // まだ続くなら、同じ操作を繰り返す

2件の返信を表示中 - 1 - 2件目 (全2件中)
  • トピック「WP_queryで複数タームごとに記事を指定して一覧を表示」には新たに返信することはできません。