[WordPress] offsetを使用したページネーション処理

WordPress

今回は、下記レイアウトのような最新記事1件だけ大きく見せて、2件目以降からは小さな枠といったレイアウトを作成する方法をご紹介します。

offsetパラメータを使えば、簡単じゃないかと言われる方もいるかもしれませんが、これには大きな問題を抱えています。

問題というのは、1ページだけのものであればよいのですが、改ページした2ページ目以降を開いても投稿データが切り替わることなく、同じ記事が出てしまうという点です。
これは、offsetパラメータを指定することで、paged(ページ区切り)の処理を破壊してしまうためです。

詳しくはこちらを参照
http://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination

スポンサーリンク

対処法

offsetとpagedを同時に使うとダメということは、どちらかを使わなければ問題ないということ。
解決方法として、pagedパラメータで指定するのではなく、offsetの開始値を変えることにより、抽出する記事を絞ります。

<?php
    //管理画面で設定した「1ページに表示する最大投稿数」の取得
    $per_page    = get_option('posts_per_page');

    //現在表示しているページ数の取得
    $paged        = (get_query_var('paged')) ? get_query_var('paged') : 1;

    //1ページ目か2ページ目以降かを判定して、
    if(is_paged()){
        //2ページ目以降は、(現在ページ数 × 最大投稿数) - (最大投稿数から1件除外)
        //最大投稿数が9件に設定して、3ページ目であれば、20件目〜28件目が表示される
        $offset = ($paged * $per_page) - ($per_page - 1);
    } else {
        //1ページ目であれば、1件除外する。
        $offset = 1;
    }
?>
<?php
    if(!is_paged()){
        //最新1件の情報を取得
        $first_args = array(
            'numberposts'    => 1
        );
        $first_posts = get_posts($first_args);
        if($first_posts){
            echo '<div class="firstBlock">';
            foreach($first_posts as $post){
                setup_postdata($post);

                //ここに1件目の情報を書く
                the_title();
                the_content();
            }
            echo '</div>';
            wp_reset_postdata();
        }
    }

    //2件目以降
    $args = array(
         'posts_per_page'    => $per_page
        ,'offset'            => $offset
    );
    $the_query = new WP_Query( $args );
    if ( $the_query->have_posts() ){
        echo '<ul>';
        while ( $the_query->have_posts() ){
            $the_query->the_post();

            //ここに2件目以降の情報を書く
            the_title();
            the_content();
        }
        echo '</ul>';
    }

    //ページネーション
    if (function_exists('pagination')) {
        if(count($the_query->posts) > 0){
            $max_pager_num = ceil($the_query->max_num_pages);
            pagination($max_pager_num);
        }
    }
    wp_reset_query();
?>

上記だけでは、改ページリンクに問題が出てきますので、
下記コードをfunctions.phpに記述することで、解決します。

<?php
    function special_offset_pregp_wpse($qry) {
        if ($qry->is_main_query() && !is_admin()) {
            $ppg = get_option('posts_per_page');
            $offset = 1;

            $offset = $offset + ( ($qry->query_vars['paged']-1) * $ppg );
            $qry->set('posts_per_page',$ppg);
            $qry->set('offset',$offset);
            add_filter('found_posts', 'special_offset_pregp_fp_wpse', 1, 2 );
        }
    }
    add_action('pre_get_posts','special_offset_pregp_wpse');
    function special_offset_pregp_fp_wpse($found_posts) {
        return $found_posts - 1;
    }
?>

例えば、「1ページに表示する最大投稿数」を9件にして、記事が10件あった場合、2ページ目へのページネーションリンクが発生してしまいます。
もちろんoffsetで、表示件数を-1しているため、2ページ目へ行っても記事が表示されることはありません。

参考サイト:http://wordpress.stackexchange.com/questions/105496/how-to-adjust-found-posts-so-that-it-accounts-for-offset-and-pagination

コメント

スポンサーリンク
タイトルとURLをコピーしました