WordPressで、投稿記事と同じカテゴリー内の前後数件の記事を一覧出力する

[最終更新] 2016年11月17日

ブログでは、記事下に投稿記事と同じカテゴリーの記事を並べる、ということをよくします。今回は、投稿した記事と同じカテゴリーの前後数件の記事を一覧出力します。要は、投稿した記事と同じカテゴリーでかつ、投稿した日付が近い日のものを一覧出力しよう、ということです。

スポンサーリンク

動機

ブログにおいては、投稿した記事と同じカテゴリーの記事を記事下に一覧出力するのが一般的です。その時、同一カテゴリーの最新記事であるか、あるいはランダムに並べたものであることがたいていのようです。

それはそれでよいのですが、投稿した記事の前後の記事を一覧出力したい、というケースもあるものと思います。たとえば連載記事です。全20回の連載記事を一つのカテゴリでまとめて、記事下に最新記事を10件表示するようにした場合、たとえ第5回の記事のページでも、記事下に一覧出力されるのは第11回〜第20回となってしまいます。しかし、この場合読者に優しいのは、第5回の前後、すなわち第1回〜第4回および第6回〜第10回が一覧出力されることではないでしょうか。

このサイトは、連載記事は多くありませんが、ひとつながりのテーマについて、ある時期に集中して記述することが多いです。したがって、記事下に出力するのは、最新記事よりも、投稿記事の前後の記事であるほうが、より関連性が高くなる可能性が高いと考え、今回の実装に至りました。

完成形

前後合わせて10件の記事を出力します。基本は前5件、後5件ですが、記事数が5件に満たない場合は前2件後8件などとします。合計が10件に満たない場合は、すべて表示されます。また、投稿記事は一覧内に出力しません。カテゴリーが複数ある場合は、すべてのカテゴリーについて一覧出力します。その際、一度出力した記事は他カテゴリー内で出力しません。

2016年11月現在、この記事の下の出力がまさにそうです。一応画像を貼ります(日付出力部分はソースコードに含んでいません。念のため)。

記事一覧出力の例
記事一覧出力の例

だいたい上のような感じを目指します。

ソースコード

ソースコードを以下に記述します。使用されている関数の意味や、どのファイルに適用すべきかなどは、より簡単な実装である「WordPress で同一カテゴリの記事タイトルを記事下に表示(複数カテゴリ)」の記事を参照してください。この記事に書いてあることがわかれば大丈夫です。逆にわからないと厳しいと思います。

<?php
// 投稿記事のカテゴリーを取得する
$post_cat_ary = get_the_category();
$post_cat_id = array();
foreach( $post_cat_ary as $post_cat ):
	$post_cat_id[] = $post_cat->cat_ID;
endforeach;
$args = array( 'include' => $post_cat_id );
$categories = get_categories( $args );

// 投稿記事のIDと、除外するIDリストの配列
$post_id = get_the_ID();
$post_id_array = array();

// カテゴリー毎にループ処理
foreach( $categories as $category ):
	// 投稿記事のカテゴリ内で新着から何番目かを確認
	$args = array( 'posts_per_page' => 999, 'category' => $category->cat_ID, 'exclude' => $post_id_array );
	$posts = get_posts( $args );
	$posts_ids = array();
	foreach ( $posts as $post ) {
		$posts_ids[] += $post->ID;
	}
	$post_pos = array_search( $post_id, $posts_ids );

	// post_id_array に投稿記事のIDを追加
	$exclude_ids = array();
	$exclude_ids[] = $post_id_array;
	$exclude_ids[] += $post_id;

	// 投稿記事がカテゴリー内で新着5件内だった時の処理
	$post_offset = $post_pos - 5;
	if ( $post_offset < 0 ) {
		$post_offset = 0;
	}

	// 投稿記事の順番 - 5件 をオフセットして記事一覧を取得
	$args = array( 'posts_per_page' => 10, 'offset' => $post_offset, 'category' => $category->cat_ID, 'exclude' => $exclude_ids );
	$posts = get_posts( $args );

	if ( sizeof($posts) > 0 ):			
		echo '<h2><a href="'.get_category_link( $category->term_id ).'">'.$category->cat_name.'</a> の記事</h2>';
	   	echo '<ul>';
		$count = 0;
         	foreach( $posts as $post ):
			// 投稿記事がカテゴリー内で最新だった時
			if ( $post_pos == 0 ) {
				if ( $count == 0 ) {
					echo '<li>---本記事(カテゴリー内最新)---</li>';
				}						
			} 

			// 記事の表示
       			echo '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';
			// 一度出た記事を二度表示しない
			$post_id_array[] = get_the_ID();

			if ( ($post > 0) && ($post_pos < 5) ) {
				if ( $count == $post_pos -1 ) {
					echo '<li>---本記事---</li>';
				}
			} else {
				if ( $count == 4 ) {
					echo '<li>---本記事---</li>';
				}
			}
			$count += 1;
             	endforeach;
	        echo '</ul>';
	endif;
endforeach;
$post = get_post($post_id);
?>

大まかには以下のことをしています。

  1. 投稿記事のカテゴリーを取得する($categories)
  2. 取得した各カテゴリーについて、次のループ処理を行う
  3. 投稿記事が、そのカテゴリーで新着から何番目かを確認する($post_pos)
  4. $post_posから前後5件表示したいので、$post_pos-5 をオフセットしてget_posts()
  5. get_posts()の結果を$postにして出力する
  6. 3-5を投稿記事のカテゴリーの数だけ出力
  7. $postを元に戻す

最後はメタデータに影響するのでなにげに重要です。$postをいじるのは行儀が悪いのかしら……。そろそろWordPressちゃんと勉強しようか……。

一度出た記事を表示しないなどの処理もしているので、コードがちょっと複雑になっています。詳細については、コメントでわかるように書いているつもり…です。

関連コンテンツ

関連記事

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。