WordPressの投稿ページには「次の投稿」「前の投稿」へ移動できるリンク機能が最初から用意されています。ただ、この標準の挙動は投稿日順にたどるだけで、カテゴリをまたいで前後の記事へリンクしてしまいます。
ブログの構成によっては、それだと読者を戸惑わせてしまうことがあります。技術系の記事を読んでいたのに、次の記事がまったく関係ない雑記だった、という経験は私にもありました。読み進めてもらうなら、同じカテゴリの記事へつなげたほうが親切です。ここでは前後の記事リンクを同じカテゴリ(タクソノミー)に絞る方法を、現行のWordPressの仕様に沿って整理します。
前後の記事リンクを同一カテゴリに絞る基本
まず、前後の記事リンクを表示する基本のコードはこちらです。
<?php previous_post_link( '« %link', '%title' ); // 前の投稿へのリンク ?>
<?php next_post_link( '%link »', '%title' ); // 次の投稿へのリンク ?>
第1引数がリンクの表示フォーマットで、%linkの位置にaタグのリンクが入ります。第2引数がリンク文字列のフォーマットで、%titleとすると記事タイトルが表示されます。
同じカテゴリ内だけでリンクさせたいときは、第3引数($in_same_term)にtrueを渡します。ここはデフォルトがfalseなので、明示的にtrueにするのがポイントです。
<?php previous_post_link( '« %link', '%title', true ); ?>
<?php next_post_link( '%link »', '%title', true ); ?>
これだけで、いま表示している記事と同じカテゴリに属する前後の記事へリンクが絞られます。
特定のカテゴリを対象から外す
特定のカテゴリの記事をリンク対象から除きたい場合は、第4引数($excluded_terms)に除外したいカテゴリのIDを渡します。カンマ区切りの文字列、または配列で複数指定できます。
<?php // カンマ区切りの文字列で指定 ?>
<?php previous_post_link( '« %link', '%title', true, '1,2' ); ?>
<?php next_post_link( '%link »', '%title', true, '1,2' ); ?>
<?php // 配列で指定してもOK ?>
<?php next_post_link( '%link »', '%title', true, array( 1, 2 ) ); ?>
古い記事だと除外IDをandでつなぐ書き方を見かけますが、現在の公式リファレンスではカンマ区切りか配列が案内されています。新しく書くならこちらに合わせておくと安心です。
カスタムタクソノミーで絞り込む
カスタム投稿タイプで独自の分類(カスタムタクソノミー)を使っている場合は、第5引数($taxonomy)にタクソノミー名を渡します。この引数のデフォルトは'category'なので、標準カテゴリ以外で絞るときは必ず指定します。
<?php previous_post_link( '« %link', '%title', true, '', 'タクソノミー名' ); ?>
<?php next_post_link( '%link »', '%title', true, '', 'タクソノミー名' ); ?>
タクソノミー名は、テーマのfunctions.phpにあるregister_taxonomy()の記述で確認できます。第1引数に書かれている文字列がタクソノミー名です。
ちなみにnext_post_link()の現行のシグネチャは次のようになっています。並び順を押さえておくと引数の抜け漏れを防げます。
next_post_link( string $format = '%link »', string $link = '%title', bool $in_same_term = false, int[]|string $excluded_terms = '', string $taxonomy = 'category' )
リンクだけでなく投稿データも扱いたいときは get_adjacent_post()
テンプレート内でもっと自由にレイアウトしたい、サムネイルや抜粋も出したい、という場合はget_adjacent_post()が便利です。こちらはaタグではなく前後の投稿オブジェクト(WP_Post)そのものを返してくれます。
引数の順番がprevious_post_link()系とは違うので注意が必要です。get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy )の順で、第3引数の$previousをtrueにすると前の投稿、falseにすると次の投稿を取得します。
<?php
// 同じカスタムタクソノミー内の「前の投稿」を取得
$prev = get_adjacent_post( true, '', true, 'タクソノミー名' );
if ( $prev ) {
echo '<a href="' . esc_url( get_permalink( $prev->ID ) ) . '">';
echo esc_html( get_the_title( $prev->ID ) );
echo '</a>';
}
?>
該当する投稿がなければ空文字が返り、グローバルの$postがセットされていない場合はnullが返ります。表示前に取得結果をチェックしておくと、リンク切れやエラーを避けられます。
まとめ
ポイントを整理します。previous_post_link()とnext_post_link()は、第3引数をtrueにするだけで同一カテゴリに絞れます。カスタムタクソノミーで絞るなら第5引数にタクソノミー名を指定し、除外したい分類があれば第4引数にIDをカンマ区切りか配列で渡します。より細かく作り込みたいときは、投稿オブジェクトを返すget_adjacent_post()に切り替えると自由度が上がります。読者が同じテーマの記事をたどりやすくなるので、回遊性を高めたい方はぜひ設定してみてください。