WordPressテーマ「Cocoon」を使用していたところ、サイドバーに設置したカテゴリー別人気記事ランキングがなぜか表示されませんでした。
その原因の調査でいろいろと調べました。
なお、今回のバージョンは以下の通りです。
- Cocoon 1.5.5.1
WordPressテーマ「Cocoon」の人気記事ランキング
Cocoonで人気記事ランキングを表示させるには、「Cocoon設定」⇒「アクセス集計」でアクセス集計を有効化しておく必要があります。
そして、人気記事ランキングのウィジェットが用意されているので、それを使って任意の場所に設置することができます。
ウィジェットの設定では、以下の2つの表示モードを選択できます。
- 全ての人気記事
- カテゴリ別人気記事
「全ての人気記事」は全記事のランキングで、全てのページで表示されます。
一方、「カテゴリ別人気記事」はカテゴリごとのランキングなので、投稿・カテゴリページで表示され、トップページやタグページなどでは表示されなくなります。
そして、「全ての人気記事」を選択すると問題なくランキングが表示されるのですが、「カテゴリ別人気記事」を選択すると、投稿ページやカテゴリーページを見ても画面には「人気記事は見つかりませんでした。」と出ています…なぜ?
PV数は増えているので集計はされているのに…。
カテゴリー別人気記事が表示されない原因の調査
ひとまず思い当たるところから、以下の内容を見ていきました。
- 設定の漏れ
- 競合するプラグインなど
- キャッシュ
しかし、Cocoonの設定でそれらしきものも見当たらず、ググっても有益な情報は見つからず…。
キャッシュ系のプラグインやアクセス集計のプラグインは入れておらず…。
Cocoonのキャッシュを削除して、ブラウザキャッシュを削除して、サーバーのキャッシュ機能を無効にして、ブラウザをプライベートモードで閲覧しても変わらず…。
ローカルでデバッグして原因が判明
仕方なくローカル環境でデバッグして、表示されない原因を探りました。
WordPressのデバッグ方法については、こちらの記事を参照してください。
人気記事ランキングは独自のウィジェットが作られているので、ウィジェットを追加するWordPressの関数は「register_widget」だから、文字列検索してみるとそれっぽいのが見つかりました。
そこから以下の順に辿り、「access-func.php」に辿り着きます。
- cocoon-master\lib\widgets\popular-entries.php
- PopularEntryWidgetItem::widget
- cocoon-master\lib\html-forms.php
- generate_popular_entries_tag
- cocoon-master\lib\page-access\access-func.php
- get_access_ranking_records
「access-func.php」内の「get_access_ranking_records」関数で人気記事のデータを以下のようなSQLで取得していますが、これの結果が0件になっています。
SELECT
ID,
sum_count,
post_title,
post_author,
post_date,
post_modified,
post_status,
post_type,
comment_count
FROM
(
SELECT
terms_accesses.post_id,
SUM(terms_accesses.count) AS sum_count,
terms_accesses.term_taxonomy_id,
terms_accesses.taxonomy
FROM
(
#カテゴリとアクセステーブルを内部結合してグルーピングし並び替えた結果
SELECT
wp_cocoon_accesses.post_id,
wp_cocoon_accesses.count,
wp_term_relationships.term_taxonomy_id,
wp_term_taxonomy.taxonomy
FROM
wp_term_relationships
INNER JOIN
wp_cocoon_accesses
ON wp_term_relationships.object_id = wp_cocoon_accesses.post_id
INNER JOIN
wp_term_taxonomy
ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE
wp_cocoon_accesses.post_type = 'post'
AND wp_cocoon_accesses.date BETWEEN '2019-01-16' AND '2019-01-23'
AND wp_term_relationships.term_taxonomy_id IN(170)
AND wp_term_taxonomy.taxonomy = 'category' #WHERE句
GROUP BY
wp_cocoon_accesses.id
) AS terms_accesses #カテゴリとアクセステーブルを内部結合した仮の名前
GROUP BY
terms_accesses.post_id
ORDER BY
sum_count DESC
LIMIT 5
) AS ranks_posts
INNER JOIN
wp_posts
ON ranks_posts.post_id = wp_posts.id
WHERE
post_status = 'publish'
AND post_type = 'post'
なぜ0件なのか、SQLを細かく分けて実行していくと、入れ子になっている一番内側のWHERE句の条件「wp_term_relationships.term_taxonomy_id IN(170)」が原因のようです。
WordPress Codexを参考に、カテゴリー関係のテーブル「wp_terms」「wp_term_taxonomy」「wp_term_relationships」を順に見ていくと、実データは以下のようになっています。
「wp_terms」:カテゴリーのデータが保存されているテーブル。
term_id | name | slug | term_group |
---|---|---|---|
170 | Windows | windows | 0 |
「wp_term_taxonomy」:カテゴリーの分類用テーブル。
term_taxonomy_id | term_id | taxonomy | description | parent | count |
---|---|---|---|---|---|
284 | 170 | category | 0 | 46 |
「wp_term_relationships」:記事とカテゴリーを関連付けるテーブル。
object_id | term_taxonomy_id | term_order |
---|---|---|
5871 | 284 | 0 |
プログラムでカテゴリーID(term_id):170を取得してSQLの条件を組み立てていますが、term_taxonomy_idに対して検索しており、284と一致せず、0件になっているようです。
しかし、別のWordPressサイトのデータを見てみると、term_idとterm_taxonomy_idは一致していて問題なくカテゴリー別人気記事が表示されているんですよね…。
本来は一致しているものなのか?
それとも、カテゴリー・タグの見直しやサーバー・ドメイン移行など行って運用してきて、いろいろと修正を加えてきましたので、それで一致しなくなったのか?
謎のままです。
カテゴリー別人気記事を表示させるように修正
ということで、一旦プログラムを修正してカテゴリー別人気記事を表示させました。
「access-func.php」内の条件設定箇所を1行コメントアウトにして、以下のようにterm_idに対する条件へと修正しました。
//カテゴリー指定
if (is_ids_exist($cat_ids)) {
$cat_ids = implode(',', $cat_ids);
//$where .= " AND {$term_relationships}.term_taxonomy_id IN ({$cat_ids}) ".PHP_EOL;
$where .= " AND {$term_taxonomy}.term_id IN ({$cat_ids}) ".PHP_EOL;
}
これで、カテゴリーページや投稿ページで属するカテゴリーの人気記事が表示されるようになりました。
この件は、後でフォーラムで聞いてみたいと思います。
【2019年1月29日 追記】最新テーマで問題対応済み
最後に
今回は、WordPressテーマ「Cocoon」で、サイドバーに設置したカテゴリー別人気記事ランキングが表示されない原因の調査と対応を行いました。
テーマ本体の不具合対応もしていただきましたので、これからも使い続けたいと思います。
コメント
まさにこれと同じ理由でかなり前から悩んでいたので助かりました!
>こむたんさん
コメントありがとうございます。
お役に立てて良かったです。
Cocoonフォーラムで聞いてみたところ、早速対応していただき、この問題の対応をソースコードに反映してくれました。
最新のテーマで対応済みです。
WordPressでのテーマ更新の配信はもう少し後で、v1.5.7以降で対応済みのようです。