
こんにちは、yutaです。
WordPressでオリジナルテーマを作成している時に、ブログ記事一覧を表示させるページで、ページネーション( [ 1,2,3…10 次へ ]みたいなページ送りのリンク)を実装しようとした時になかなかうまくいかなったので、やり方をメモしておきます。
この記事を読めば、表示させる記事のカテゴリーやタグ、執筆者などを指定したうえでページネーションを実装することができるようになります。
ただページネーションを表示したいだけであれば、関数リファレンス/paginate linksの「基本的な例」にあるコードをコピペすればOK
ページに表示させる記事のカテゴリーやタグを指定したり、1ページあたりに表示させる記事数を指定したい場合は、上記リンクの「カスタムクエリを使用した例」を書き換えればOK
だけど、これだけでは不親切なのでもうちょっと丁寧な説明が以下。
基本的にページネーションを表示するときは、「echo paginate_links();」を、ページネーションを表示させたい場所で実行すればOK
ただページネーションを表示したいだけの場合と、表示させる記事などを色々と指定したうえでページネーションを表示する場合でのコードの違いは、
paginate_link()の引数のtotalに、WordPressのデフォルトのグローバル関数である$wp_queryを使って、$wp_query->max_num_pagesとするのか、WP_Query()を使って独自に生成した変数$the_query(カスタムクエリ)で、$the_query->max_num_pagesとするのかという点。
というわけなので、以下をページネーションを表示させたい場所に貼り付けると、表示させる記事などを指定したうえでのページネーションが表示される。
<?php $big = 999999999; // need an unlikely integer 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 //ここだけがデフォルトと違う ) ); ?>
ただし、上記コードだけでは、$the_queryを生成できていないので、それを生成するためのコードが以下。
<?php //Protect against arbitrary paged values(現在のページが変な値にならないようにするためのもの) $paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1; $args = array( 'posts_per_page' => 5, //1ページあたり5記事を表示 'category_name' => 'gallery', //"gallery"というカテゴリーに属する記事だけを取得 'paged' => $paged, //現在のページに該当する記事から取得 ); $the_query = new WP_Query( $args ); ?>
これで、the_queryという変数(カスタムクエリ)が生成されたので、上述しているpaginate_link()を実行するとうまくいく。
実際にページネーションを実装する場合には、最初にカスタムクエリの生成を行うコードを記述して、その後にpaginate_links()を実行する流れになる。
くどいけど、要するに以下の順で記述すればOK(記述内容は上記と同じ)
<?php //Protect against arbitrary paged values(現在のページが変な値にならないようにするためのもの) $paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1; $args = array( 'posts_per_page' => 5, //1ページあたり5記事を表示 'category_name' => 'gallery', //「gallery」というカテゴリーに属する記事だけを取得 'paged' => $paged, //現在のページに該当する記事から取得 ); $the_query = new WP_Query( $args ); ?> <?php $big = 999999999; // need an unlikely integer 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 //ここだけがデフォルトと違う ) ); ?>
毎回このコードを書いているとソースがごちゃごちゃするので、関数化してfunctions.phpなどに入れておくと良い。 (僕の場合は、functions.phpを直接いじりたくないので、selfcreated_functions.phpみたいなのを別で作ってそこに記述しています。selfcreated_functions.phpはfunctions.phpのなかでrequire “selfcreated_functions.php”;として呼び出しているので、きちんと実行されます。)
ですので、僕はpaginate_links()のコードは以下のように関数化してselfcreated_functions.phpの中に記述しています。
function show_pagination($the_query){ //関数化しているので、カスタムクエリは引数で渡してあげる big = 999999999; // need an unlikely integer 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 //ここだけがデフォルトと違う ) ); }
カスタムクエリの生成自体も関数かできますが、僕はやってません。やりたければやると良いですw
基本的にはこれで説明終了ですが、表示させる記事のパターンを色々と変えてみましょう。これは、カスタムクエリを生成する時に引数$argの中身を変えることで実現できます。
カスタムクエリの生成については、関数リファレンス/WP Query で詳しく書いてあるんですが、最初は読んでもよく分からんのです。結局は、上で紹介した
<?php //Protect against arbitrary paged values(現在のページが変な値にならないようにするためのもの) $paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1; $args = array( 'posts_per_page' => 5, //1ページあたり5記事を表示 'category_name' => 'gallery', //"gallery"というカテゴリーに属する記事だけを取得 'paged' => $paged, //現在のページに該当する記事から取得 ); $the_query = new WP_Query( $args ); ?>
これの、$argsの中身のcategory_nameを、
‘category_name’ => ‘animal’,
とすれば「animal」というカテゴリーに属する記事を取得してくれるし、
‘tag’ => ‘cooking’,
とすれば「cooking」というタグに属する記事を取得してくれるし、
‘author_name’ => ‘yuta’,
とすれば「yuta」さんが執筆した記事を取得してくれる、というお話。
なので、例えば$argsを以下のようにした場合、
<?php //Protect against arbitrary paged values(現在のページが変な値にならないようにするためのもの) $paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1; $args = array( 'posts_per_page' => 8, 'author_name' => 'yuta', 'category_name' => 'life', 'tag' => 'room,eat', 'paged' => $paged, ); $the_query = new WP_Query( $args ); ?>
「yuta」さんが執筆した記事のうち、カテゴリーが「life」で、そのうち「room」もしくは「eat」というタグ付けがある記事を1ページあたり8記事取得する。という意味になります。