トップページにインパクトが欲しい!
ブログを巡回していると最新記事だけ大きくなっていて、2件目以降はアーカイブ形式に表示されるトップページをよく見ますよね。
通常のループ処理だと同じレイアウトを並べることしかできないので、ちょっとした細工が必要になります。
目次
offsetだとページネーションが使えない
最初に思いつくのがoffsetだと思います。
最新記事と2件目以降で別にループを作って、2件目のループでoffset指定で2件目以降をループさせる方法です。
offsetを使用した場合
<?php $args = array( 'post_type' =>'post', 'posts_per_page' => 1 ); $my_query = new WP_Query($args); if( $my_query -> have_posts() ) : while($my_query->have_posts()) : $my_query->the_post(); ?> <!-- 最新記事 --> <?php endwhile; endif; ?> //2件目以降のループ <?php $paged = get_query_var('paged') ? get_query_var('paged') : 1 ; $args = array( 'post_type' =>'post', 'posts_per_page' => 10, 'paged' => $paged, 'offset' => 1 ); $my_query = new WP_Query($args); if( $my_query -> have_posts() ) : while($my_query->have_posts()) : $my_query->the_post(); ?> <!-- 2件目以降の記事 --> <?php endwhile; endif; ?>
これでも期待した表示はできるのですが、問題はサブループを使うこととoffsetを使用するとページネーション(ページャー)が使えないという点です。
通常こういった表示をしたい場所はブログのトップページで、ページ送りで以前の記事も見られるようにすることだと思います。
その場合必須になるページネーションが使えないのは致命的です。
メインループの中で最新記事を判別する
となれば、何かしらの方法で最新記事だけ選別して別の表示をさせる方法がベターでしょう。
私は下記のように選別してみました。
最新記事だけ選別して表示
<?php $args = array( 'post_type' => 'post', 'posts_per_page' => 1 ); $my_query = new WP_Query($args); $first_post = $my_query-> posts[0]; $first_post_id = $first_post-> ID; ?> <?php if( have_posts() ) : while(have_posts()) : the_post(); if($post->ID == $first_post_id): ?> <!-- 1件目の記事 --> <?php else : ?> <!-- 2件目以降の記事 --> <?php endif; endwhile; endif; ?>
ちょっと分解してみます。
まず選別の方法ですが、記事一覧の格納されている$postsから一番上(最新)の記事IDを拾っておいて、メインループ内にif文でそのIDの記事をより分けて表示させています。
ただ$postsはページ送りする度に、そのページ内で表示される分だけの記事が格納されます。
例えば1ページ5記事表示の設定だと、2ページ目の6記事目も最新記事と同様大きく表示されてしまいます。
それだとちょっと意図したものと違うので、記事全体からの最新記事IDを拾うコードを書いてあります
最新記事のIDを取得
$args = array( 'post_type' => 'post', 'posts_per_page' => 1 ); $my_query = new WP_Query($args); $first_post = $my_query-> posts[0]; $first_post_id = $first_post-> ID;
そのIDとループされる記事のIDを照合してより分け処理を行います。
if($post->ID == $first_post_id):
まとめ
最初はちょっと悩んでいたのですが、いざ組んでみたら意外とシンプルでした。
$my_query -> posts[0];は0番目の記事を拾うという意味ですので、3番目・5番目も大きくしたいという場合は数値を2・4とすれば応用できます。
ちなみに$postsを参照して2ページ目、3ページ目も同じレイアウトで表示する場合はこちらになります。
2ページ以降も同じレイアウトで表示
<?php $first_post = $posts[0]; $first_post_id = $first_post-> ID; ?> <?php if( have_posts() ) : while(have_posts()) : the_post(); if($post->ID == $first_post_id): ?> <!-- 1件目の記事 --> <?php else : ?> <!-- 2件目以降の記事 --> <?php endif; endwhile; endif; ?>
追記
当サイト上記の方法で最新記事だけ大きくして、残りはfloatのカラム落としでレイアウトしていたのですが、記事が増えてきて少々トラブルに見舞われました。
後日そのトラブルを解消した記事を書きましたので、同じようなレイアウトを考えている方は併せて参照してみてください。
追記2
後日気が付いたのですが「最新記事だけ選別して表示」の項の方法だと、2ページ目の表示が奇数になってしまい、最後の列に端数が出てしまいます。
例えば1ページ5件表示で最新記事が2枠、残り4記事が1枠ずつだと計6枠になるので、1ページ目は問題ないのですが、2ページ目は全て1枠になるので計5枠になってしまい最後の列が1個空いてしまう・・・という感じです。
そういう訳で一応2番目の記事まで大きくするソースを追記しておきます。
最新記事と次点記事だけ大きくする
<?php $args = array( 'post_type' => 'post', 'posts_per_page' => 1 ); $my_query = new WP_Query($args); $first_post = $my_query-> posts[0]; //1番目の記事を取得 $first_post_id = $first_post-> ID; //1番目の記事IDを取得 $Second_post = $my_query-> posts[1]; //2番目の記事を取得 $Second_post_id = $Second_post-> ID; //2番目の記事IDを取得 ?> <?php if( have_posts() ) : while(have_posts()) : the_post(); if($post->ID == $first_post_id || $post->ID == $Second_post_id): ?> <!-- 1件目と2件目の記事 --> <?php else : ?> <!-- 3件目以降の記事 --> <?php endif; endwhile; endif; ?>
はじめまして。
「ページネーションも使える!wordpressでoffsetを使わず最新記事だけ大きく表示する方法」の記事を拝見させていただきました。
カスタム投稿タイプのアーカイブページに利用したいと思ったのですが、
下記のエラーが出てしまいました。
Parse error: syntax error, unexpected ‘endwhile’ (T_ENDWHILE)
内容変えずにコピペで試してみたのですが、同じでした。
いろいろ試したのですが、うまくいかず。
助言をいただけると大変たすかります。
どうぞよろしくおねがします。
ご指摘ありがとうございます。
確認してみたところ、endwhile;の一つ前に入るべきendif;が抜けていたのが原因でした。
ご迷惑をおかけしました。
ソースのほうは修正を入れておきましたので、宜しければ是非ご利用ください。
ちなみにこれを作った後掲載記事が増えてから発覚したのですが、「最新記事だけ選別して表示」の項のソースを使用すると、2ページ目の記事が奇数になってしまいます。
例えば1ページの表示記事が5件だとして、最新記事が2枠分、残り4記事が1枠ずつで計6枠使用したレイアウトにしてしまうと、2ページ目はすべて1枠なので最後の列に端数が出てしまうんです。
作った時なんで気が付かなかったのだろうかと・・・
一応「最新と次点の記事を大きくする」バージョンも追記しておきますので、そちらも参照してみてください。