遥か昔、100億年ほど前に作っていたテーマを使用していたサイトで突然アーカイブページに何も表示されなくなったと連絡がありました。ブラウザの表示でなければ、何もして無ければ変化が起こるはずがないので、何を変更したか訊いたところ「WordPressとプラグイン」をアップデートしたという事でした。はい。100%コレが原因で挙動が変わったわけですね。
「突然動かなくなった」じゃなくて、「アップデートしたら」って最初から言ってください...
(´-`).。oO(普段からもっとこまめにアップデートしておいておくれよ...)
よく解ってない運用者に期待するのが間違っているのです。はい。愚痴を言っても始まらないので、調査しましょう。
Note.
- アップデートされたWordPressのバージョン:
4.6.1
「title」というスラッグ名のタクソノミーのアーカイブページで投稿が表示されていない
問題のページを確認したところ、title
という名前のタクソノミーアーカイブページで問題が発生していました。
タクソノミーの登録はこのようになっていました。
<?php // function.php add_action('init', 'my_custom_init'); function my_custom_init() { // 中略 // $arg = array( 'labels' => $labels, 'public' => true, 'show_ui' => true, 'hierarchical' => true, 'show_tagcloud' => true, ); register_taxonomy('title', 'product', $arg); // 中略 // }
product
というカスタム投稿タイプのタクソノミーになっています。
他のproduct
に紐付けられたタクソノミーのアーカイブページは問題なく表示されており、タクソノミーの登録方法にも特に違いはありませんでした。
また、function.php
でこのタクソノミーの際に何か処理を行ってるコードも特にありませんでした。
何が原因になっているか探す
問題がよくわからない時は、糸口を掴むために問題が起きているページと正常なページのWordPressのグローバル変数 $wp_query
をダンプして見比べて違いを探していきます。
問題となっているタクソノミーのアーカイブページのテンプレートはtaxonomy-title.php
です。
<?php var_dump( $wp_query ); ?>
上記コードをテンプレートに記述して見たところ、["posts"]=> &array(0)
となっており取得できている投稿が0件となっていました。
どうやら投稿を取得するクエリに問題がありそうです。
このページを表示するのに使われたクエリは$wp_query
オブジェクトから下記で見ることができます。
<?php var_dump( $wp_query->request ); ?>
タクソノミー名が投稿タイトルと一致するものを探していた!
title
タクソノミーがhoge
のアーカイブページ (url: http://site-name/title/hoge
) の時、次のようなクエリが使用されていました。
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND wp_posts.post_title = 'hoge' AND ( wp_term_relationships.term_taxonomy_id IN (8) ) AND wp_posts.post_type = 'product' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 20
WHERE句におかしなものがありますね...
_人人人人人人人人人人人人人人人人人人_ > AND wp_posts.post_title = 'hoge' <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
どうみても、投稿タイトルとタクソノミー名が一致しているものを探しています。本当に有難うございます。
当然、他の問題なく表示されているタクソノミーのアーカイブページにはpost_title =
という条件はありませんでした。
リファレンスを見るかぎり、title
というタクソノミー名は予約語にはなっていない様なのですが、title
というタクソノミー名でアーカイブなどの絞込の条件がquery_vars
の中にあると、投稿のタイトルの検索と誤認してしまってうようです。
<?php var_dump( $wp_query->query_vars ); ?> array(66) { ["title"]=> string(4) "hoge" // ← これが post_title = 'hoge' の条件になってるっぽい ["error"]=> string(0) "" ["m"]=> // 以下略
pre_get_posts アクション内でクエリの条件を修正する。
意図しない条件が入ってしまっているので、WordPressのクエリを変更する pre_get_posts
アクション内でクエリの条件を変更します。
<?php // function.php function my_posts_query( $query ) { if( !is_admin() && $query->is_main_query() ) { if( is_archive() && is_tax('title') ) { // query_vars["title"]を削除 unset($query->query_vars["title"]); // query_vars["title"]を削除 するとナゼかタクソノミーの指定も無くなってしまうので、改めて追加する $term = $query->query["title"]; $tax_query = array( array( 'taxonomy' => 'title', 'field' => 'slug', 'terms' => $term, ), ); $query->set('tax_query', $tax_query); } } } add_action('pre_get_posts', 'my_posts_query');
これで、問題なくtitle
というタクソノミーのアーカイブページが問題なく表示されるようになりました。
リファレンスの予約語の欄にtitle
という単語は無かったのですが、WordPress内で一般的に使われている単語はカスタム投稿やタクソノミー名に使うにはキケンがあると思っておいた方が良いかもしれません。
[参考]
- Function Reference/register taxonomy « WordPress Codex
- 関数リファレンス/register taxonomy - WordPress Codex 日本語版
- 関数リファレンス/WP Query - WordPress Codex 日本語版
- pre_get_posts でカスタムポストをカスタムタクソノミーで絞込みしようとして、どっぷりハマってあっさり抜けだした方法 | テクニカルノート
- 作者: 新海誠,東宝,コミックス・ウェーブ・フィルム,角川書店
- 出版社/メーカー: KADOKAWA/角川書店
- 発売日: 2016/08/27
- メディア: 単行本
- この商品を含むブログ (13件) を見る