投稿の“前の投稿”と“次の投稿”へのページ送りをカスタマイズする方法【WordPress】

毎回作業でハマるので、備忘録として記しておきます。

WordPressの個別記事(個別投稿)ページの下部に前後の投稿へのナビゲーションを設置する方法です。

「previous_post_link()」と「next_post_link()」では対応できないアイキャッチ画像の表示なども含めた方法です。

設定方法

前後の投稿の取得

まずはループ『while( have_posts() ):』内で、前の投稿の情報を「get_previous_post()」で、次の投稿の情報を「get_next_post()」でそれぞれ取得して変数にセットします。
そのとき、前後の投稿の案内を表示中の投稿と同じカテゴリー内に絞り込む場合は、()内に“true”をセットしておきます。

$previous_post = get_previous_post(true);
$next_post = get_next_post(true);

前後の投稿のID取得を追記

次に、前後それぞれの投稿IDを取得を追記します。

$previous_post = get_previous_post(true);
$previous_id = $previous_post->ID;
$next_post = get_next_post(true);
$next_id = $next_post->ID;

前後の投稿の公開日時取得も追記

各日付も表示する場合は「mysql2date」を使って必要な形で日付情報を取得し変数にセットして追記します。
(下記サンプルでは日付は「2020.01.22」のようなかたちになります)

$previous_post = get_previous_post(true);
$previous_id = $previous_post->ID;
$previous_date = mysql2date('Y.m.d', $previous_post->post_date);
$next_post = get_next_post(true);
$next_id = $next_post->ID;
$next_date = mysql2date('Y.m.d', $next_post->post_date);

ここまでで基本的な部分は完成です。
あとは上記設定で取得した前後の投稿のIDを上手く使って下記のような情報の配置をしていきます。

前後各リンクURL

<?php the_permalink( $previous_id ); ?>
<?php the_permalink( $next_id ); ?>

前後各タイトル

<?php echo get_the_title( $previous_id ); ?>
<?php echo get_the_title( $next_id ); ?>

アイキャッチ画像も表示させる方法

アイキャッチ画像をサムネイルサイズで表示させる場合は、サイズのしてもセットしておきます。

$size = 'thumbnail';

任意のサイズをセットする場合は、あらかじめ『functions.php』に「add_image_size($サイズ名, $幅, $高さ, $サイズでのトリミング true又はfalse)」を設定し、上記ソースの「thumbnail」をadd_image_sizeのサイズ名にします。

アイキャッチ画像を表示させる際は、アイキャッチの有無での条件分岐の中で画像を表示させるようにします。

<?php
$size = 'thumbnail';
if( has_post_thumbnail( $previous_id ) { echo get_the_post_thumbnail( $previous_id, $size ); }
if( has_post_thumbnail( $next_id ) { echo get_the_post_thumbnail( $next_id, $size ); }
?>

前後各投稿中の最初の画像をサムネイルとして表示させる方法

アイキャッチ画像の登録が無い場合“No Image”では少し味気ないので、前後それぞれ投稿中の最初の画像をサムネイルとして表示させるという悪あがきの方法も追記しておきます。

まず、テーマのための関数「functions.php」に前後各投稿の最初の画像を取得するための関数を下記のように作成します。
(画像のサイズは、上記「アイキャッチ画像も設定させる方法」のサイズ設定と同じとなります)

/* 一つ前の投稿の本文中に挿入されている最初の画像を抽出してattachment情報を取得する方法
*************************************************************************************/
function prev_thumbnail_image() {
    global $post;
	$image = '';
	$get_size = 'thumbnail';
	$prev_post = get_previous_post(true);
	$image_get = preg_match_all('/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $prev_post->post_content, $matches);
	$image_id = $matches[1][0];
	$image = wp_get_attachment_image( $image_id, $get_size, false, array(
		'class' => 'thumbnail-image',
		'srcset' => wp_get_attachment_image_srcset( $image_id, $get_size ),
		'sizes' => wp_get_attachment_image_sizes( $image_id, $get_size )
	));
	if( empty( $image ) ) {
		$image = '';
	}
	return $image;
}

/* 一つ後の投稿の本文中に挿入されている最初の画像を抽出してattachment情報を取得する方法
*************************************************************************************/
function next_thumbnail_image() {
    global $post;
	$image = '';
	$get_size = 'thumbnail';
	$next_post = get_next_post(true);
	$image_get = preg_match_all('/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $next_post->post_content, $matches);
	$image_id = $matches[1][0];
	$image = wp_get_attachment_image( $image_id, $get_size, false, array(
		'class' => 'thumbnail-image',
		'srcset' => wp_get_attachment_image_srcset( $image_id, $get_size ),
		'sizes' => wp_get_attachment_image_sizes( $image_id, $get_size )
	));
	if( empty( $image ) ) {
		$image = '';
	}
	return $image;
}

これで前の投稿の最初の画像を

<?php echo prev_thumbnail_image(); ?>

後の投稿の最初の画像を

<?php echo next_thumbnail_image(); ?>

でそれぞれ表示させることができます。

ちなみにカスタム投稿でも使えるようにするには、投稿のIDを「get_adjacent_post()」で取得するようにします。

get_adjacent_post('タクソミー制限(初期値:false)', '除外するカテゴリID', '前の投稿はtrue(初期値)、後の投稿はfalse', 'タクソミー制限がある場合のタクソミー名')

カスタム投稿でも使えるように下ソースが下記になります。
functions.phpに追記します。

/* 一つ前の投稿の本文中に挿入されている最初の画像を抽出してattachment情報を取得する方法
*************************************************************************************/
function prev_thumbnail_image() {
    global $post;
	$image = '';
	$get_size = 'thumbnail';
	$prev_post = get_previous_post(true);
	if(is_post_type_archive('カスタム投稿のスラッグ名') || (get_post_type() === 'カスタム投稿のスラッグ名' && is_single())) {
		$prev_post = get_adjacent_post(false, '1');
		$prev_id = $prev_post->ID;
	}
	$image_get = preg_match_all('/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $prev_post->post_content, $matches);
	$image_id = $matches[1][0];
	$image = wp_get_attachment_image( $image_id, $get_size, false, array(
		'class' => 'thumbnail-image',   //レイアウト調整のために画像にクラスを設置
		'srcset' => wp_get_attachment_image_srcset( $image_id, $get_size ),   //高解像度対応
		'sizes' => wp_get_attachment_image_sizes( $image_id, $get_size )
	));
	if( empty( $image ) ) {
		$image = '';
	}
	return $image;
}

/* 一つ後の投稿の本文中に挿入されている最初の画像を抽出してattachment情報を取得する方法
*************************************************************************************/
function next_thumbnail_image() {
    global $post;
	$image = '';
	$get_size = 'thumbnail';
	$next_post = get_next_post(true);
	if(is_post_type_archive('カスタム投稿のスラッグ名') || (get_post_type() === 'カスタム投稿のスラッグ名' && is_single())) {
		$next_post = get_adjacent_post(false, '1', false);
		$next_id = $next_post->ID;
	}
	$image_get = preg_match_all('/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $next_post->post_content, $matches);
	$image_id = $matches[1][0];
	$image = wp_get_attachment_image( $image_id, $get_size, false, array(
		'class' => 'thumbnail-image',   //レイアウト調整のために画像にクラスを設置
		'srcset' => wp_get_attachment_image_srcset( $image_id, $get_size ),   //高解像度対応
		'sizes' => wp_get_attachment_image_sizes( $image_id, $get_size )
	));
	if( empty( $image ) ) {
		$image = '';
	}
	return $image;
}

完成形

以上を踏まえ、
single.php側の処理として

  • 前後の投稿を取得し、そこから各投稿のID、投稿日を取得
  • 前後の投稿の有無での条件分岐
  • アイキャッチ画像の表示
  • アイキャッチ画像がないときの投稿の最初の画像のサムネイル表記
  • アイキャッチ画像も投稿内にも画像が無い時の表記

の内容のソースサンプルです。

<?php
	$previous_post = get_previous_post(true);
	$previous_id = $previous_post->ID;
	$previous_date = mysql2date('Y.m.d', $previous_post->post_date);
	$next_post = get_next_post(true);
	$next_id = $next_post->ID;
	$next_date = mysql2date('Y.m.d', $next_post->post_date);
	$catch_thumbnail_size = 'thumbnail';
?>
<ul class="post-prev-next">
	<li class="is-prev">
		<h3 class="link-title"><span>前の記事</span></h3>
		<?php if( $previous_post ): ?>
			<a class="trans" href="<?php the_permalink( $previous_id ); ?>">
			<?php
				if( has_post_thumbnail( $previous_id ) ):
					echo '<figure class="item-img">'.get_the_post_thumbnail( $previous_id, $catch_thumbnail_size ).'</figure>';
				elseif( prev_thumbnail_image() ):
			?>
					<figure class="item-img"><?php echo prev_thumbnail_image(); ?></figure>
				<?php endif; ?>
				<div class="item-content">
					<h3 class="item-title"><?php echo get_the_title( $previous_id ); ?></h3>
					<time class="item-time" datetime="<?php echo $previous_date; ?>"><?php echo $previous_date; ?></time>
				</div>
			</a>
		<?php else: ?>
			<div class="trans">
				<div class="item-content">
					<h3 class="item-title">これ以前の記事はありません</h3>
				</div>
			</div>
		<?php endif; ?>
	</li>
	<li class="is-next">
		<h3 class="link-title"><span>次の記事</span></h3>
		<?php if( $next_post ): ?>
			<a class="trans" href="<?php the_permalink( $next_id ); ?>">
			<?php
				if(has_post_thumbnail( $next_id )):
					echo '<figure class="item-img">'.get_the_post_thumbnail( $next_id, $catch_thumbnail_size ).'</figure>';
				elseif( next_thumbnail_image() ):
			?>
					<figure class="item-img"><?php echo next_thumbnail_image(); ?></figure>
				<?php endif; ?>
				<div class="item-content">
					<h3 class="item-title"><?php echo get_the_title( $next_id ); ?></h3>
					<time class="item-time" datetime="<?php echo $next_datetime; ?>"><?php echo $next_date; ?></time>
				</div>
			</a>
		<?php else: ?>
			<div class="trans">
				<div class="item-content">
					<h3 class="item-title">これ以上新しい記事はありません</h3>
				</div>
			</div>
		<?php endif; ?>
	</li>
</ul>
/* 一つ前の投稿の本文中に挿入されている最初の画像を抽出してattachment情報を取得する方法
*************************************************************************************/
function prev_thumbnail_image() {
    global $post;
	$image = '';
	$get_size = 'thumbnail';
	$prev_post = get_previous_post(true);
	if(is_post_type_archive('カスタム投稿のスラッグ名') || (get_post_type() === 'カスタム投稿のスラッグ名' && is_single())) {
		$prev_post = get_adjacent_post(false, '1');
		$prev_id = $prev_post->ID;
	}
	$image_get = preg_match_all('/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $prev_post->post_content, $matches);
	$image_id = $matches[1][0];
	$image = wp_get_attachment_image( $image_id, $get_size, false, array(
		'class' => 'thumbnail-image',   //レイアウト調整のために画像にクラスを設置
		'srcset' => wp_get_attachment_image_srcset( $image_id, $get_size ),   //高解像度対応
		'sizes' => wp_get_attachment_image_sizes( $image_id, $get_size )
	));
	if( empty( $image ) ) {
		$image = '';
	}
	return $image;
}

/* 一つ後の投稿の本文中に挿入されている最初の画像を抽出してattachment情報を取得する方法
*************************************************************************************/
function next_thumbnail_image() {
    global $post;
	$image = '';
	$get_size = 'thumbnail';
	$next_post = get_next_post(true);
	if(is_post_type_archive('カスタム投稿のスラッグ名') || (get_post_type() === 'カスタム投稿のスラッグ名' && is_single())) {
		$next_post = get_adjacent_post(false, '1', false);
		$next_id = $next_post->ID;
	}
	$image_get = preg_match_all('/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $next_post->post_content, $matches);
	$image_id = $matches[1][0];
	$image = wp_get_attachment_image( $image_id, $get_size, false, array(
		'class' => 'thumbnail-image',   //レイアウト調整のために画像にクラスを設置
		'srcset' => wp_get_attachment_image_srcset( $image_id, $get_size ),   //高解像度対応
		'sizes' => wp_get_attachment_image_sizes( $image_id, $get_size )
	));
	if( empty( $image ) ) {
		$image = '';
	}
	return $image;
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です