プラグインなしでWordPressに関連記事を表示する

関連記事

プラグインなしで関連記事をいい感じに取得して表示したい

  • 同じカテゴリかつ同じタグの記事があれば優先的に表示
  • カテゴリとタグが一致する記事がなければカテゴリのみが一致する記事を取得して関連記事として表示

上記をプラグインなしで実現しようと思います。

軽く検索した感じだとWEB上になさそうだし、大して難しくもなさそうなので自分で書きました。

BootStrap3の使用を前提としたHTMLなので使う場合は適宜書きかえてください。

functions.php

add_filter('the_content', 'addRelation');
function addRelation($content)
{
    if (is_single()) {
        $id = get_the_ID();
        $showMaxCount = 5;
        $tags = get_the_tags($id);
        $categories = get_the_category($id);
        if (!$categories) {
            return $content;
        }
        $categoriIds = [];
        $tagIds = [];
        $args = [
            'post_type' => 'post',
            'post__not_in' => [$id],
            'showposts' => 5,
            'orderby' => 'rand'
        ];
        foreach ($categories as $category) {
            $categoryIds[] = $category->term_id;
        }
        $args['category__in'] = $categoryIds;
        // tag
        $sameTagQuery = [];
        if ($tags) {
            foreach ($tags as $tag) {
                $tagIds[] = $tag->term_id;
            }
            $args['tag__in'] = $tagIds;
            $sameTagQuery = new WP_Query($args);
        }
        // category
        if (isset($args['tag__in'])) {
            unset($args['tag__in']);
        }
        $sameCategoryQuery = new WP_Query($args);
        if ($sameCategoryQuery->have_posts()) {
            $content .= '<h3>関連記事</h3><ul class="list-unstyled">';
            $excludeIds = [];
            $count = 0;
            if ($sameTagQuery && $sameTagQuery->have_posts()) {
                while ($sameTagQuery->have_posts()) {
                    if ($count >= $showMaxCount) {
                        break;
                    }
                    $sameTagQuery->the_post();
                    $excludeIds[] = get_the_ID();
                    $content .= sprintf('<li><a href="%s">%s<p>%s</p></a></li>', get_the_permalink(), get_the_title(), get_the_post_thumbnail(get_the_ID(), 'thumbnail'));
                    $count++;
                }
            }
            while ($sameCategoryQuery->have_posts()) {
                $sameCategoryQuery->the_post();
                if ($count >= $showMaxCount || in_array(get_the_ID(), $excludeIds)) {
                    break;
                }
                $content .= sprintf('<li><a href="%s">%s<p>%s</p></a></li>', get_the_permalink(), get_the_title(), get_the_post_thumbnail(get_the_ID(), 'thumbnail'));
                $count++;
            }
            $content .= '</ul>';
            wp_reset_query();
        }
    }

    return $content;
}

WP_Queryの制限

どうやらWP_QueryはタグとカテゴリのIN句をOR条件で検索することができないようで、まず同じカテゴリかつタグの記事を検索、見つからなければカテゴリのみ一致する記事を検索すると言う冗長なコードになっています。

whileとhave_posts()で逐次処理する仕様も気持ち悪いのですが、もうWordPressにあまり期待していないのでコードを改良する気も起きず放置。

ブロックエディタはゴミだし、余計なタグを勝手に入れるし、ビジュアルエディタとコード入力を切り替えると自動保存されないことがあるし、実績にあぐらをかいたゴミCMSとしか言いようがありません。

プラグインとショートコードの互換性があるもっと優れた後継CMSができたら即座に乗り換えたいんですけどね。

関連記事

SNSでシェアする