LoginSignup
1
5

More than 5 years have passed since last update.

[WordPress]記事ページに同カテゴリーのページネーションを設置する方法

Last updated at Posted at 2017-05-09

WordPressを利用する際、カテゴリーページやアーカイブページではページネーションを利用すると思いますが、記事ページ(single.php)にもページネーションを設置したいという依頼がありました。
あまり需要は無いと思いますが、 同一カテゴリーに所属する記事へのページネーションの設置方法を記録しておきます。

仕様

  • 検証バージョン:WordPress 4.7.4
  • 記事は 一つのカテゴリーにのみ所属(複数カテゴリーに適用する場合はforeach等でアレンジしてください)

コード

single.phpに記述するコード

ページネーションを設置する箇所に以下のコードを記入し、3行目の
$pagination = 5;
の数字を、任意の数に書き換えてください。(※半角数字)
ページネーション表示イメージ

single.php
<ul class="pagination">
<?php
$pagination = 5;    // 1ページに表示するページ送りの最大数

$cat = get_the_category();
$cat = $cat[0];
$catname = get_cat_name($cat->term_id);     // カテゴリー名を取得
$catid = get_cat_ID($catname);              // カテゴリーIDを取得

$post_id = get_the_ID();    // 現在の投稿IDを取得
$post_id_array = array();   // 取得したくない投稿情報ID(複数指定する場合は,で区切る)

// 投稿記事のカテゴリ内で新着から何番目かを確認
$args = array( 'posts_per_page' => -1, 'category' => $catid, 'exclude' => $post_id_array );
$posts = get_posts( $args );
$posts_ids = array();

foreach ( $posts as $post ) {
    $posts_ids[] += $post->ID;
}

$post_current = array_search($post_id, $posts_ids);     // 現在の記事番号(順番)を取得
$post_last = count($posts_ids);                         // 同じカテゴリー内の記事数
$post_last_group = $post_last - $pagination;            // 最後尾のページ送りグループ
$post_last_switch = $post_last - ($pagination - 1);     // 最後の5つに切り替えるする記事番号

// 最大値が1〜4まで前後のリンク数が異なる
switch ($pagination) {
    case 1:
        $post_prev = $post_current;
        $post_next = $post_current + 1;
        break;

    case 2:
        $post_prev = $post_current;
        $post_next = $post_current + 2;
        break;

    case 3:
        $post_prev = $post_current - 1;
        $post_next = $post_current + 2;
        break;

    case 4:
        $post_prev = $post_current - 1;
        $post_next = $post_current + 3;
        break;

    default:
        $post_prev = $post_current - 2;
        $post_next = $post_current + 3;
        break;
}

wp_reset_postdata();

// 「次へ(新しい記事へ)」リンクの設定
if ($post_last >= $pagination && $post_current > ($pagination - 2)) {
    if ($pagination != $post_last) {
        echo '<li><a href="'.get_permalink($posts_ids[0]).'">&laquo;&nbsp;最新</li>';
        next_post_link('<li>%link</li>','&laquo;&nbsp;次へ',true);
    }
}

// 記事数が最大数以上ある場合
// 例)最大数が5個で、記事が5個以上ある場合
if($post_last >= $pagination) {
    if ($post_current < ($pagination - 1)) {
        $is_first = true;

        for ($i=0; $i < $pagination; $i++) {
            if ($i == $post_current) {
                // 現在のページ
                echo '<li class="active"><a href="#">'.($i+1).'</a></li>';
            } else {
                // その他のページ
                echo '<li><a href="'.get_permalink($posts_ids[$i]).'">'.($i+1).'</a></li>';
            }
        }
    } else if ($post_current >= $post_last_switch) {
        $is_last = true;

        for ($i=$post_last_group; $i < $post_last; $i++) {
            if ($i == $post_current) {
                // 現在のページ
                echo '<li class="active"><a href="#">'.($i+1).'</a></li>';
            } else {
                // その他のページ
                echo '<li><a href="'.get_permalink($posts_ids[$i]).'">'.($i+1).'</a></li>';
            }
        }
    } else {
        for ($i=$post_prev; $i < $post_next; $i++) {
            if ($i == $post_current) {
                // 現在のページ
                echo '<li class="active"><a href="#">'.($i+1).'</a></li>';
            } else {
                // その他のページ
                echo '<li><a href="'.get_permalink($posts_ids[$i]).'">'.($i+1).'</a></li>';
            }
        }
    }
} // ここまで / 記事数が最大数以上ある場合

// 記事数が最大数未満の場合
else {
    for ($i=0; $i < $post_last; $i++) {
        if ($i == $post_current) {
                // 現在のページ
            echo '<li class="active"><a href="#">'.($i+1).'</a></li>';
        } else {
                // その他のページ
            echo '<li><a href="'.get_permalink($posts_ids[$i]).'">'.($i+1).'</a></li>';
        }
    }
} // ここまで / 記事数が最大数未満の場合

// 「前へ(古い記事へ)」リンクの設定
if ($post_last >= $pagination && $is_last == false && $post_next <= $post_last && $pagination != $post_last) {
    if ($pagination == 2 && $post_current != ($post_last - 2)) {
        previous_post_link('<li>%link</li>','前へ&nbsp;&raquo;',true);
        echo '<li><a href="'.get_permalink(end($posts_ids)).'">最古&nbsp;&raquo;</li>';
    } else if($pagination != 2) {
        previous_post_link('<li>%link</li>','前へ&nbsp;&raquo;',true);
        echo '<li><a href="'.get_permalink(end($posts_ids)).'">最古&nbsp;&raquo;</li>';
    }
}
?>
</ul>

サンプルでは<ul>タグを使用しており、現在のページに該当する<li>タグにactiveというclassを付与しています。
なお、サンプルはBootstrapのページネーション用cssを使用しています。

出力されるHTML例

<ul class="pagination">
    <li><a href="/post1">«&nbsp;最新</a></li>
    <li><a href="/post4" rel="next">«&nbsp;次へ</a></li>
    <li><a href="/post3">3</a></li>
    <li><a href="/post4">4</a></li>
    <li class="active"><a href="#">5</a></li>
    <li><a href="/post6">6</a></li>
    <li><a href="/post7">7</a></li>
    <li><a href="/post6" rel="prev">前へ&nbsp;»</a></li>
    <li><a href="/post10">最古&nbsp;»</a></li>
</ul>

動作

基本は現在の記事を中心に、

  • 設定した記事数分の前後記事へのリンク
  • 番号リンクとは別に直前・直後記事へのリンク
  • 左右端に最新・最古記事へのリンク

が表示されます。
ページネーション表示イメージ

最新から5個目(設定した記事数)までの記事にいる場合は「最新」「次へ」リンクは表示されません。
最新から設定した記事数までの表示イメージ

同じく最古から5個目までの記事にいる場合は「最古」「前へ」リンクは表示されません。
最古から設定した記事数までの表示イメージ

カテゴリー内の記事数が設定した記事数より少ない場合は、前後と最新・最古のリンクは表示されません。
設定した記事数より少ない場合の表示イメージ

以上になります。

必要な機能は取り揃えていると思います。


下記のページを参考にさせていただきました。ありがとうございます。

▼WordPressで、投稿記事と同じカテゴリー内の前後数件の記事を一覧出力する
https://hack-le.com/wplistcatzengo/

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5