【WordPress】複数の前後記事を出力する方法

July 28, 2015

表示中の記事ページより新しい記事へのリンクを複数と、古い記事へのリンクを複数 出力する方法です。プラグインは使いません。60行ほどのコードで実装できます。

複数の前後記事を表示する機能は、FC2 ブログでは標準で用意されているのですが、WordPress では次の 1記事、または 前の 1記事へのリンクを出力する next_post_link() と previous_post_link() しかないため、自前で実装することにしました。こんな感じです。

How to Add Multiple Newer Older Posts Link in Single Post

実は、複数の前後記事を表示するのは SEO 対策の意味合いが大きいです。いわゆる内部リンクの整備です。

一つの記事がクロールされたときに、ナビゲーションとして複数の前後記事へのリンクを表示することで、クローラーの巡回を促すわけです。記事ページがクロールされなければ、ページの評価が上がることもありません。SEO 的には極めて重要な施策だと思います。

(参考)

複数の前後記事を出力する PHP コード

早速ですが PHP コードです。

尚、WordPress の多言語化プラグインである Bogo に対応しています。具体的には、表示中の記事と同じ言語の前後記事のみを出力します。

プラグインをお探しですか?
それならば「wordpress 関連記事 プラグイン」で検索がオススメです。内部リンクの整備ならば前後の記事である必要はありません。

single.php のループ内に追加することを想定しています。

<?php
$max_posts = 10; // 偶数で指定 出力する前後記事の合計件数

$post_date = getdate( get_the_date('U') );
$date_arg = array(
	'year' => $post_date['year'],
	'month' => $post_date['mon'],
	'day' => $post_date['mday'],
);

$newer_posts = get_posts(
	array(
		'numberposts' => $max_posts,
		'order' => 'ASC',
		'date_query' => array( array(
			'after' => $date_arg,
			'inclusive' => false,
		) ),
		'suppress_filters' => false // Bogo 対応 不要ならば削除
	)
);
$older_posts = get_posts(
	array(
		'numberposts' => $max_posts,
		'date_query' => array( array(
			'before' => $date_arg,
			'inclusive' => false,
		) ),
		'suppress_filters' => false // Bogo 対応 不要ならば削除
	)
);
$all = count( $newer_posts ) + count( $older_posts );
$max_posts = ( $all < $max_posts ) ? $all : $max_posts;

$html_newer = ''; $newer = 0;
$html_older = ''; $older = 0;
while ( ($newer + $older) < $max_posts ) {
	if ( $newer_posts[$newer] ) {
		$p = $newer_posts[$newer++];
		$html_newer = '<li><a href="' . get_permalink( $p->ID ) . '">' . $p->post_title . '</a></li>' . $html_newer;
	}
	if ( $older_posts[$older] ) {
		$p = $older_posts[$older++];
		$html_older = $html_older . '<li><a href="' . get_permalink( $p->ID ) . '">' . $p->post_title . '</a></li>';
	}
}
?>

<nav>
<?php
if ( $newer > 0 ) : ?>
	<ul class="newerPosts">
		<?php echo $html_newer; ?>
	</ul>
<?php endif; ?>

	<div class="currentPost"><?php the_title() ?></div>

<?php
if ( $older > 0 ) : ?>
	<ul class="olderPosts">
		<?php echo $html_older; ?>
	</ul>
<?php endif; ?>
</nav>

制限事項と動作仕様

制限事項

日付で前後の判定をしているため、同じ日付で複数の記事を公開している場合には非対応です。若干の改修を加える必要があると思います。

WordPress 3.7以降対応です(それより古いバージョンでは WP_Query が日付パラメータに対応していません)。

動作仕様

$max_posts を 10 に指定した場合、以下の条件に従って前後記事へのリンク(アンカー テキストは記事タイトル)が出力されます。

  • 基本的には新しい記事 5件 古い記事 5件が表示される
  • 例えば 表示中の記事より新しい記事が 3件しかなかった場合は 新しい記事 3件 古い記事 7件が表示される
  • 記事総数が 10 に満たない場合は すべての記事が表示される

実際に出力される HTML は 49行目~最後になります。新しい記事リスト(ul class=”newerPosts”)、現在の記事(div class=”currentPost”)、古い記事リスト(ul class=”olderPosts”)です。ul 要素内の li 要素は 40行目と 44行目で生成しています。このあたりをカスタマイズし、スタイルシートを組み合わせれば柔軟なデザインが可能だと思います。

関連ページ

プチ解説

ポイントは、14行目の「’order’ => ‘ASC’」でしょうか。date_query で after を指定する場合には order を ASC にしないと意図した結果を得られません。わりとハマりました。この関係で $newer_posts は古い順で取得されるため、40行目の HTML 生成で逆順にしています。

同じカテゴリの前後記事のみ表示したい場合

get_posts() の取得条件(11~31行目)に category_name または category__in 等を追加すれば可能です。カテゴリ情報は get_the_category() で取得できます。

どなたかのお役に立つことを願いつつ また次回。

コメントを残す

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