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 pager">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) ,'" class="first">', $text_first ,'</a>';
}
if ( $paged > 1 ) {
// 「前へ」 の表示
echo '<a href="', get_pagenum_link( $paged - 1 ) ,'" class="prev">', $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 ) ,'" class="next">', $text_next ,'</a>';
}
if ( $paged + $range < $pages ) {
// 「最後へ」 の表示
echo '<a href="', get_pagenum_link( $pages ) ,'" class="last">', $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.prev {
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によって、以下のような見た目になります。
コメント
コメント一覧 (3件)
いつも参考に読ませてもらってます!
質問なのですが、先輩にWordPressのthe_posts_pagination関数を使うといいと教わっていたのですが、こちらのコードとの違いってあるんでしょうか??
コメントありがとうございます!
動作自体はthe_posts_pagination関数を使用しても変わらないと思いますが、自作の関数を使用した方がどんな処理をしてるか明確で、カスタマイズも柔軟に対応できるのではないかと思います!
参考になる記事ありがとうございますm(_ _)m
【カスタム分類アーカイブ】taxonomy-xxx.php
で実装しようとしているのですが、
2ページ目がindex.phpを読み込んでしまい正しく表示されません。
どこか設定が間違っているのでしょうか?