wordpressのWP_Queryとかでoffsetを使わずにオフセットする

2014.6.19 Wordpress

wordpressのquery_postsとかwp_queryでoffsetを使わずにオフセットする

前回の記事で、WP_QueryやQuery_postsで’offset’のプロパティを使用すると、ページャーにエラーが出て同じ記事しか表示されない…的なことを書きました。
WordPressでページネーション実装したときのWP_Queryとquery_posts共通のハマりポイント

で?なに?if(have_posts()): while(have_posts()): the_post();でいいじゃん?

って方も多いと思いますが、上記のような問題は、ページにループを2つ作る場合に非常に困るんですよね。

query_postsとかwp_queryでoffsetを使わずにオフセットする

最新記事のみ「ループ1」2番目以降は「ループ2」で出力したい時とかあると思うんですね。
ループ2の最初の記事は先頭から2記事目を表示したい、ということです。

WP-PageNaviとoffsetの関係 -WordPress(ワードプレス) (wald-grun/blog)
一応ここにそれっぽい解決法がありましたが、どうも上手く行かず。

なので、事実上offsetは諦めて先頭記事をループ2から除外することにしました。

WP_Queryやquery_postsでoffsetを指定せずに2番めの記事から表示する

では、どうするか…

先頭記事のIDを取得して、ループ2からそれを除外します。
WP_QueryやQuery_postsにはそれぞれ、投稿を除外するアレがありますね。
テンプレートタグ/query posts – WordPress Codex 日本語版
関数リファレンス/WP Query – WordPress Codex 日本語版

‘post__not_in’に指定するIDを取得する

get_the_IDをループ2の直前で使います。
関数リファレンス/get the ID – WordPress Codex 日本語版

それを、WP_Queryの引数として指定する配列にブチ込みます。

$firstID = get_the_ID(); //投稿の最初の記事ID

$postOthers = array(
  'showposts' => 5 ,
  'paged' => get_query_var('paged') ,
  'post__not_in' => array($firstID)
);

ループ1と2の扱いはこんな感じ。

<ul class="loop1">
<?php //【1】
  $postNum1 = array(
      'posts_per_page' => 1 ,
    );

  $post1 = new WP_Query( $postNum1 );

  if($post1->have_posts()){
    while($post1->have_posts()){ //最初の1記事
      $post1->the_post();
?>
  <li>
    <a href="<?php the_permalink(); ?>">
     ループ1で出したい内容…
    </a>
  </li>
  <?php 
    }
  }
  ?>
</ul>
<ul class="loop2">
 <?php //【2】
  $firstID = get_the_ID(); //投稿の最初の記事ID

  $postOthers = array(
    'showposts' => 5 ,
    'paged' => get_query_var('paged') ,
    'post__not_in' => array($firstID) //ここにさっきの$firstIDを。
    );

  $postOther =  new WP_Query($postOthers) ;

  if($postOther -> have_posts()){
    while($postOther-> have_posts()){ //最初の1記事以降の
      $postOther->the_post();
 ?>
<li class="<?php echo addCatClass(post);?>">
 <a href="<?php the_permalink(); ?>">
 ループ2で出したい内容…
  <h2><?php echo get_the_title(); ?></h2>
  <p><span class="data-date"><?php the_time('Y年n月j日'); ?></span></p>
  <button type="button" class="btn btn-default" >記事を読む</button>
 </a>
</li>
 <?php 
   }
 }
 ?>
</ul>

ちょっと素人クサイかもしれませんが、これでイケました!

ページャーで次のページにジャンプした時、そのページでの先頭記事がスッポ抜けるかと心配していましたが…それも無事回避していました!やったね!

おそらく、ループ2の外でget_the_ID()しているのがミソかと思います。
試していませんが、ループの中だと各記事のIDを取ってしまうのではないかと。

これを思いつく前にふと、最初の記事だけ漠然と判別できれば…と思いましたが、それをどうするかイマイチ閃かなかったので、こっちでも「こうやれば同じこと出来るよ!」とかアイデアがあれば是非是非お申し付けくださいませ

function isFirst(){//最初の記事の判別
 global $wp_query;
 return ($wp_query->current_post === 0);
}
 
function isLast(){//最後の記事の判別
 global $wp_query;
 return ($wp_query->current_post+1 === $wp_query->post_count);
}
 
function isOdd(){//奇数記事の判別
 global $wp_query;
 return ((($wp_query->current_post+1) % 2) === 1);
}
 
function isEver(){//偶数記事の判別
 global $wp_query;
 return ((($wp_query->current_post+1) % 2) === 0);
}

 

今回はWP_Queryで実装していましたが、理屈は同じ(?)なのでquery_postsでも大丈夫だと思います。ダメだったら言ってください。satohmsysが陳謝します。

 

でわ!

Profile

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