サポート » テーマ » 投稿のカテゴリー一覧を、記事の更新に並べたい

  • いつもお世話になります。

    オリジナルテーマのhome.phpで、投稿の新着情報をカテゴリ毎に1件ずつ表示しています。
    このカテゴリを、記事の日付順に並べることは可能でしょうか?

    例えますと、
     3月1日 カテゴリBの記事
     4月1日 カテゴリAの記事
     5月1日 カテゴリBの記事
    と投稿した場合、home.phpで
    ・カテゴリB 5月1日 タイトル
    ・カテゴリA 4月1日 タイトル
    と表示したいのです。
    ちなみに、1記事に対し1カテゴリのみ選択しています。

    現在はget_termsで取得したカテゴリ情報をforeachで回し、
    そのループ内でget_postsにget_terms情報を入れて
    1件ずつ出力しています。

    <?php
    $cat_all = get_terms('category');
    if(!is_wp_error($cat_all) && count($cat_all)):
    	//cat loop start
    	foreach($cat_all as $cat_value):
    	$cat_posts = get_posts(array(
    		 'numberposts' => 1,
    		 'post_type' => 'post',
    		 'taxonomy' => 'category',
    		 'term' => $cat_value->slug,
    	));
    	if($cat_posts):
    	?>
    		<h3><a href="<?php echo get_category_link($cat_value->term_id); ?>"><?php echo esc_html($cat_value->name); ?></a></h3>
    		<?php //post out start
    		foreach($cat_posts as $cat_post): ?>
    		    <p><?php echo $cat_post->post_date; ?></p>
    		    <p><a href="<?php echo get_permalink($cat_post->ID); ?>"><?php echo esc_html($cat_post->post_title); ?></a></p>
    		<?php endforeach; //post out end ?>
    	<?php endif; endforeach; //cat loop end
    endif; ?>

    get_termsだと、(当たり前かもしれませんが)日付順というソートができないようなので、
    普通にループさせ、既出カテゴリの記事は条件分岐で飛ばす?

    タクソノミーオーダーのプラグインが入っているので、
    更新のたびにそのカテゴリをトップに持って来るのが早いような気もしていますが

    これを使うとその他のカテゴリリストにも影響が出ますし、
    カスタマーサイトなので、できるだけコードで対応したいと考えています。
    どうぞよろしくお願い致します。

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • 投稿は日付順に並べて、1 カテゴリにつき、1 投稿を出力、ということで合ってますか? それでよければ…

    functions.php

    add_action('pre_get_posts', 'show_every_cat');
    add_filter('posts_groupby', 'every_cat_grouby');
    function show_every_cat($query) {
        if (is_admin() || !$query->is_main_query()) return;
        if (!is_home()) return;
        $cat_all = get_terms('category');
        foreach ($cat_all as $cat) {
            $cats[] = $cat->term_id;
        }
        $query->set('tax_query', array(
                                     array(
                                         'taxonomy' => 'category',
                                         'field'    => 'id',
                                         'terms'    => $cats,
                                         'operator' => 'IN'
                                      )
                                 ));
        $query->set('orderby', 'date');
    }
    function every_cat_groupby($groupby) {
        if (!is_home()) return;
        global $wpdb;
        $groupby = "$wpdb->term_relationships.term_taxonomy_id";
        return $groupby;
    }

    home.php

    if (have_posts()) :
        while (have_posts()) : the_post();
        ....
        endwhile;
    endif;

    if 判定の部分は、違ってたら直してください。tax_query はなくてもいいのですが、groupby フィルタを使うために必要なので、削れません。たぶん、ループで get_posts() するより数段速いはずです。

    テンプレートで、タグやカテゴリを得るには、通常どおり、get_the_* や the_* が使えます。

    トピック投稿者 spicablue

    (@spicablue)

    早速のご返信ありがとうございます!

    いただいたコードをそのまま入れてみたのですが、エラーが出てしまいました。

    htmlソース上部

    Warning: call_user_func_array() expects parameter 1 to be a valid callback, function ‘every_cat_grouby’ not found or invalid function name in /wordpress/wpincludes/plugin.php on line 256

    また、記事もカテゴリ毎ではなく、全投稿が表示されております。

    functions.phpでどこかカスタマイズが必要だったのでしょうか。

    おっと。

    誤: add_filter('posts_groupby', 'every_cat_grouby');
    正: add_filter('posts_groupby', 'every_cat_groupby');

    トピック投稿者 spicablue

    (@spicablue)

    ありがとうございます、表示されました^^

    もうひとつ、このカテゴリ毎に取り出す投稿を、最新のものにすることはできないでしょうか?

    最初の例えですと、
     3月1日 カテゴリBの記事
     4月1日 カテゴリAの記事
     5月1日 カテゴリBの記事
    と投稿していますが、現在は
    ・カテゴリA 4月1日 タイトル
    ・カテゴリB 3月1日 タイトル
    と表示されており、
    新規記事を投稿しても同じ表示になってしまいます。

    こんにちは、

    ちなみに、1記事に対し1カテゴリのみ選択しています。

    でしたら、こんな方法ではどうですか?

    <?php
    query_posts( array( 'posts_per_page' => -1 ) );
    
    if ( have_posts() ) {
    
        while ( have_posts() ) {
    
            the_post();
            $categories = get_the_category();
            $flag       = display_not_yet( $categories[0]->term_id );
            if ( $flag ) {
    
                echo $categories[0] -> cat_name;
    
                printf( '<p>%1$s  <a href="%2$s">%3$s</a></p>', get_the_date(), get_permalink( $post->ID ), the_title( '', '', false ) );
            }
        }
      
    }
    wp_reset_query();
    
    function display_not_yet( $category_id ) {
    
        static $cat_ids = array();
    
        if ( !in_array( $category_id, $cat_ids ) ) {
    
            $cat_ids[] = $category_id;
            return true;
        }
    
        return false;
    }
    ?>

    おおざっぱなので、post_statusだとか、エスケープの必要な部分は、それなりにお願いします

    ああ、なるほど。じゃあ posts_where かな。一つの投稿に複数のカテゴリがついてたらどうしますかねぇ?

    add_action('pre_get_posts', 'show_every_cat');
    add_filter('posts_where_request', 'every_cat_where');
    function show_every_cat($query) {
        if (is_admin() || !$query->is_main_query()) return;
        if (!is_home()) return;
        $query->set('orderby', 'date');
        $query->set('order', 'DESC');
    }
    function every_cat_where($where) {
        if (!is_home()) return $where;
        $cat_all = get_terms('category');
        foreach ($cat_all as $cat) {
            $cats[] = $cat->term_id;
        }
        global $wpdb;
        $where .= " AND $wpdb->posts.ID IN (SELECT MAX(object_id) FROM $wpdb->term_relationships AS t WHERE t.term_taxonomy_id IN (" . implode(',', $cats . ") GROUP BY t.term_taxonomy_id) ";
        return $where;
    }

    ああ、なるほど。じゃあ posts_where かな。一つの投稿に複数のカテゴリがついてたらどうしますかねぇ?

    即、白旗あげます

    ただ、ちょっとやってみました

    home.php

    <?php
    
    /* カテゴリIDをキーとした配列の作成 */
    $category_ids = array_flip( get_all_category_ids() );
    $category_ids = array_map( "reset_val", $category_ids );
    /* 表示する投稿の件数(最大) */
    $limit_posts = 3;
    
    function reset_val( $str ) {
        return 0;
    }
    
    query_posts( array( 'posts_per_page' => -1 ) );
    
    if ( have_posts() ) {
    
        while ( have_posts() ) {
    
            the_post();
    
            $categories = get_the_category();
            /* 一つ目のループでは、カテゴリIDをキーにした配列に、投稿IDをセット */
            foreach ( $categories as $key => $val ) {
    
                if ( empty( $result[ $val -> term_id ] ) || count( $result[ $val -> term_id ] ) < $limit_posts ) { 
    
                    $result[$val -> term_id][$key] = $post -> ID;
                }
            }
        }
    }
    wp_reset_query();
    
    /* このループで、htmlを組み立てて表示 */
    echo '<ul>';
    foreach ( $result as $key => $vals ) {
    
        $category_link = '<li><h3><a href="%1$s" title="Category Name">%2$s</a></h3><ul>';
    
        printf( $category_link, get_category_link( $key ), get_cat_name( $key ) );
    
        $entry_html = '<li><span>%2$s</span> <a href="%1$s">%3$s</a>';
    
       foreach ( $vals as $val ) {
    
            $permalink = get_permalink( $val );
            $date      = get_the_time( 'Y m d', $val );
            $title     = get_the_title( $val );
    
            printf( $entry_html, $permalink, $date, $title );
        }
        echo '</li></ul></li>';
    }
    
    echo '</ul>';
    ?>

    訂正

    $result[$val -> term_id][$key] = $post -> ID;

    $result[$val -> term_id][ $post -> ID] = $post -> ID;

    トピック投稿者 spicablue

    (@spicablue)

    kjmtshさん、nobitaさん、ありがとうございます!

    お恥ずかしいながら、他の案件にスケジュールを押されて、まだテストできておりません。。
    素早くお返事いただいたのに、申し訳ないです。

    今回の案件では、カテゴリーをラジオボタンにしているので重複の可能性はないのですが
    今後そういった可能性も出てきますね。

    またテストできましたら、改めてお返事させていただきます!

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • トピック「投稿のカテゴリー一覧を、記事の更新に並べたい」には新たに返信することはできません。