「WP_Query()」使っても先頭に固定表示ができない現象が見つかりました。
カテゴリーやタグで絞り込んだ状態だと、先頭に固定表示した投稿のみの一覧か、それ以外の一覧しか取得できないのです。
以前に「WordPressで「先頭に固定表示」が効かない!?解決法を調べたよ」で「WP_Query()」を使えば先頭に固定表示ができるようになると書いたのですが、それでは解決できない事例でしたので、少し調べてみました。
先頭に固定表示ができない
ことの発端は、トップページにカテゴリーで絞り込んだ状態で、最新の投稿を表示させてみたところ起こりました。
「先頭に固定表示」したものだけを表示することはできるのですが、「先頭に固定表示」が1件しかなければ1件しか表示しませんし、1件もが無ければ何も表示されなくなってしまいます。
5件表示しているうち、1件の「先頭固定表示」があれば、最初の1件は先頭固定表示、他4件は日付順で表示ということができないのです。
WordPressのバグ?
いろいろチェックしていくと「index.php」や「archive.php」などの一覧ページでもカテゴリー等で絞り込んでいると「先頭に固定表示」が有効になっていません。
自作のテーマが原因かなと思い、公式テーマ「Twenty Twenty-Four」で検証してみましたが、同じことが起こりました。
投稿インデックスを使っていれば、カテゴリーを超えた一覧ページでは「先頭に固定表示」が有効になりますが、カテゴリーで絞り込んでしまうと「先頭に固定表示」は無効になってしまいます。
投稿インデックスを使っていなければ、一覧ページは何かしらのカテゴリーで絞り込まれた状態になるわけですから「先頭に固定表示」が有効になるところが無いということになります。
解決策を考えてみる
いろいろ調べてみましたが、カテゴリー等で絞り込んだ状態で、先頭に固定表示をさせる良い方法は見つけることはできませんでした。
そこで、苦肉の策ですが、考えついた方法が下記の通りです。
- カテゴリー絞り込んであり、かつ、先頭に固定表示したものを取得
- 先頭に固定表示したものがあれば、その件数を取得
- 表示する数から先頭に固定表示した件数を引いて、それ以外の件数を算出する
- 先頭に固定表示を除外したカテゴリーで絞り込んだものを取得
- 2つのループを連続して表示
コードにするとこんな感じです。
「aaa」というスラッグのタームで絞り込んで5件表示させています。
// 先頭に固定表示を取得
$sticky_args = array(
'post_type' => 'post',
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => 5,
'post__in' => get_option('sticky_posts'),// 先頭に固定表示で絞り込み
'tax_query' => array(array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array('aaa'),
))
);
$sticky_posts = new WP_Query($sticky_args);
while($sticky_posts->have_posts()):$sticky_posts->the_post();
先頭に固定表示のループ
endwhile;
wp_reset_postdata();
// 先頭に固定表示した件数を取得して、その他の件数を算出
$other_count = 5 - $sticky_posts->found_posts;
// posts_per_pageが0以下だと全件取得してしまうので、算出した件数が1以上だったら、先頭に固定表示を除外した投稿を取得
if($other_count > 0):
// 先頭に固定表示を除外した投稿を取得
$other_args = array(
'post_type' => 'post',
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => $other_count,
'post__not_in' => get_option('sticky_posts'),// 先頭に固定表示を除外
'ignore_sticky_posts' => 1,// 先頭に固定表示の件数を引く
'tax_query' => array(array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array('aaa'),
)),
);
$other_posts = new WP_Query($other_args);
while($other_posts->have_posts()):$other_posts->the_post();
その他の投稿のループ
endwhile;
wp_reset_postdata();
endif;
WP_Query()を使っても「先頭に固定表示」できない まとめ
「front-page.php」などでスポット的に使うのはいいとしても、「archive.php」などのメインクエリの一覧ページにも適用させることは可能なのでしょうか?
1ページ目は何とかするとして、2ページ目・3ページ目があった場合はどうしたらいいのか、今のところ思いつきません。
カテゴリーを使わず、全てカスタム投稿で構成したら何とかなるのかな。