WordPressでページャーを表示する時はこれまで「WP-PageNavi」というプラグインに頼っていたのですが、そろそろコード直書きで実装してみることにしてみました。

ググればほぼ同じ内容のコードがたくさん出てきたのですが、そのコードだとエラーが出たりしてちょっと気に食わなかったので、自分なりにカスタマイズしてみました。

2018 / 11 / 20 追記
通常のアーカイブページだけでなく、WP_Queryのサブループでも使用できるように関数を調節・記事を追記いたしました。

目次

関数本体のコード

まずはページャーを生成する関数をfunctions.phpで定義しておきます。

以下のコードをコピペしてください。

/**
* ページネーション出力関数
* $paged : 現在のページ
* $pages : 全ページ数
* $range : 左右に何ページ表示するか
* $show_only : 1ページしかない時に表示するかどうか
*/
public static function pagination( $pages, $paged, $range = 2, $show_only = false ) {

    $pages = ( int ) $pages;    //float型で渡ってくるので明示的に int型 へ
    $paged = $paged ?: 1;       //get_query_var('paged')をそのまま投げても大丈夫なように

    //表示テキスト
    $text_first   = "« 最初へ";
    $text_before  = "‹ 前へ";
    $text_next    = "次へ ›";
    $text_last    = "最後へ »";

    if ( $show_only && $pages === 1 ) {
        // 1ページのみで表示設定が true の時
        echo '<div class="pagination"><span class="current">1</span></div>';
        return;
    }

    if ( $pages === 1 ) return;    // 1ページのみで表示設定もない場合

    if ( 1 !== $pages ) {
        //2ページ以上の時
        echo '<div class="pagination"><span class="page_num">Page ', $paged ,' of ', $pages ,'</span>';
        if ( $paged > $range + 1 ) {
            // 「最初へ」 の表示
            echo '<a href="', get_pagenum_link(1) ,'">', $text_first ,'</a>';
        }
        if ( $paged > 1 ) {
            // 「前へ」 の表示
            echo '<a href="', get_pagenum_link( $paged - 1 ) ,'">', $text_before ,'</a>';
        }
        for ( $i = 1; $i <= $pages; $i++ ) {

            if ( $i <= $paged + $range && $i >= $paged - $range ) {
                // $paged +- $range 以内であればページ番号を出力
                if ( $paged === $i ) {
                    echo '<span class="current pager">', $i ,'</span>';
                } else {
                    echo '<a href="', get_pagenum_link( $i ) ,'" class="pager">', $i ,'</a>';
                }
            }

        }
        if ( $paged < $pages ) {
            // 「次へ」 の表示
            echo '<a href="', get_pagenum_link( $paged + 1 ) ,'">', $text_next ,'</a>';
        }
        if ( $paged + $range < $pages ) {
            // 「最後へ」 の表示
            echo '<a href="', get_pagenum_link( $pages ) ,'">', $text_last ,'</a>';
        }
        echo '</div>';
    }
}

少し長いコードではあるのですが、中身は特別難しいわけではありません。

前へ」や「次へ」などの表示するテキストは編集しやすいように冒頭部分で変数に代入してまとめてあります。

引数の説明

引数は4つ渡すことができるようにしています。

  • $pages:全ページ数を渡します。(呼び出し側で$wp_query->max_num_pagesを使う)
  • $paged:現在のページ番号を渡します。(呼び出し側でget_query_var('paged')を使う)
  • $range:「現在のページ」から左右に表示させるページ数。初期値は2
  • $show_only:全ページ数が1ページしかない時にページャーを表示するかどうか。初期値はfalse

ちょっぴり解説

関数内部の処理の長れを簡単に列挙しておきます。

  • 変数の準備
  • 全ページ数が 1ページの場合の処理
  • 「最初へ」 を表示するかどうかの分岐
  • 「前へ」 を表示するかどうかの分岐
  • 「番号表示のページャー」を表示するループ
  • $range以内の番号のみ表示させる
  • 「現在のページ」はHTMLソースが別なので分岐
  • 「次へ」 を表示するかどうかの分岐
  • 「最後へ」 を表示するかどうかの分岐

ページャー呼び出し側の記述方法

基本的にはページャーを表示したい場所で、先ほど定義しておいたpagination()関数を呼び出すだけで使えます。

アーカイブページなどのメインループで使用する場合

archive.phpなどのアーカイブページ用のテンプレートファイルでメインループを回している場合の使い方から説明します。

例:archive.phpで呼び出し

/**
 * メインループ開始位置
 */
if(have_posts()):
    while(have_posts()): the_post();

        /* 投稿の表示 */

    endwhile;

    /* 以下、ページャーの表示 */
    if ( function_exists( 'pagination' ) ) :
        pagination( $wp_query->max_num_pages, get_query_var( 'paged' ) );
    endif;

else :
    echo 'まだ記事がありません。';
endif;

全体的にはこんな感じになりますね。
ポイントとなる、関数呼び出し部分だけをピックアップしてみます。

以下の部分がページャーの表示コードです

if ( function_exists( 'pagination' ) ) :
    pagination( $wp_query->max_num_pages, get_query_var( 'paged' ) );
endif;

第1引数に渡す「全ページ数」は、メインループの場合、$wp_query->max_num_pagesで取得できます。

第2引数に渡す「現在のページ番号」は、get_query_var( 'paged' )で取得できます。

全ページ数の取得で$additional_loopを使ったコードを載せてる記事がたくさんあったのですが、エラーで動きませんでした。
また、get_query_var('paged') ?: 1のような、先頭ページの場合に対する分岐処理は関数の内部で行なっているので、呼び出し側では必要ありません。

全ページ数が1ページの場合もページャーを表示させる場合

pagination( $wp_query->max_num_pages, get_query_var( 'paged' ), 2, true);

としてください。

WP_Queryによるサブループで使用する場合

サブループで使う場合は以下のようになります。

$paged = get_query_var('paged') ?: 1;
$args  = array(
    'paged' => $paged,  //「現在のページ番号」はここでも指定する
    /* その他のプロパティの指定など... */
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
    while ( $the_query->have_posts() ) : $the_query->the_post();

        /* 投稿の表示 */

    endwhile;
endif;

/* ページャーの表示 */
if ( function_exists( 'pagination' ) ) :
    pagination( $the_query->max_num_pages, $paged );  //$wp_query ではなく $the_query ないことに注意!
endif;

wp_reset_postdata();

pagination関数の呼び出し位置はwp_reset_postdata()より前にしましょう。

また、「現在のページ番号」ですが、サブループの条件プロパティにも渡してあげないといけないので、注意してください。

一番注意すべき点は、第1引数に渡す「最大ページ数」です。

メインループではグローバル変数である$wp_queryにクエリ情報が入っていましたが、サブループでは自分でクエリ情報を保存する変数を定義していると思います。

上記では$the_queryという変数にnew WP_Query()でクエリ情報を保存しているので、$the_query->max_num_pagesで最大ページ数が取得できます。

 

CSSで見た目を調節

最後に、ページャーのスタイルを整えましょう。

以下は一例です。Flexboxを使って横並びにし、ページャーは正方形になるようにしてます。色はシンプルに白黒。
好きにカスタマイズしてお使いください。

.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 40px 0;
    position: relative;
    font-size: 13px;
}

.pagination span, .pagination a {
    display: block;
    width: auto;
    margin: 4px;
    padding: 8px;
    border: 1px solid #000;
    background-color: #fff;
    text-decoration: none;
    text-align: center;
    line-height: 16px;
}

/* ページ番号 */
.pagination .pager{
    width: 32px;
}

/* ホバー時 & 現在のページ */
.pagination a:hover,
.pagination .current  {
    color: #fff;
    border-color: #000;
    background-color: #000;
}

/* 前へ */
.pagination a.before {
    margin-right: 16px;
}
/* 次へ */
.pagination a.next {
    margin-left: 16px;
}
/* 最初へ */
.pagination a.first {}
/* 最後へ */
.pagination a.last {}

/* Page x / y */
.pagination span.page_num {
    display: none;
}

「ページ番号 / ページ数」の表示は基本使わないと思うので display:none; にしちゃってます。
(使わないならソースコード自体から消したほうがいいですが)

上記CSSによって、以下のような見た目になります。

ページャーデザイン例

- Thank you for reading. -

コメント

  • yuka★ より:

    いつも参考に読ませてもらってます!
    質問なのですが、先輩にWordPressのthe_posts_pagination関数を使うといいと教わっていたのですが、こちらのコードとの違いってあるんでしょうか??

    • より:

      コメントありがとうございます!

      動作自体はthe_posts_pagination関数を使用しても変わらないと思いますが、自作の関数を使用した方がどんな処理をしてるか明確で、カスタマイズも柔軟に対応できるのではないかと思います!

コメントする