「何言ってるんだこの人???」
・・・と、言われるかもしれませんが。
WordPressでカテゴリ一覧やターム別一覧を表示すると、デフォルトで、もれなく子孫カテゴリの記事も含まれます。「えっ?なんでwww」と、思いますが、そういう仕様のようで・・・。
百聞は一見にしかず。
こちらをご覧ください https://learning.ccc-labo.net/category/followup/
この「勉強会のフォローアップ」というカテゴリには子カテゴリがあります。
勉強会のフォローアップ
└条件分岐いろいろ
└自習課題
「勉強会のフォローアップ」の一覧には、「勉強会のフォローアップ」、「条件分岐いろいろ」、「自習課題」の3つのカテゴリのいずれかを選択している記事が表示されています。
かえって都合が良いこともあるので、私はブログを書くときはあまり気にしていないです。それでも時には、子カテゴリの記事は不要で、純粋に、そのカテゴリを選んでいる記事だけが表示されてほしいということもあります。
というわけで、「WPのカテゴリ(ターム)別一覧から子カテゴリの記事を外す」方法です。
以下に書く方法やサンプルコードは、下記の「参考記事」をもとにしました。
https://hseki-luckey.hatenablog.jp/entry/2018/01/16/233106
考え方についても、この記事を参考にしているので、先にこちらを読んでおかれると以下の理解が早いと思います。
parse_tax_query を使って解決する
parse_tax_query ってなんやねん、、、と思っていますが、当方、フィルターとかアクションとかがよくわかってないほどの理解度なので、説明できません。
なので、さくっとサンプルコードです。テーマの functinos.php に書いて使います。
function custom_search_parse_tax_query($query){
if ( is_admin() || ! $query->is_main_query() ){
return;
}
if( $query->is_tax('hoge_cat') ){
$query->tax_query->queries[0]['include_children'] = false;
}
}
add_action('parse_tax_query', 'custom_search_parse_tax_query');
これでOKです。
5行目の $query->is_tax('hoge_cat')
部分が、「子カテゴリの記事をなくす」の対象になるアーカイブの条件を書いている部分です。
カテゴリだったら $query->is_category()
特定のタームだったら $query->is_tax('hoge_cat', 'foo')
などとします。WPの条件分岐についてはこちら。
6行目の部分で、「クエリの中の tax_query の中の queries の中の0番目の中にある include_children の値を false に変えている」ということだと理解しています。
ただ、これは、何かの条件で「queries の0番目」の位置が変わってしまったら効かないかエラーになったりしそうかな?と思います。
その場合はクエリの中身を見て正しく書き直すと良いと思います。
pre_get_post だと何が起きている?
以前にこの方法で試したことがあったのですが、「参考記事」ではSQLのクエリが増えることや処理時間が伸びることを理由に、失敗例とされています。(当方、SQLのクエリは理解できないのと、まだ記事が少ない状況で試したので、いずれも実感できず・・・)なので、なにかしら「余計なことをしている」印象を持っています。
こちらもコードは functions.php に書きます。
function custom_category_archive_query($query){
if ( is_admin() || ! $query->is_main_query() ){
return;
}
if( $query->is_tax('hoge_cat') ){
$term = get_queried_object();
$tax_query = array(
array(
'taxonomy' => $term->taxonomy,
'field' => 'term_id',
'terms' => array($term->term_id),
'include_children' => false
)
);
$query->set('tax_query', $tax_query);
}
}
add_filter('pre_get_posts', 'custom_category_archive_query');
これでも、ねらった表示にはなります。しかし、遅かったり余計なSQL文がはいると・・・・・いったい何が起こるのか、できれば理解したい。
で、SQLは読めないので、いっそ、$query を見てみようと思いつき。
taxonomy.php に以下を記載。
echo '<pre>'. print_r( $wp_query, true ) .'</pre>';
ダサかろうが全て実際に表示してみるスタイル….
以下のような表示が得られます。
WP_Query Object
(
//省略
[tax_query] => WP_Tax_Query Object
(
[queries] => Array
(
[0] => Array
(
[taxonomy] => archive_cat
[terms] => Array
(
[0] => 9
)
[field] => term_id
[operator] => IN
[include_children] =>
)
[1] => Array
(
[taxonomy] => archive_cat
[terms] => Array
(
[0] => zaidanjyouhou
)
[field] => slug
[operator] => IN
[include_children] => 1
)
)
[relation] => AND
//省略
注目は [queries] の中身で、[1]の方が、WPのデフォルトで出てくるもので、[0]の方が、おそらく、pre_get_posts を書くことによって追加されたものだと思います。
やりたいことはあくまで、 [1] に書いてある [include_children] => 1 を0(表記なし)にすること、なので、pre_get_posts ではやはり「余計なことをしてる」ということになるのかと。