プラグインなしでWordPressにタグを優先しつつ同じカテゴリの関連記事を表示する

関連記事

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

同じカテゴリかつ同じタグの記事があれば優先的に表示、なければ同じカテゴリの記事を取得して関連記事としてプラグインなしで表示したかったのですが、軽く検索した感じWEB上になさそうだし大して難しくもなさそうなので自分で書きました。

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

WordPress関連記事 プラグインなし

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ができたら即座に乗り換えたいんですけどね。

関連記事

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL