WordPressでページネーション実装したときのWP_Queryとquery_posts共通のハマりポイント

2014.6.19 Wordpress

プラグイン無しで管理しやすいCSSでページネーションを出したほうが俄然エコ…というわけでページネーションを実装する関数です。

wordpressプラグイン無しでページネーションを実装

function pagination($pages = '', $range = 4){
 $showitems = ($range * 2)+1; 

 global $paged;
 if(empty($paged)){ $paged = 1;}

 if($pages == ''){
     global $wp_query;      
     $pages = $wp_query->max_num_pages; //ページ総数
     
     if(!$pages){ $pages = 1; }
 }  

 if(1 != $pages){
     echo '<ul class="pager"><li>Page'.$paged.' of '.$pages. '</li>';
     if($paged > 2 && $paged > $range+1 && $showitems < $pages){
     	 echo '<li><a href="'.get_pagenum_link(1). '">&laquo First</a></li>';
     	}
     if($paged > 1 && $showitems < $pages){
      echo '<li><a href="' .get_pagenum_link($paged - 1) .'">&lsaquo 前</a></li>';
		}

  	for ($i=1; $i <= $pages; $i++){
         if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems )) {
             echo ($paged == $i)? '<li class="current">' .$i. '</li>' : '<li><a href="' .get_pagenum_link($i) . '" class="inactive">' .$i. '</a></li>';
         }
     }

     if ($paged < $pages && $showitems < $pages){
      echo '<li><a href="' . get_pagenum_link($paged + 1) . '">次 ›</a></li>';
  		}
     if ($paged < $pages-1 &&  $paged+$range-1 < $pages && $showitems < $pages){
     	echo '<li><a href="'.get_pagenum_link($pages).'"><i class="glyphicon glyphicon-fast-forward"></i></a></li>';
        }
 }
}
//出力
if (function_exists("pagination")) {
pagination($wp_query->max_num_pages)
;}

関数名は「pagenation」とします。

引数の$range=4は、すぐ後で演算に使われて非常に影が薄いのですが「ページネーションの数」(サンプルコードだと最大9まで表示)を決める大事な役割を担っています。
表示数をオーバーした分の投稿もモチロン観ることが出来ます。

では、コードを順に確認していきます。

 global $paged;
 if(empty($paged)){ $paged = 1;}

ここで現在いる記事一覧ページの値を取得しています。 それがカラであるなら、1を代入します。

 

つぎに、この部分で存在する記事に対するページ総数の判断をしています。

if($pages == ''){
    global $wp_query;      
    $pages = $wp_query->max_num_pages;//ページ総数
    if(!$pages){$pages = 1; }
   }

$wp_query->max_num_pages;ページの総数を取得しています。
それがカラだった場合は、$pagesに「1」が代入されます。

その$pagesが「1」で無かった場合=記事がある程度存在する場合のページネーションの表示がこちらです。

if(1 != $pages){
   echo '<ul class="pager"><li>Page'.$paged.' of '.$pages. '</li>';
if($paged > 2 && $paged > $range+1 && $showitems < $pages){
  echo '<li><a href="'.get_pagenum_link(1). '">&laquo 最初</a></li>';
  }
if($paged > 1 && $showitems < $pages){
    echo '<li><a href="' .get_pagenum_link($paged - 1) .'">&lsaquo 前</a></li>';
  }

今回は<ul class=”pager”>この中に</ul>ページネーションを表示します。

$pagedには現在見ている記事一覧ページの値が入っています。
$pagesには先ほど$pages = $wp_query->max_num_pages;で取得した全ページ数が入ってます。

その後のif()で、「一番先頭の記事一覧ページに飛ぶページネーション」を出力するかどうか、「一つ前の記事一覧ページにジャンプするページネーション」を出力するかどうか、を判断しています。

get_pagenum_link()でページ送り専用のリンクを取得しています。()に指定したページ番号へジャンプします。
get_pagenum_link(WordPressの機能) – WPSeek.com

 

そして、ページネーションの要となるループ部分が、中盤のこれ

for ($i=1; $i <= $pages; $i++){
  if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems )) {
      echo ($paged == $i)? '<li class="current">' .$i. '</li>' : '<li><a href="' .get_pagenum_link($i) . '" class="inactive">' .$i. '</a></li>';
  }
}

for文でループさせます。全ページ数$pagesの数まで1つずつ出力します。
ちょっと解りづらいので、分解して見てみましょう。

  1. 1 != $pages … 全記事一覧が1ページ以上ある
  2. $i >= $paged+$range+1 … $i(ループの回数)が、今見ている記事一覧ページの値+$range(例だと4)+1よりも大きい
  3. $i <= $paged-$range-1 … $i(ループの回数)が、今見ている記事一覧ページの値-$range(例だと4)-1よりも小さい
  4. $pages <= $showitems … 今見ている記事一覧ページの値が、$showtimeよりも小さい

1.は必須で、2と3のどちらか、もしくは4に当てはまっていることが条件です! 以降はif文の短縮形で、$paged(今見ている記事一覧ページ)と$i(ループの回数)が同じならば、表示中のページとして<li class=”current”></li>に内包されます。 もし、$paged(今見ている記事一覧ページ)と$i(ループの回数)が同じではないならget_pagenum_linkで取得したリンクとともにページ番号(≒$i)を出力してくれます。

このページ番号を出力するループが、ページネーションをずらっと並べるメインのところです!

 

次に、1つ前の記事にアクセスするリンクを出力した時と同様に、「次の”記事一覧ページ”」にアクセスするリンクを出力します。

if ($paged < $pages && $showitems < $pages){
  echo '<li><a href="' . get_pagenum_link($paged + 1) . '">次 &rsaquo</a></li>';
}
if ($paged < $pages-1 &&  $paged+$range-1 < $pages && $showitems < $pages){
 echo '<li><a href="'.get_pagenum_link($pages).'">最後&raquo</a></li>';
}

get_pagenum_link($paged + 1)で、次のページ一覧のリンクを出力します。

これでプラグイン無しでページネーションが実装できました。
この方法に関してはたくさんの記事がありますので良かったら調べてみてください!
WordPressにプラグイン無しでページネーションを設置する方法 | コリス
WordPress プラグインなしでシンプルなページネーションを実装 | 福島県郡山市のホームページ制作、Web制作 Kyasper Web Design キャスパーウェブデザイン
WordPressでページネイション | ダリの雑記:WEBプログラム版

僕が直面したページネーションのハマリポイントについて

あと、途中に上手くページ送りが出来ずハマってしまったときに色々見つけたやつを紹介します。ページネーション大事ですからねー

query_postsで

wp_reset_query()よりも後ろに書いている

クエリ情報がリセットされては意味が無いのです。かならずこれ以前にページャーを出すこと。

$query_stringを書いていない

ページごとに用意された条件の設定をする$query_stringは書くクセを付けたほうが良さげ。

「1ページに表示する最大投稿数」の表記が影響している

query_postsのパラメータでposts_per_pageを指定していると、「1ページに表示する最大投稿数」と干渉して404ページが出たり、色々エラーが起こる場合があります。
「1ページに表示する最大投稿数」よりもposts_per_pageで出力する記事数を多くするといいらしいです。

‘paged’ => $paged ,を書いていない

query_posts() は現在ページの指定がないと2ページ目だろうがなんだろうが1ページ目を読み込んでしまう説があるので、以下のコードを書いて’paged’を指定します。

<?php
$paged = get_query_var('paged'); 

$hoge = array('paged' => $paged , …他色々);
?>

WP_Queryで

‘offset’を指定している

offsetを指定しているとページャーが上手く機能しないらしいです。(query_postsも同様)
僕はこのパターンでした…ループを2つ作っていたのですが、まさかこれとは。
詳しくはコチラの記事を参照してください。wp_pagenaviでの対処法も載っています!旧バージョンですが。
WP-PageNaviとoffsetの関係 -WordPress(ワードプレス) (wald-grun/blog)

 

いかがでしたか?

こんな感じで、ドタバタとページネーションを実装していました。

 

でわ!

Profile

東京でWebデザイナー・コーダーとして、フロントエンド的なことからデザイン思考的なことを考えたりして、ごにょごにょと活動中。(ポートフォリオ)Webクリエイターでは珍しい(?) HIPHOP, R&B好き。休日はよくカフェや漫画喫茶に出向いたりパン屋に行ったりコーヒ豆買いに行ったり、主に散歩しています。。デザインのトレンドやデザイン思考、HTML、CSSからSASS、Javascript、Wordpress構築などコーディングのTIPSなどをブログにアップしていきます。その他のことはtwitter( @satohmsys )まで。コーヒー友達募集中。