WordPressを利用する際、カテゴリーページやアーカイブページではページネーションを利用すると思いますが、記事ページ(single.php)にもページネーションを設置したいという依頼がありました。
あまり需要は無いと思いますが、 同一カテゴリーに所属する記事へのページネーションの設置方法を記録しておきます。
仕様
- 検証バージョン:WordPress 4.7.4
- 記事は 一つのカテゴリーにのみ所属(複数カテゴリーに適用する場合はforeach等でアレンジしてください)
コード
single.phpに記述するコード
ページネーションを設置する箇所に以下のコードを記入し、3行目の
$pagination = 5;
の数字を、任意の数に書き換えてください。(※半角数字)
<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]).'">« 最新</li>';
next_post_link('<li>%link</li>','« 次へ',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>','前へ »',true);
echo '<li><a href="'.get_permalink(end($posts_ids)).'">最古 »</li>';
} else if($pagination != 2) {
previous_post_link('<li>%link</li>','前へ »',true);
echo '<li><a href="'.get_permalink(end($posts_ids)).'">最古 »</li>';
}
}
?>
</ul>
サンプルでは<ul>
タグを使用しており、現在のページに該当する<li>
タグにactive
というclassを付与しています。
なお、サンプルはBootstrapのページネーション用cssを使用しています。
出力されるHTML例
<ul class="pagination">
<li><a href="/post1">« 最新</a></li>
<li><a href="/post4" rel="next">« 次へ</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">前へ »</a></li>
<li><a href="/post10">最古 »</a></li>
</ul>
動作
基本は現在の記事を中心に、
- 設定した記事数分の前後記事へのリンク
- 番号リンクとは別に直前・直後記事へのリンク
- 左右端に最新・最古記事へのリンク
最新から5個目(設定した記事数)までの記事にいる場合は「最新」「次へ」リンクは表示されません。
同じく最古から5個目までの記事にいる場合は「最古」「前へ」リンクは表示されません。
カテゴリー内の記事数が設定した記事数より少ない場合は、前後と最新・最古のリンクは表示されません。
以上になります。
必要な機能は取り揃えていると思います。
下記のページを参考にさせていただきました。ありがとうございます。
▼WordPressで、投稿記事と同じカテゴリー内の前後数件の記事を一覧出力する
https://hack-le.com/wplistcatzengo/