プラグインなしでページネーションをつける
WordPressのカスタマイズ案件で、割とよく出てくる件であり、結構ハマりやすいのが、「ページネーション」です。
WordPressにおいて、ページネーションを表示できる関数はいくつか存在しているのですが、今回はそれらの中でもおそらく使用頻度の高い、以下のキャプチャのような数字付きのページネーションを、プラグインを使わずに表示する方法について書いていきたいと思います。
↑こう言うやつのことです
まずは結論、コードから:
WordPressには、とある特定の投稿を取得してくる方法が複数あるのですが、今回は WP_Query(); を使用したループを作成して、そこにページネーションをつける、という方法を例に書いていきます。
※そもそもWordPressにおけるループって何?と言う部分については、Codex日本語版のこのページに詳しく書かれています。
なおループという概念自体は、WordPress(と言うかPHP)に限った概念ではなく、他のプログラム言語でも頻出する概念なので、上記のリンク先を一読しておくのも良いかと思います。
では以下、コードになります。
<?php $paged = get_query_var('paged') ? get_query_var('paged') : 1; $mypost = array( 'category_name' => 'wp-tips', 'paged' => $paged, 'post_type' => 'post', 'post_status' => 'publish', 'order' => 'ASC', 'posts_per_page' => 3 ); $the_query = new WP_Query($mypost); ?> <div class="m-container-postlist"> <div class="m-wrapper-postlist"> <?php if ($the_query->have_posts()): while ($the_query->have_posts()): $the_query->the_post(); ?> <!-- postlist --> <div class="m-item-postlist"> <div class="m-child-postlist"> <?php if(has_post_thumbnail()): ?> <img src="<?php the_post_thumbnail_url('large'); ?>" alt="<?php the_title(); ?>"> <?php endif; ?> <div class="m-title-postlist"> <p><?php the_title(); ?></p> </div><!-- pair of m-title-postlist --> </div><!-- pair of m-child-postlist --> </div><!-- pair of m-item-postlist --> <!-- // postlist --> <?php endwhile; ?> <!-- pagenation --> <?php $big = 999999999; echo paginate_links(array( 'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), 'format' => '?paged=%#%', 'current' => max(1, get_query_var('paged')), 'total' => $the_query->max_num_pages ) ); ?> <!-- // pagenation --> <?php wp_reset_postdata(); ?> <?php endif; ?> </div><!-- pair of m-wrapper-postlist --> </div>
上記コードの解説です。
まずは、「どんな投稿を取得してくるか?」という部分を冒頭の 3 ~ 10 行目で定義。
これを、変数$mypost に配列として格納しておきます。
この $myposts を WP_Query();
に渡して、それを $the_query として定義(11行目)。
$the_query に対して、条件に一致する投稿があれば、投稿を取得してきてね、と言う意味が書いてあるのが
16行目の if ($the_query->have_posts()): while ($the_query->have_posts()): $the_query->the_post();
の部分です。
ここから29行目の endwhile;
までがループの範囲になり、
指定した条件を満たす投稿がある限り、
16行目 ~ 29行目の中身の内容が繰り返し実行されます(他の言語でもよく出てきますが、whileループなどと呼ばれているものです)。
実際に表示される各投稿は、18行目 ~ 27行目までで、
20~22行目でサムネイルがある場合はサムネイルの表示、
24行目では投稿のタイトルを取得しています。
この18行目 ~ 27行目のループの中身について、適宜表示させたい項目を追加するなどすれば、記事リストの表示を柔軟にカスタマイズすることができます。
ページネーションに影響する部分
2行目に書いてあるこの記述
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
は、ページネーション付きのthemeファイル内でよく見かける一行ですが、
これは、変数$paged に入る値を、三項演算子の形で記述している部分になります。
※三項演算子についてはPHP公式に丁寧な解説があります。比較演算子のページの中段に、どういったものか細かく書かれています。
細かい説明は省きますが、ものすごくざっくり言うと ? の前の条件式が true の場合なら : の前の値、false なら : の後の値を返す書き方です
具体的に2行目でどんなことを書いているかと言うと、 get_query_var() を使用して、WordPress内で現在その瞬間実行されているクエリにおいて参照可能な値の中から ‘paged’ と言うキーを探して、そこに値が存在していたらその値を、存在しなければ 1 を返す、と言う処理になります。
この’paged’ と言うキーの値には、通常は表示しようとしているページ番号が数字で入っているので、
それを変数 $paged に格納して、5行目の値としてセットしておきます。
これによって、ページネーションを付けた際も、
ユーザーが表示しようとしたページがユーザーの意図通りに表示される様になる、というわけです(仮に3ページ目のリンクをクリックしたとしたら、意図通りに3ページ目が出る様に設定している、と言う意味です)。
ここまでの記述が、WP_Query(); による投稿の取得になります。
ここまでの記述で、記事の表示自体ができる様になります。
(上の例では、
4行目で定義している通り wp-tips と言うスラッグを持つカテゴリから記事を取得、
9行目で定義している通り、1ページあたり3件ずつ取得する、と言う書き方になります)
ページネーションの記述を追加する
上記までで解説した投稿取得用のループの下に、paginate_links() 関数を記述(上のコードの例でいうと、30行目~40行目)すれば、
冒頭の様なページ番号付きのページネーションを表示することが可能です。
次は、この部分にフォーカスして詳しく見ていきます。
<?php $big = 999999999; echo paginate_links( array( 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), 'format' => '?paged=%#%', 'current' => max( 1, get_query_var('paged') ), 'total' => $the_query->max_num_pages ) ); ?>
この paginate_links();
は、ページ番号付きのリンクを返すためのWordPressの関数です。
この関数にも、実行時に様々なパラメーターを渡すことが可能で、それによって表示内容のカスタマイズが可能です。
上記の例では、base, format, current, total を指定しており、それぞれの引数の意味は WordPress Codex 内の、pagenate_linksページのこの部分 を参照してください。
以上の記述で、ページネーションを追加した記事一覧ページが作成できます。
今回は固定ページ用のテンプレートを作成して、そこに記述してサンプルを作りました。
サンプルページは以下リンク先になります。
ページネーションのサンプル
この記事のまとめ
今回は、プラグインを使わずに、WP_Query() と pagenate_links() を組み合わせてページネーションを表示させる方法についてご紹介しました。もしプラグインを使う場合は、例えば有名な wp_pagenavi などがありますが、何より、WordPressにおける投稿取得の仕組みとページ分割の仕組みを知っておく事は、WordPressのカスタマイズ案件においてとても重要です。上記の方法を知っておく事で、よりさまざまなケースで、柔軟なカスタマイズに対応ができることかと思います。
※この記事は、内容の品質向上を目的に、随時更新を行う場合があります。