WordPress 自作ページネーションの作成(page_num_links)
こんにちは
今回はWordPressのページネーション生成関数を使用しない、、
自作の関数を用意し、各パラメータを設定できる引数を取れるようにしたページネーションを作成しようと思います
- page_num_links()を用いる
- デフォルト引数を設定する
- デフォルトの連想配列を変数化する
- wp_parse_args(連想配列、デフォルト連想配列)
- extract( 連想配列, オプションの挙動設定 );
- 必要なページ情報を取得する (投稿情報)
- 投稿タイプの取得
- 投稿総数の取得
- 現在のページのアーカイプURLを取得
- 投稿総数の取得 (wp_count_posts)
- 現在のページのアーカイプURLを取得(get_post_type_archive_link)
- 「最大投稿数設定の取得」 と 「最大ページ数の取得」
- ページネーションを出力する
- 「$show_only=表示設定が trueで 1ページのみの時」
- 1ページのみで表示設定もない場合
- 2ページ以上ある場合はページネーションを表示する
- まずは現在のページ数の表示をしていこうと思います
- 「次へ、前へ、先頭へ、最後へ」を表示する場合
- 表示する際の変数を解説
- get_pagenum_link( )を解説
- メインのページネーションをループで処理する
- 前後リンクと最後のリンクを設定
- 次への表示
- 最後へのリンクを表示
- 表示する場所に関数を展開する
- まとめ
以前作成したWordPressの組み込み関数でpagenaite-links()という組み込み関数を使用したものでしたが、
こちらの関数は「現在のページの前後にいくつページを表示するか?」という
‘mid_size’ パラメータの設定があるにも関わらず
そのパラメータの内部設定でそのパラメータを上書きする仕様があるため
結果、思い通りの表示にはなりませんでした。。
私のサイトでは良いのですが、これがクライアントワークであった場合プラグインなどに頼ることとなり、自分の中で満足いく仕事がかなわないと感じました
page_num_links()を用いる
page_num_links()は前述のpagenaite_links()でも内部で使用している関数であり、
その関数の使用は
引数に指定したページ番号のリンクを返すという仕組みである為、うまく使用すればこれだけでページネーションを実装することが可能です
それではfunctions.phpに記述していきます
いきなり長いコードですが一つづつ解説していきます。
そしてここから実際に表示するページの内容を記述します
<?php
if ( function_exists( 'pagination' ) ) :
$args = array(
'prev_next' => false,
);
pagination( $args );
endif;
?>
上記の記述で表示するわけですが注目するのは引数に$argsを指定していることと
その引数のパラメータは一切指定しなくても表示出来るようにしておく
ということです
デフォルト引数を設定する
$defaults = array (
'paged' => max(1, get_query_var('paged')),
'prev_next' => TRUE,
'range' => 2,
'show_only' => FALSE,
'add_item_class'=> ''
);
さていよいよfunction宣言をして関数を記述していくわけですが、
$defaultsに対して配列でこれから使用するであろう引数を、キーと値として連想配列形式で用意します
ここに記述しておいた値が「パラメータ引数の$argsのデフォルト値(初期設定)」になります
デフォルトの連想配列を変数化する
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
wp_parse_args(連想配列、デフォルト連想配列)
wp_parse_args()は連想配列を第一引数にしてデフォルト値の配列を結合するための汎用の関数です
結合するだけで$argsに対しての連想配列として使用することが出来るわけですが
このままでは関数の引数として使用できないのでこれを変数にしていきます
extract( 連想配列, オプションの挙動設定 );
extract();は連想配列を渡してそのキーを=変数名、値を=変数の値として変換することが可能です
第二引数は変数名がカブったとき、衝突した際の挙動を指定します
今回は「すでに変数が存在する場合はスキップする」を指定しています
これでさっきデフォルトで用意した配列を
$pages,$paged,$prev_next,$rangeといった様に変数化することが出来たので
後はこれらの変数を引数に使用して関数ロジックを組んでいきます
必要なページ情報を取得する (投稿情報)
$post_type = get_post_type();
if (is_tax()) {
$post_count = get_queried_object()->count;
$current_url = get_term_link(get_queried_object()->slug, get_queried_object()->taxonomy);
} else {
// 投稿タイプの投稿数を取得
$post_count = wp_count_posts($post_type)->publish;
// 投稿タイプのアーカイブURLを取得
$current_url = get_post_type_archive_link($post_type);
}
投稿タイプの取得
まず現在のページの種類によって情報の取得方法が異なる為
$post_type = get_post_type();で現在の全ての投稿タイプを取得しています
投稿総数の取得
$post_count = get_queried_object()->count;
get_queried_object()は現在表示しているページの情報を取得する関数で
先にif (is_tax())タクソノミーページの場合として分岐しているので->count;とすることで投稿の総数を取得することが出来ます
現在のページのアーカイプURLを取得
まぁあまり必要はありませんが一応取得しておきます
$current_url =
get_term_link(get_queried_object()->slug, get_queried_object()->taxonomy);
get_term_linkはその名の通りタームのリンクを(ID or スラッグ、タクソノミースラッグ)を引数として取得してくるのでここでも先に解説したget_queried_object()で撮ってくることが可能です
そして投稿タイプがタクソノミー出ない場合の取得方法です
投稿総数の取得 (wp_count_posts)
wp_count_postsは(投稿タイプ、オプション)として現在のページの投稿総数を取得できる関数です
今回の場合先に取得していた($post_type)を引数として->publish;というパラメータで繋いでやることで現在公開中の投稿カウントと条件設定します
現在のページのアーカイプURLを取得(get_post_type_archive_link)
これも簡単です
get_post_type_archive_link($post_type);
として現在の投稿タイプから、そのアーカイプページを取得することが出来る関数を使用しています
「最大投稿数設定の取得」 と 「最大ページ数の取得」
漢字にすると小難しいですが「最大投稿数設定」とは単純に
自身が設定知ているWordPressの投稿設定の「1ページに何件の投稿を表示するか」の設定値を取得します
「最大ページ数の取得」はそのままの意味で「ページネーションを何ページ分用意するか」という数値ですね
$page_limit = get_option(‘posts_per_page’);
get_option()はWordPressの色々な設定(オプション情報)を取得してくる関数で
様々なパラメータで情報を取得できるのですが今回はposts_per_pageを引数として
「最大投稿数設定」を取ってこれます
次は最大ページ数です
$max_page = ( int ) ceil($post_count / $page_limit);
やりたいこととしては 投稿数÷1ページ投稿数=総ページ数
という式が成り立つのですが小数点以下まで割り算されてしまうため
PHP関数のceil()を使用して小数点以下を切り上げします
そしてこの関数はfroat型で返り値が戻ってくるため
意図的に(int)で整数型に変換して渡します
さてこれで必要な情報がすべて出揃ったのでいよいよページネーションを出力する部分を書いていきます
ページネーションを出力する
if ( $show_only && $post_count < $page_limit ) {
echo '<ul class="pagination"><li class="current pager">1</li></ul>';
return;
}
$show_onlyは元々引数でfalseにしていましたがこちらがtrueにした場合の分岐を先に書いていきます
「$show_only=表示設定が trueで 1ページのみの時」
表示できる投稿が1ページに収まる場合ですね
簡単なHTMLを出力します
今回HTMLの<li>タグには現在のページにはクラス名として.currentを
そして全ての<li>タグに.pagerというクラス名を付与しています
1ページのみで表示設定もない場合
if ( $post_count < $page_limit ) return;
この場合はページネーションを表示しないので即リターンです
2ページ以上ある場合はページネーションを表示する
if ( 1 !== $post_count ) {
echo '<ul class="pagination"><li class="page_num">現在 ', $current_page ,' ページ目です','</li><br>';
if ( $current_page > $range + 1 && $prev_next) {
echo '<li class="first ',$add_item_class,'"><a href="', $current_url ,'" >', $text_first ,'</a></li>';
}
if ( $current_page > 1 && $prev_next) {
echo '<li class="prev ',$add_item_class,'"><a href="', get_pagenum_link( $current_page - 1 ) ,'">', $text_before ,'</a></li>';
}
さていよいよページネーション本体ですね
まずは現在のページ数の表示をしていこうと思います
$current_pageという変数に現在のページが入っているのでこちらで簡単に表示できます
「次へ、前へ、先頭へ、最後へ」を表示する場合
$prev_nextという変数には前後のテキスト表示の有無を切り替えれる様に真偽値を入れていました
これがtrueに設定した場合の分岐になります
条件分岐の仕方、中身としては、
現在のページ > 前後にいくつ表示するか + 1 && 表示設定
という条件で表示しています
表示する際の変数を解説
echo '<li class="first ',$add_item_class,'"><a href="', $current_url ,'" >', $text_first ,'</a></li>';
$add_item_classはクラス名を追加する際に使用します
デフォルトは空にしてありますがあったほうが親切かと思います
<a>タグのhref属性には先頭ページのURLということで$current_urlを使用しています
ここは後で解説するpage_num_links(1)でも問題ありません
$text_firstには表示する際の文字をあらかじめ代入しておきましょう
//表示用テキスト
$text_first = "先頭へ";
$text_before = "前へ";
$text_next = "次へ";
$text_last = "最後へ";
ここもお好みですし、デフォルト設定にして変数化しても親切かと思います
get_pagenum_link( )を解説
今回のメインの関数です
引数として渡された番号のリンクを返す関数
ということでget_pagenum_link( $current_page – 1 )とすることで一つ前のページヘリンクのURLを出力してくれます
ちなみに内部でesc_url()を使用するためサニタイズの必要もありません
この関数を使用してメインのページネーションを生成します
メインのページネーションをループで処理する
for ( $i = 1; $i <= $max_page; $i++ ) {
if ( $i <= $current_page + $range && $i >= $current_page - $range ) {
if ( $current_page === $i ) {
echo '<li class="current pager ',$add_item_class,'">', $i ,'</li>';
} else {
echo '<li class="pager ',$add_item_class,'"><a href="', get_pagenum_link( $i ) ,'" class="pager ',$add_item_class,'">', $i ,'</a></li>';
}
}
}
ループの条件は最大ページ数までということで$max_pageにします
その上で1から$current_page +- $range 以内であればページ番号を出力するという条件でページネーションを出力します
更にその中で現在のページ番号の場合という条件で$current_page === $iで分岐します
そしてその場合だけリンクを出力しないようにすることと、class=”current” というクラス名を付与してあげることでCSSで現在のページの装飾がしやすくなります
その他の場合、elseの場合はget_pagenum_link( $i )とすることで連番でリンクが出力出来るというわけです
前後リンクと最後のリンクを設定
if ( $current_page < $max_page && $prev_next) {
echo '<li class="next ',$add_item_class,'"><a href="', get_pagenum_link( $current_page + 1 ) ,'">', $text_next ,'</a></li>';
}
if ( $current_page + $range < $max_page && $prev_next) {
echo '<li class="last ',$add_item_class,'"><a href="', get_pagenum_link( $max_page ) ,'">', $text_last ,'</a></li>';
}
echo '</ul>';
}
次への表示
現在のページ より 最大ページ数が多い 表示設定
上記の分岐で「次へ」のリンクを出力していきます
リンクはget_pagenum_link( $current_page + 1 )ですね
最後へのリンクを表示
現在のページ + 前後ページ が 最大ページ数より少ない場合 && 表示設定
最後は上記の条件です
リンクはget_pagenum_link( $max_page )で問題ないですね
最後に〆となる<ul>タグを出力したら完成ですね
表示する場所に関数を展開する
<?php
if ( function_exists( 'pagination' ) ) :
$args = array(
'prev_next' => false,
);
pagination( $args );
endif;
?>
もちろんデフォルト設定しているため連想配列を用意しなくても動きます
まとめ
お疲れさまでした
なかなか長丁場の解説とコードになってしまいましたが
その甲斐あって引数として渡されたパラメータによって通常のワードプレスに組み込みで備わっている関数を使用するよりかなり自由度が高いと思います
前後の表示設定やクラスの追加にとどまらず
こちらのコードをベースとしてクライアント用に自分用にカスタマイズしていけたら楽しくオリジナリティを追求できると思います
コメントをお待ちしております