こんにちは。
管理人です。
かなり前から問題だったんですが、記事一覧ページ、アーカイブページ(archive.php)で下のようなページネーションのプラグインが表示されないなどの問題がありました。
- WP-PageNavi
- WP-Paginate
問題の症状として、
- 2ページ目以降が404エラーになる
- アーカイブページで2ページ目も1ページ目と同じ内容になる
- ページネーションのページ数と記事数がぐちゃぐちゃ
などがあります。
私も仕事でwordpressをカスタマイズしているのでこの問題は毎回厄介でした。
今回は、wordpressをカスタマイズしているwebエンジニアたちがつまずいてしまいがちな、ページネーションプラグイン「WP-PageNavi」のエラー問題を解決するプログラムをお伝えしようと思います。
実際のソースを書いてみる
では早速ソースを書いてみます。
記事一覧のプログラムから書いています。
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$posts_per_page = 10; //1ページの中に出力する記事数を定義
query_posts($query_string . '&posts_per_page='.$posts_per_page.'&paged=' . $paged);
$args = array(
'post_type' => 'sample', //カスタム投稿タイプ「sample」
'posts_per_page' => $posts_per_page, //1ページの中に出力する記事数(上の変数で定義する)
'paged' => $paged,
'order' => 'DESC', //新しい順のソート(「ASC」にすると古い順)
);
?>
<?php $my_query_sample = new WP_Query( $args ); ?>
<?php if ($my_query_sample->have_posts()): ?>
<div class="content_list">
<ul>
<?php while ( $my_query_sample->have_posts() ) : $my_query_sample->the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>">
タイトル:<?php the_title(); ?><br>
内容抜粋:<?php echo mb_substr(get_the_excerpt(), 0, 70); ?><br>
投稿日時:<time datetime="<?php the_time('Y-m-d'); ?>T<?php the_time('H:i:sP'); ?>"><?php the_time('Y.m.d'); ?></time>
</a>
</li>
<?php endwhile; ?>
</ul>
</div>
<?php else: //記事が1つも無い場合 ?>
<p>現在表示できる記事はありません。</p><br>
<div class="btn">
<a href="<?php echo esc_url(home_url()); ?>/">TOPへ戻る</a>
</div>
<?php endif; ?>
<?php if(function_exists('wp_pagenavi')) { //ページネーションプラグイン
wp_pagenavi(array('query'=>$my_query_sample));
} ?>
<?php wp_reset_postdata(); wp_reset_query();?>
このソースはページネーションプラグインの「WP-PageNavi」を使った場合の書き方ですが、「WP-Paginate」を使いたい方は、
<?php if(function_exists('wp_pagenavi')) { //ページネーションプラグイン
wp_pagenavi(array('query'=>$my_query_sample));
} ?>
の部分を
<?php if(function_exists('wp_paginate')) {
wp_paginate(array('query'=>$my_query_sample));
} ?>
と書き換えれば「WP-Paginate」でも同じように動作します。
そして、このプログラムは、下記条件下の基で動作します。
- ページ内でループが1つであるときのみ
- $argsで定義している
‘post_type’ > ‘sample’, //カスタム投稿タイプ「sample」
はそのアーカイブページ(archive-〇〇〇〇〇〇.php)を一致させる
もう一つ重要な設定
さて、上でお伝えしたソースで、晴れてページネーションを表示、実装できたかと思いきや、実はもう一つ重要な設定が必要なのです。
上のプログラムの
query_posts($query_string . '&posts_per_page='.$posts_per_page.'&paged=' . $paged);
の部分は、「1ページに表示する最大投稿数」を設定している部分です。
「1ページに表示する最大投稿数」と聞くと、wordpressを頻繁に触っている方は気付いたかもしれませんね。
これはワードプレスの管理画面の
[設定] > [表示設定] > [1ページに表示する最大投稿数]
で確認、設定することができます。
1ページに表示する記事数を設定するときに編集するのですが、これがページネーションにも影響を与えるのです。
しかし、複数のカスタム投稿タイプを使っているサイトで複数のアーカイブページが存在する場合、それぞれのカスタム投稿アーカイブページで記事を一覧表示するときに何記事表示させるのか、自由に決めることができないのです。
つまり、 [1ページに表示する最大投稿数] で20と設定したとすると、カスタム投稿タイプ「news」のアーカイブページ(archive-news.php)でも、カスタム投稿タイプ「products」 (archive-products.php) でも同じように20件記事が表示されてしまいます。
これを各アーカイブページで自由に記事の表示件数を設定するためのソースが
query_posts($query_string . '&posts_per_page='.$posts_per_page.'&paged=' . $paged);
ということです。
今回お伝えしたプログラムでは変数を使って
$posts_per_page = 10; //1ページの中に出力する記事数を定義
query_posts($query_string . '&posts_per_page='.$posts_per_page.'&paged=' . $paged);
としています。👍
なぜなら、$posts_per_pageという変数は、
$args = array(
'post_type' => 'sample', //カスタム投稿タイプ「sample」
'posts_per_page' => $posts_per_page, //1ページの中に出力する記事数(上の変数で定義する)
'paged' => $paged,
'order' => 'DESC', //新しい順のソート(「ASC」にすると古い順)
);
の部分でも使うからです。
あとがき
さて、今回はアーカイブページでページネーションプラグインを使おうとしたときに発生するバグの解決策をお伝えしました。
「WP-PageNavi」や「WP-Paginate」は非常に重宝するプラグインですが、アーカイブページでのみ不具合があり、それを解決する方法がなかなかネットに落ちておらず苦しんでいるエンジニアは多いのではないでしょうか。
ぜひ、wordpressをカスタマイズしているwebエンジニアの方々の役に立ててほしいです。
もし少しでもお役に立てれば「役に立った!」などのコメントを頂けると非常に喜びます っっ !!!
メールアドレスとサイトの入力欄がありますが、メールアドレスは捨てアドや適当なアドレスでも問題ありませんしサイトは任意です。
お気軽にコメントいただけると非常に喜びますっっ !!!(2回目)
それでは、今回はこの辺で。
最後まで読んでいただきありがとうございました。
余談。。。
ページネーションプラグインは、毎回「WP-PageNavi」を使っていく方針だったんですが、カスタム投稿アーカイブページとどうも相性が悪く、困っていたわけですが、幸い、私の職場の上司がシステムエンジニアでPHPはもちろん、そのほかの言語も使いこなす「すごい人」なので、毎回ページネーション(ページ送り)の部分はお願いしていました。
ただ、毎回お願いして他の作業の手を止めてしまうのも申し訳ないし私一人でどうにかできないものかと、その上司が作ってくれたページネーションのプログラムをじっと刮目してみると、あることに気付きました。
記事を一覧表示するプログラム自体が私が作っていたものと少しだけ違っていました。
その部分を突き詰めていくと、私が作っていたプログラムにはページネーションに必要なプログラムが欠けていたことに気付いたのです。
そんなことがあり、この記事で書いたソースに行きついた、という、、、余談でした。笑
昔の人はよく言ったもので、諦めたらそこで試合終了、ですね。
あきらめずに解決策を探してよかったです^^
コメントを残す