どういう意味かというと、WordPressで例えば「美味しいラーメン屋さん」というタイトルで「グルメ、ラーメン、安い」というタグが関連付けられている場合に関連記事を表示するという仕様で同一タグを含む記事一覧を取得するというのはよくあるのですが、そうではなく「ラーメン」というタグを含む記事の中で記事ではなく「ラーメン」以外のタグを関連タグとして取得するというもの。
なので「美味しいラーメン屋さん」という記事で「グルメ、ラーメン、安い」というタグの中から「ラーメン」というタグをクリックした時に「ラーメン」というタグを含む全ての記事の持つ他のタグ「はやい、こってり、おすすめ」といったタグだけを関連として抽出するというもの。
しかもタグの並び順として①タグの最終更新日順で②タグの記事カウント順というありそうでなかったややこしそうなもの。記事でなくタグを取得というのがミソでどうしようかと考えたのですが直接SQLを使うことにしました。
//呼び出し元(タグアーカイブのtag.php)
////関連キーワード 。<a>タグ付きのタグクラウド取得
<? echo related_tag_list(get_query_var('tag_id')); ?>
//functions.php
/**
* 特定のタグを含んだ関連する記事のタグクラウドを取得
* 記事の日付順にソートした後でカウントでソート
* @param $tagId タグID
*/
function related_tag_list($tagId){
global $wpdb;
//SQL取得
$query ="SELECT DISTINCT Tag.term_id, Tag.name, Tag.slug, Term.count"
." FROM (
SELECT $wpdb->posts.ID
FROM $wpdb->posts INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) WHERE 1=1
AND ( $wpdb->term_relationships.term_taxonomy_id IN ("
. $tagId .") )
AND $wpdb->posts.post_type = 'post'
AND ($wpdb->posts.post_status = 'publish' OR $wpdb->posts.post_status = 'private')
GROUP BY $wpdb->posts.ID
ORDER BY $wpdb->posts.post_date DESC
) AS Post"
." JOIN $wpdb->term_relationships AS Relate ON(Post.ID = Relate.object_id)
JOIN $wpdb->term_taxonomy AS Term ON(Relate.term_taxonomy_id = Term.term_taxonomy_id)
JOIN $wpdb->terms AS Tag ON(Term.term_id = Tag.term_id)
WHERE Term.taxonomy ='post_tag'
ORDER BY Term.count DESC";
$results = $wpdb->get_results($query); //実行
$taglist ="";
//HTMLタグ生成
foreach($results as $row) {
$id = $row->term_id;
$name = $row->name;
if($tagId != $id){
$taglist.= '<a class="tag" href="' . get_tag_link( $id ) . '">' . $name . '</a> ';
}
}
return $taglist;
}
最初にwp_term_taxonomyとwp_postsをJOINして記事の作成順でソートさせて該当するタグIDを含むサブクエリとタグの記事の取得件数を持つwp_term_relationshipsをJOINさせて取得。
HTMLでは該当するタグに関連するものなので当該のタグ以外いのものをHTMLと描き出し
とりあえずできたけどどうなんだろ
