WordPress関連記事から特定カテゴリーだけ除外したい場合の実装例

WordPress

WordPress で記事下に関連記事を表示していると、運用ルールの都合で「このカテゴリーだけは関連記事の判定から外したい」というケースが出てくることがあります。

ここでは、実際に single.php に手を入れて、関連記事の抽出から特定カテゴリーだけを除外した実装例をご紹介します。

前提環境と状況

テーマ側で、single.php の末尾付近に「関連記事」用の WP_Query が組み込まれている

関連記事は、現在表示している投稿と同じカテゴリーに属する記事をランダムで取得する構造

記事自体には※例「恐竜」+その他の本来のカテゴリー(例:歴史、ニュースなど)が付与される運用

目的は「恐竜」カテゴリーだけ関連記事の判定からは外す。

元の single.php では、関連記事部分は概ね次のようなコードになっていました。

// related post *******************************************************************************
if ($options['show_related_post']) :
$categories = get_the_category($post->ID);
if ($categories) {
$category_ids = array();
foreach($categories as $individual_category) $category_ids[] = $individual_category->term_id;

$args=array(
'category__in' => $category_ids,
'post__not_in' => array($post->ID),
'showposts' => 8,
'orderby' => 'rand'
);
$my_query = new wp_query($args);
if($my_query->have_posts()) {
// ここから関連記事のHTML

この状態だと、記事についている全カテゴリーをそのまま関連記事の抽出条件として使うため、「恐竜」も含めて検索されてしまいます。

方針:WP_Query の前で「恐竜」だけを弾く

やることはシンプルで、関連記事用の $category_ids を作る時に、「恐竜」カテゴリーの term_id だけを除外する、という処理を足すだけです。

ポイントは以下の2つです。

get_cat_ID(‘恐竜’) で「恐竜」カテゴリーの ID を取得

foreach 内で、その ID に一致するカテゴリーを continue でスキップする

HTML 部分は一切触らず、「カテゴリ配列を組み立てる部分だけ」差し替えるのが安全です。

実際に行った修正コード

single.php の関連記事ブロックを、次のように書き換えます。

// related post *******************************************************************************
if ($options['show_related_post']) :
$categories = get_the_category($post->ID);
if ($categories) {

// 「恐竜」カテゴリを関連記事の抽出元から除外
$exclude_cat_id = get_cat_ID('恐竜');

$category_ids = array();
foreach ($categories as $individual_category) {
if ($individual_category->term_id == $exclude_cat_id) continue;
$category_ids[] = $individual_category->term_id;
}

$args = array(
'category__in' => $category_ids,
'post__not_in' => array($post->ID),
'showposts' => 8,
'orderby' => 'rand'
);
$my_query = new wp_query($args);
if($my_query->have_posts()) {
// ここから関連記事のHTML(元のまま)

この部分だけ差し替えれば十分です。

$exclude_cat_id = get_cat_ID(‘恐竜’);

foreach 内の if ($individual_category->term_id == $exclude_cat_id) continue;

この2点が実質的な変更箇所です。それ以外は元の構造を保っています。
なお、ループ後の

wp_reset_postdata();

は、グローバル $post を元に戻すために必要なので、そのまま残します。

動作イメージ

この変更により、実際の挙動は次のようになります。

記事には「恐竜」+「本来のジャンル」の2つ以上のカテゴリーが付与されている。

関連記事を引くときは、「恐竜」以外のカテゴリーだけを元にWP_Query が実行される。

念のため $category_ids が空の場合のガードを入れておくとより安全です。

例:

if (!empty($category_ids)) {
$args = array(
'category__in' => $category_ids,
'post__not_in' => array($post->ID),
'showposts' => 8,
'orderby' => 'rand'
);
$my_query = new wp_query($args);
if($my_query->have_posts()) {
// 関連記事HTML
}
wp_reset_postdata();
}

こうしておけば、「恐竜」だけが付いた記事が出てきても、変な関連記事クエリが走らず、単に関連記事が非表示になるだけで済みます。

まとめ

この手の「運用上、関連記事からどうしても外したいカテゴリー」が1つある時には、今回のようにテーマ側でカテゴリ配列を軽くフィルタしてしまうのが、一番シンプルで管理もしやすいかと思います。

コメント

タイトルとURLをコピーしました