KEPRATE(ケプレイト)|大阪府枚方市・交野市・寝屋川市を中心に活動しているフリーランスWeb制作事務所 WordPress・レスポンシブ対応ならおまかせ!

WordPressでレスポンシブ対応のページネーション(ページ送り)をプラグインなしで実装

2018/05/18
Category :
  1. WordPress
Tags :
  1. レスポンシブ
  2. 自作

WordPressでページネーション(ページ送り)を表示するにはプラグイン(WP-PageNaviというのが有名)を使用すると簡単に実現出来ます。
ですがプラグインを使用するのは

  1. ページネーションのオリジナルを自作できればWordPressに限らずAjaxなページでも同じ考え方で簡単に実装できる。
    (色々なものにいかせるという事)
  2. 細かい仕様調節も楽勝。(レスポンシブ対応、プルダウンメニュー化など)
  3. WordPressのバージョンアップデートの際も心配がなくなる。裏でどのようにして動作しているのか把握したいので個人的に自作可能なら自作したい。

上記の理由からプラグインを使用するのはやめてfunction.phpに一つ関数を用意するだけで割と簡単に自作出来そうだったので自作した際のメモ。

呼び方としてページネーション・ページング・ページャーがありますがどれが正解なのだろう・・・
個人的にはページャーが短くてキリッとしていて好みなのですがプラグインで使われている名前はページネーションが多そうなのでページネーションとしておきます。

流れとしてはfunction.phpにページネーションを表示するための関数を追加して出力したい記事一覧ページテンプレートにコード追加。最後にcssで見た目の確認・調節。

下記が今回作成するページネーションの完成図。
必要になりそうなパーツはあらかじめ全て出力していて不必要なパーツはcssで非表示に。
ページ数が膨大になるとページ送りに・・・的なものが欲しくなるかもしれないが現状は実装していない。
先頭へ・最後へもページ数が少ない時はcssで非表示に。

【PC】
【スマホ】
  1. テスト用に表示投稿数は2件の設定です。

WordPressの設定で表示投稿数をきめる

1ページにつき何件分の投稿を表示をするかを決める。
この表示投稿数がおかしいと正しいページ数が取得できないので結構重要。

WordPressの管理画面で
設定 > 表示設定 に移動して1ページに表示する最大投稿数の数値を変更する。
(下図赤枠箇所)

上記の方法でも問題はないのですが全てのテンプレートが同じ仕様(数値)になってしまい
あまり推奨しないような記述を読んだ記憶もあり最近はfunction.php上で表示投稿数の設定している。
下記が記述内容。

function change_posts_per_page($query) {

    //管理画面やメインクエリに干渉しないために必須
     if( is_admin() || ! $query->is_main_query() ){
         return;
     }

    //検索ページ
    if ( $query->is_search() ) {
        $query->set( 'posts_per_page', '8' );
        return;
    }

    //カテゴリーページ
    if ( $query->is_category() ) {
        $query->set( 'posts_per_page', '10' );
        return;
    }
}

add_action( 'pre_get_posts', 'change_posts_per_page' );

各テンプレート、個別に表示投稿数を変更する事が実現できます。
上記設定だと検索ページは8件
カテゴリーページは10件
となります。
んーマンダム。
下記サイトがナイスな感じで詳しくまとめらております。

[WordPress]pre_get_postsを使いこなす!pre_get_posts使い方まとめ

function.phpにオリジナル関数を追加

今回のページネーションの仕様は下記の感じ。

  1. レスポンシブ対応
  2. ボタン形式

function.php内にオリジナルの関数get_responsive_pagination()を追加。

function get_responsive_pagination($_pagination_range_pc,$_pagination_range_sp){

    global $wp_query;

    $total_posts_num = $wp_query->found_posts;

    //記事数が0の場合終了
    if ($total_posts_num == 0) return;

    //1ページに表示する範囲
    $page_range = get_query_var('posts_per_page');

    //合計ページ数
    $total_page_num = ceil($total_posts_num/$page_range);

    //現在のページを取得
    $index_page_num = get_query_var('paged') ? get_query_var('paged') :1 ;

    //開始件数を取得
    $from = $page_range * ($index_page_num - 1 ) + 1;

    //終了件数を取得
    $to = $page_range * $index_page_num;

    //開始件数から終了件数
    $from_to = '';

    //合計該当記事数が終了件数より小さい場合、終了件数に設定
    if($total_posts_num <= $to)$to = $total_posts_num;

    if($total_posts_num == 1 ){
        $from_to = $from;
    }else{
        $from_to = $from.'〜'.$to;
    }

    if($from == $to)$from_to = $from;

    /* PC */
    $pagination_range = $_pagination_range_pc;
    //ページャー範囲が合計ページ数より多い場合
    if ($pagination_range >= $total_page_num) $pagination_range = $total_page_num;
    $pagination_offset = floor($pagination_range / 2);
    $pagination_from_limit = $total_page_num - $pagination_range + 1;
    $offset_from = $index_page_num - $pagination_offset;
    if ($offset_from <= 1) $offset_from = 1;
    if ($offset_from >= $pagination_from_limit) $offset_from = $pagination_from_limit;
    $offset_to = $offset_from + $pagination_range;

    /* SP */
    $pagination_range_sp = $_pagination_range_sp;
    //ページャー範囲が合計ページ数より多い場合
    if ($pagination_range_sp >= $total_page_num) $pagination_range_sp = $total_page_num;
    $pagination_offset_sp = floor($pagination_range_sp / 2);
    $pagination_from_limit_sp = $total_page_num - $pagination_range_sp + 1;
    $offset_from_sp = $index_page_num - $pagination_offset_sp;
    if ($offset_from_sp <= 1) $offset_from_sp = 1;
    if ($offset_from_sp >= $pagination_from_limit_sp) $offset_from_sp = $pagination_from_limit_sp;
    $offset_to_sp = $offset_from_sp + $pagination_range_sp;

    $add_class = '';
    $source = '';
    if($total_page_num > $_pagination_range_sp + 2 ) $add_class .= ' pagination-range-over-sp';
    if($total_page_num > $_pagination_range_pc + 2 ) $add_class .= ' pagination-range-over-pc';
    $source .= '<nav class="cms-pagination'.$add_class.'">'."\n";
    $source .= '<ul class="clearfix">'."\n";

    //prev first
    if($index_page_num != 1 ) {
        $source .= '<li class="pagination-no-num first"><a href="'.get_pagenum_link(1).'">先頭へ</a></li>'."\n";
        $source .= '<li class="pagination-no-num prev"><a href="'.get_pagenum_link($index_page_num - 1).'">前へ</a></li>'."\n";
    }else{
        $source .= '<li class="pagination-no-num first"><span>先頭へ</span></li>'."\n";
        $source .= '<li class="pagination-no-num prev"><span>前へ</span></li>'."\n";
    }

    for ($i=$offset_from; $i < $offset_to; $i++){
        if($index_page_num == $i){
            if($i>=$offset_from_sp && $i<$offset_to_sp){
                $source .= '<li class="pagination-index pagination-sp"><span>'.$i.'</span></li>'."\n";
            }else{
                $source .= '<li class="pagination-index"><span>'.$i.'</span></li>'."\n";
            }
        }else{
            if($i>=$offset_from_sp && $i<$offset_to_sp){
                $source .= '<li class="pagination-sp"><a href="'.get_pagenum_link($i).'">'.$i.'</a></li>'."\n";
            }else{
                $source .= '<li><a href="'.get_pagenum_link($i).'">'.$i.'</a></li>'."\n";
            }
        }
    }

    //next last
    if($index_page_num != $total_page_num) {
        $source .= '<li class="pagination-no-num next"><a href="'.get_pagenum_link($index_page_num + 1).'">次へ</a></li>'."\n";
        $source .= '<li class="pagination-no-num last"><a href="'.get_pagenum_link($total_page_num).'">最後へ</a></li>'."\n";
    }else{
        $source .= '<li class="pagination-no-num next"><span>次へ</span></li>'."\n";
        $source .= '<li class="pagination-no-num last"><span>最後へ</span></li>'."\n";
    }

    $source .= '</ul>'."\n";
    $source .= '</nav>'."\n";
    $source .= '<div class="pagination-txt">'.$from_to.'<span> / '.$total_posts_num.'件</div>'."\n";

    echo $source;

}

解説

  1. 1行目:
    引数に【$_pager_range_pc】PC用ボタン出力数字範囲、【$_pager_range_sp】スマホ用ボタン出力数字範囲を指定。
  2. 3行目〜37行目:
    出力に必要な値を取得。ごにょごにょ。
  3. 39行目〜59行目:
    ボタンの出力数字範囲に応じての必要な数字が表示されるように調節。ごにょごにょ。
  4. 61行目〜:
    出力開始

ページネーションの細かい作り方を説明しているととてもとても時間がかかってしまう・・・ガッテム。
いつの日か機会があれば図入りで解説してみたい。
今回はあくまでWordPressにオリジナルのレスポンシブ対応のページネーション実装方法に限定。

記事一覧ページテンプレートにコード追加

人気ランキング記事を挿入したい場所に以下を挿入。
‘custom_popular_ranking'(任意で作成) という名前のカスタムフィールドをfunction.phpで自動で作成しているのでその値が高い順に記事を表示させる。

  1. htmlは適宜自分のサイトに合わせて変更が必要。
<?php get_responsive_pagination(7,4);?>

第1引数にPC用の出力数字範囲、第2引数にスマホ用の出力数字範囲
これにより以下のようになります。

【PC】
【スマホ】
  1. テスト用に表示投稿数は2件の設定です。

以下出力されるHTMLソース。
あとはcssで見た目の調節など。

<nav class="cms-pagination pagination-range-over-sp pagination-range-over-pc">
    <ul class="clearfix">
        <li class="pagination-no-num first"><span>先頭へ</span></li>
        <li class="pagination-no-num prev"><span>前へ</span></li>
        <li class="pagination-index pagination-sp"><span>1</span></li>
        <li class="pagination-sp"><a href="https://keprate.com/web/page/2/">2</a></li>
        <li class="pagination-sp"><a href="https://keprate.com/web/page/3/">3</a></li>
        <li class="pagination-sp"><a href="https://keprate.com/web/page/4/">4</a></li>
        <li><a href="https://keprate.com/web/page/5/">5</a></li>
        <li><a href="https://keprate.com/web/page/6/">6</a></li>
        <li><a href="https://keprate.com/web/page/7/">7</a></li>
        <li class="pagination-no-num next"><a href="https://keprate.com/web/page/2/">次へ</a></li>
        <li class="pagination-no-num last"><a href="https://keprate.com/web/page/14/">最後へ</a></li>
    </ul>
</nav>

cssで見た目を調節

あとは見た目の調節。
先頭へ・最後へなどは必要な際は動的にpagination-range-over-sp、pagination-range-over-pcが付加されるのでcssで表示・非表示の設定をすればいいです。
レスポンシブスマホ対応ですが全てのページ件数を表示するとスマホでは横幅が足りませんのでpagination-spが付いているリストのみ表示するようにしています。
4件ぐらいですと問題ないかと思います。
あとはサイトに合わせたデザインにごにょごにょ変更。

/* cms-pagination */
.cms-pagination {
    width: 100%;
    overflow: hidden;
    margin-top: 40px;
}

.cms-pagination ul {
    position: relative;
    float: left;
    left: 50%;
    margin-bottom: 12px;
}

.cms-pagination ul li {
    position: relative;
    float: left;
    left: -50%;
    width: 34px;
    height: 38px;
    display: table;
    margin: 0 2px;
    display: none;
}

.cms-pagination ul li.pagination-no-num {
    width: 50px;
    display: table;
}

.cms-pagination ul li.pagination-no-num span {
    background: #eee;
    border: 1px solid #ddd;
    color: #ccc;
}

.cms-pagination ul li.pagination-sp {
    display: table;
}

.cms-pagination ul li a,
.cms-pagination ul li span {
    width: 100%;
    height: 100%;
    display: table-cell;
    vertical-align: middle;
    text-align: center;
    position: relative;
    border: 1px solid #999;
    background: #fff;
}

.cms-pagination ul li a:before,
.cms-pagination ul li span:before {
    position: absolute;
    display: block;
    content: '';
    width: 96%;
    height: 2px;
    background: #ccc;
    bottom: -3px;
    left: 2%;
}

.cms-pagination ul li span {
    background: #555;
    border: 1px solid #555;
    color: #fff;
}

.pagination-txt {
    clear: both;
    text-align: center;
    margin-bottom: 40px;
}

.pagination-txt span {
    color: #999;
}

@media print,screen and (min-width: 1024px) {
    .cms-pagination ul li {
        width: 40px;
        height: 44px;
        margin: 0 3px;
        display: table;
    }
    .cms-pagination ul li a {
        -webkit-transition: background 0.3s ease;
        -moz-transition: background 0.3s ease;
        transition: background 0.3s ease;
    }
    .cms-pagination ul li a:hover {
        background: #ccc;
        -webkit-transition: background 0.3s ease;
        -moz-transition: background 0.3s ease;
        transition: background 0.3s ease;
    }
    .cms-pagination ul li.pagination-no-num {
        width: 60px;
    }

    .pagination-txt {
        margin-bottom: 60px;
    }
}
  1. ソースの流用、改変は自由ですが自己責任とさせていただきます。
トラックバック URL
https://keprate.com/web/wordpress/wp-pagination/trackback/
奇跡的に興味を持たれた方は
是非お問い合わせください。
  • 電話番号の掛け間違いにお気をつけください。
  • 女性は業務に一切関係ございません。
PAGE TOP