ブログ運営において、たとえサイト内に投稿が100個あったとしても、コンスタントに閲覧してもらえる投稿はそのうち10個程度になってしまうのがほとんどです。 いろいろなところに要因があるわけですが、残りの90個を頑張ってみてもらうようにするよりは、その10個をより見てもらえるように訪問者の目につくところで宣伝することが大切です。
そこで閲覧数に応じて自動的に中身が変わる「人気記事リスト」のようなものがあったら便利でしょう。
今回は、プラグインなしで作る人気記事リストを紹介していきます。なお、ちょっと癖が強い手法ですのでプログラミング知識があまりない方には難しいかもしれないです…
人気記事プラグインを使わない理由
BableTechではかつて、人気記事を自動的に表示してくれる「WP Popular Posts」という有名なプラグインを利用していました。 しかし訳あってこの度、そのプラグインの利用をやめて自作することにしました。
重い
プラグインの実態はPHPプログラムですが、そのPHPプログラムはサイトが表示されるたびに読み込まれます。そのため、プラグインの数が増えると単純にサイトの表示速度が遅くなってしまうのです。
WP Popular Postsはとても高機能で、おそらく複雑なPHPコードでできているのでしょう。サイトに与える影響は大きく、無効化にしてみるだけで体感でもわかるくらいサイトが軽くなりました(個人的に)
そのため、最低限の機能だけ備えているものを自分で作ればよりサイトが軽くなるのではないかと考えて、自作することに決めました。
脆弱性?
これは割と後付けなのですが、最近WP Popular Postsに脆弱性が見つかったみたいなニュースを見たりして、なんだか怖くなったので自分で作ることにしました。
プラグインってPHPファイルで動いていて、直接WordPressのデータベースを操作する権限があるわけですが、脆弱性があったら記事が全部削除される危機とかも普通にあるんですよね。
そしてWP Popular Postsくらい有名なプラグインになると多くのサイトが採用していることから、攻撃の対象になりやすく、リスクが高まってしまうのです。人気プラグインを使うというのはそういうリスクを抱えることにもつながってしまうのがちょっと怖いところですね。
勉強のため
これはもう完全に私情なのですが、プラグインの機能を自分で作ることでPHPの知識やデータベースの知識等をつけることができるかと思い、自分で作ることに挑戦したというのもあります。
こういう知識をつけておけば、万が一プラグインのサポートが切れたときとかにダメージを受けなかったり有料化したときもダメージを受けなかったりするので良いです。
サポートが切れてしまったらセキュリティ的にも危ないわけですしね…
人気記事表示機能の作り方
それでは早速実装してみたいと思います。PHPの知識やJavaScriptの知識がある程度必要になってきますのでご注意ください。
記事閲覧情報格納データベースを用意する
今回一番癖が強いのがここですね。記事の閲覧情報を格納するためだけのデータベースのテーブルを用意します。 WordPress投稿情報のメタ情報として格納する手もあるわけですが、別でデータベースを作ってしまえばさらに軽くできるのではないかと思い、そうしました。
わざわざデータベースを用意しなくても、JSON形式で閲覧情報を記録するとかでも良い気がします。
CREATE TABLE `popular_post` (
`post_id` int(8) NOT NULL,
`view_num_day` int(8) DEFAULT 0,
PRIMARY KEY (`post_id`)
)
任意のデータベースに、例えば上のようにして「popular_post」というテーブルを作ります。ちなみに私が使っているのはMySQLです。 テーブルの構造は単純で、投稿ID、一日の閲覧数だけ格納できるものとなっています。 この上に、一か月の閲覧数とかも追加したくなったら追加しようかと思います。
スクリプトを作成
私が考えているのは、
- 投稿を表示する
- JavaScriptで投稿IDをPHPプログラムに送信
- PHPプログラムで閲覧数をカウントアップ
- PHPプログラムから人気記事方法をJavaScriptに返信
- JavaScriptが人気記事情報を本文中に挿入
という流れです。まずはこのデータのやり取りの中間を担っているスクリプトの作成です。とその前に、JavaScriptに投稿IDを持たせるためにはPHPの協力が必要ですね。
<script>
const this_post_id = <?php if($_SERVER["REMOTE_ADDR"] != "自分のIPアドレス"){the_ID();}else{echo "''";} ?>;
</script>
こういうのを投稿のテンプレート(single.php)とかに記述しておけば、JavaScriptがID情報を取得することができます。
jQuery(function(){
if(typeof this_post_id === 'undefined'){this_post_id = "";}
//閲覧数をカウントアップ
jQuery.ajax({
async: true,
type: "POST",
url: "popular.php",
data: {
"mode": "get_pp",
"id": this_post_id
}
}).done(function (data) {
data = JSON.parse(data);
jQuery("ul#sidebar_popular_list").html(data["pp_DOM"]);
});
});
ページ読み込み完了後に実行するようにしています。そしてpopular.phpというPHPプログラムにリクエストを送信しています。 このプログラムはこれから作ります。
そしてそのリクエストの返信として人気記事のHTMLコードを取得して、それをHTML要素内の指定した場所に挿入しているという感じですね。
このスクリプトを投稿テンプレート(single.php)の中で読み込むか、直接記述するなりしましょう。
PHPプログラムの作成
続いてPHPプログラムです。リクエストを受信できるようにするために、Webページ上からアクセスできる位置に設置しましょう。
下のコードはあくまでも一例で、自分のサイトに合わせてセキュリティ対策等は施した方が良さそうですね。
$mode = $_POST["mode"];
if($mode == "get_pp"){
//データベースに接続
$db = mysqli_connect('localhost', 'ユーザ名', 'パスワード', 'データベース名');
//WordPressを読み込み
require_once('~/wp-load.php'); //自分のサイトのwp-load.phpのパスを指定する
$post_id = mysqli_real_escape_string($db,$_POST["id"]);//エスケープ処理
if(get_post_status(intval($post_id))){
//閲覧数をカウントアップする
$query = "INSERT INTO popular_post(post_id,view_num_day) VALUES({$post_id},1) ON DUPLICATE KEY UPDATE view_num_day = view_num_day + 1";
$result = mysqli_query($db,$query);
}
//人気記事リストを取得してJSに返す
$query = "SELECT post_id,view_num_day FROM popular_post WHERE view_num_day > 0 ORDER BY view_num_day DESC LIMIT 6";
$post_list = array();
if($result = mysqli_query($db,$query)){
foreach($result as $row){
//それぞれの投稿について
$post_list[] = $row;
}
}
$result_DOM = "";
//それぞれの人気記事について処理を施していく
foreach($post_list as $each_post){
if(get_post_status($each_post["post_id"])){
$thumbnail_url = get_the_post_thumbnail_url($each_post["post_id"],"medium");
$title = get_the_title($each_post["post_id"]);
$url = "https://bablishe.com/?p=$each_post[post_id]"; //自分のサイトのURLに合わせて
$result_DOM .= "<li><a href='{$url}'><img src='{$thumbnail_url}' alt='投稿のサムネイル画像' loading='lazy'></a>";
$result_DOM .= "<a class='post_title' href='{$url}'>{$title}</a></li>";
}
}
こういう風にすれば、指定記事の閲覧数をデータベースに格納しつつ、人気記事をデータベースから引っ張り出してきてそのサムネイルやタイトルなどをWordPress関数で取得してJavaScriptに返すことができます。
そして閲覧数のリセットについては、cronなどを利用して1日1回、0時ごろに以下のようなプログラムを実行するようにすればいいかと思います。cronというのはLinuxの、定められたタイミングでプログラムを実行する機能ですね。
//データベースに接続
$db = mysqli_connect('localhost', 'ユーザ名', 'パスワード', 'データベース名');
//一日の閲覧数をリセットする
$query = "UPDATE popular_post SET view_num_day = 0";
$result = mysqli_query($db,$query);
こうすると、過去24時間の人気記事というよりは、今日の0時からの人気記事という感じになってしまいますが、個人的にそっちの方が良いと思います。過去24時間の人気記事ってしてしまうと同じ記事ばかり固定して表示されてしまったりするのに対して、0時からの人気記事にすると程よく固定されなくなるのでいろいろな記事を提案できます。
HTML、CSSの調整
人気記事を表示させたい場所に、以下のようなHTML要素を挿入する必要があります。
<p class="suggest_post">人気記事</p>
<div style="margin-bottom: 30px;">
<ul id="sidebar_popular_list"></ul>
</div>
このul要素の中に人気記事のリストを挿入するという感じですね。この機能の良いところは、ページが読み込まれた後に人気記事を取得して挿入するので、ページの表示速度にほとんど影響を与えないところですね。
そして以下のようになりました。

CSSは各自調整願います。
ちょっと解説が全体的に適当になってしまいましたが、この記事を参考にして自作人気記事機能を導入していただけたら幸いです。
ただ、ほぼ私が勉強するためにここまで回りくどい方法をとっているというのもあるので、データベースまで使うのはやりすぎじゃないかと感じる方は他の方の方法を参考にしてみたりしてください。
また、上の写真に写っているような「関連記事」についても自作したのですが、こちらも興味がある方はぜひ以下の記事をご覧ください。