pre_get_posts でアーカイブ(一覧)ページの表示を工夫する

メインクエリとサブクエリ

!query->ismain_query() にあるように、先のコードでは pre_get_posts に与えられるクエリがメインクエリかどうかを確認しています。 まずメインクエリサブクエリについて解説しておきます。メインクエリはページを表示するために必要になる、主要なクエリです。 これを変更してしまうと期待したページが表示されなくなる、とうことです。ではサブクエリは、というと、 メインクエリによって取得されるページに対して、さらに追加されたクエリです。

例えば、トップページを表示したい、という要求を満たすものがクエリがメインクエリであり、 そのトップページの中で、さらに新着ページを取得したい、という要求を満たすものがサブクエリです。

つまりここではメインクエリの場合には処理を行わず、サブクエリの場合にのみ処理を続行する、というコードを扱うことになります。

クエリの調整

取得したいページの条件を設定するには、クエリのパラメータを設定します。 WordPress で扱うことができるクエリのパラメータは別途調べてもらうとして、この例で示した 3 つのコードについて解説します。

set( 'posts_per_page', '5' ); は、取得する投稿の上限を 5 件までとする設定です。 set( 'post_type', array('page', 'post') ); は、取得する投稿の種類が固定ページまたは投稿ページであることを要求します。 複数の値を設定する場合は、array を利用することになります。

最後に set( 'category_not_in', '1'); ですが、これは取得する投稿のカテゴリのカテゴリID が、1 ではないことを要求します。 ここで一般的には、カテゴリID 1 は "未分類" です。ただし、このクエリ自体が上手く機能しないことがあるようです。 そういう場合には、$query->set( 'cat', '-1' ); のように、cat パラメータを設定します。 これで問題を回避できない場合には、何か異なる個所に原因を持っている可能性があります。

"未分類" を完全に識別できない問題

固定ページにカテゴリを設定することができるようにするとき、 ある固定ページにカテゴリが設定されないときは、そのカテゴリは表面上 "未分類" に見えます。 この空白による未分類は、カテゴリ設定されたページの"未分類"とは異なる点に注意が必要です。

クエリによってカテゴリが設定されていないページを取得する、という操作はできそうにないため、 カテゴリが設定されていない "未分類" の固定ページを一覧する、一覧から除くことができません。

例えばコンタクトやプライバシーポリシーなどのシステムライクなページをカテゴリなしの固定ページにしているとき、 新しく類似する固定ページを追加すると、新着一覧にその業務チックなページが表示されてしまいます。 もう少し例を具体化すると、プライバシーポリシーのページを新規に追加したとき、新着一覧ページにそのページが掲載されてしまうのです。 確かに新着ではありませんが、表示したくないものです。

この問題を解決するにはシステムライクなカテゴリ専用のカテゴリを設けることです。 そして対象のカテゴリ ID を示すページを取り除きます。 最も簡単な方法は、"未分類" のカテゴリをシステムライクなカテゴリ以外に設定しないことです。 するとカテゴリID = 1 となるページを除く仕組みがあらゆる個所で利用できます。