STINGERでCFiltering「この記事を読んだ人はこんな記事も読んでいます」を実装する

2017年6月12日

CFiltering

ブログの記事を読んでいる読者に、「こんな記事もいかがですか?」と関連記事を提供すると、お互いにとても有益だと思います。

読者にとっては気になりそうな記事をすぐに読むことができますし、サイト運営者にとってもPVが上がる、SEOに有利などのメリットがあります。

ではその有益な関連記事をどうやって表示するか。

関連記事って実はランダム?

このブログで使用しているWordPressテーマSTINGER PLUSなど多くのテーマでは、関連記事は「記事と同じカテゴリーの記事をランダムに引っ張ってくる」仕様なので、あまり信頼性がありません。

WordPress Popular Postなどの関連記事表示プラグインもありますが、やはりPVが多い記事を表示などの単純な仕様になっています。

Amazonのように、きちんとした精度でこの記事を読んだ人はこんな記事も読んでいますとできないものでしょうか。

CFilteringを使えばできます

CFiltering

CFilteringとは、統計学的手法を用いてこの記事を読んだ人はこんな記事も読んでいますを精度高く実現するプラグインです。日本人が開発しています。

例えば、Amazonなどで商品を買うと、「この商品を買った人はこんな商品も買っています」と出ますよね?これが自分のブログでもできるようになります。

Amazon

ただ、このCFilteringプラグインのインストールは簡単なのですが、、導入方法が難しいです。すぐにCFilteringを導入できるWordPressのテーマはSimplicity2だけだと思います。

今回は、そんなCFilteringをSTINGERで表示させる方法を書いてみます。

functions.phpに追加

方法としてはシンプルです。

まずはCFilteringプラグインをインストールしましょう。他のプラグインと同様、WordPress管理画面からインストールして有効化するだけです。

CFiltering

その後、Wordpressのテーマ編集画面にて、functions.phpに下記のコードを追記するだけです。

add_action('get_template_part_kanren-thumbnail-on', function () {
    if (function_exists('cf_get_posts')) {
        $posts = cf_get_posts();
        if (count($posts) > 0) {
            $pre_get_posts = function ($query) use (&$pre_get_posts, $posts) {
                $num = $query->query_vars['posts_per_page'];
                $query->set('p', -1);
                $the_posts = function () use (&$the_posts, $posts, $num) {
                    remove_action('the_posts', $the_posts);
                    return array_slice($posts, 0, $num);
                };
                add_action('the_posts', $the_posts);
                remove_action('pre_get_posts', $pre_get_posts);
            };
            add_action('pre_get_posts', $pre_get_posts);
            return;
        }
    }
});

このコードを追記すると、STINGERのデフォルトの「関連記事」が、CFilteringを利用したこの記事を読んだ人はこんな記事も読んでいますに置き換わります。

データが少ない時は?

CFilteringで「この記事を読んだ人はこんな記事も読んでいます」を表示させるためには、ある程度の閲覧データすなわちPVが必要です。PV数が少ないと、「この記事を読んだ人はこんな記事も読んでいます」が判定できないからです。

データが少ない時にはSTINGERのデフォルトの関連記事が表示されます。

さらに一歩進めて

上記のコードは、「同時にアクセスされることが多い記事」を表示するため、例えば新規の記事はしばらくして同時にアクセスされたデータが溜まるまで、他のどの記事の関連記事にも入ることはありません。

そこで、新着記事を混ぜて無理やり表示させるコードも紹介します。(新着記事を1つ検索して存在したら、それが関連記事のトップでない場合に2番目に挿入します)

add_action('get_template_part_kanren-thumbnail-on', function () {
        if (function_exists('cf_get_posts')) {
            $posts = cf_get_posts();
            if (count($posts) > 0) {
                $new = get_posts(array(
                'suppress_filters' => true,
                'posts_per_page' => 1,
                'post_type' => 'post',
                'post__not_in' => array(get_the_ID())
                ));
                if (count($new) > 0) {
                    if ($posts[0]->ID != $new[0]->ID) {
                        foreach ($posts as $k => $v) {
                            if ($v->ID == $new[0]->ID) {
                                unset($posts[$k]);
                                break;
                            }
                        }
                        if (count($posts) > 0) {
                            array_splice($posts, 1, 0, array($new[0]));
                        } else {
                            $posts = array($new[0]);
                        }
                    }
                }
                $pre_get_posts = function ($query) use (&$pre_get_posts, $posts) {
                    $num = $query->query_vars['posts_per_page'];
                    $query->set('p', -1);
                    $the_posts = function () use (&$the_posts, $posts, $num) {
                        remove_action('the_posts', $the_posts);
                        return array_slice($posts, 0, $num);
                    };
                    add_action('the_posts', $the_posts);
                    remove_action('pre_get_posts', $pre_get_posts);
                };
                add_action('pre_get_posts', $pre_get_posts);
                return;
            }
        }
    });

開発されたTechNote氏に感謝します!