WordPressで前日のPVをカウントして、タイムリーなオススメ記事リストを作る方法

シェアする:

この記事をおすすめしたい人

  • WordPressでオススメ記事を表示したい人
  • WordPressで前日のPVをカウントしたい人
  • つまりオレ

今回はWordPressで前日のPVを取得する方法を考えていきます。

やりたい事は、

前日のPVでソートしたオススメ記事!

いつも通り、何やらかんやら経緯もまとめるので、興味ない人は最後のまとめだけ見てください。

意外なことにすげー簡単なコードでできました!

オススメ記事とは一体何か

このサイトでは、サイドバーに「人気の投稿」として、記事の下部に「関連記事」としてオススメ記事を掲載しています。

これらの意義は、サイトを見に来てくれた人がもっと多くの記事を見てくれるよう誘導することです。

じゃー多くの人が見てくれる記事とは何か。

自分で考えてもいいんですが、どうしても主観が入るため精度が低い可能性があります。

そこで客観的に評価できそうな指標がページビュー数です。

見てくれている回数が多いということは、ある側面では間違いなく需要の高さを示しているはず。

というわけで、以下、PVの取得の仕方、どのようなPVにするかを検討していきます。

microCMSのセミナーでの回答

以前、Nuxt.jsでのブログ形式の実装を勉強するためにmicroCMSというヘッドレスCMS(表示部分を持たないCMS)のセミナーに参加しました。

Nuxt.jsはそれ自体がデータベースを持たないので、WordPressのようにPV数などを記録しておく場所が存在しません。

そこで、セミナーの講師の人に聞いてみました。

オススメ記事の実装って何かいい方法ありますか?
PVのカウントって出来ないッスよね?

その回答がコレ↓でした。

そもそもオススメ記事をPV順にする必要あるのかい?

おお、なるほど。

PV順なら間違いという考えにとらわれていましたが、よく考えると、見てもらいたい記事を固定で表示しておいてもいいわけです。

これなら実装も簡単。

ただ、この手法、お店のサイトのように見てもらいたいページが決まっている場合には強いですが、ブログのように「どれでもいいからとにかくいっぱい見て欲しい」みたいなケースでは調整がかなり面倒です。

というわけで今回はやはりPV順でのソートに拘りたいと思います。

PVを取得する方法を考えた

プラグイン「WP-PostViews」を使った方法

最初、なるべく楽をしようとWordPressのプラグイン「WP-PostViews」を使いました。

この手のプラグインはゴテゴテしたのが多い中、WP-PostViewsは非常にシンプルにPVをカウントしていくプラグインで、PV数は記事のカスタムフィールドに記録されるため、記事一覧取得時にソートの項目として使えます。

そう、ほぼカンペキな機能なんですよ。

管理画面でPV数を確認できるのも便利(ソートもできます)で、別の方法を思いついた今でも削除予定はありません(他のテストしたプラグインは全部削除)。

ただ、ひとつ大きな問題点があって…。

記録されてるPVが記事公開以降の総PVなんですね。

なので新しく超良い記事を書いたとしても、過去の人気記事のPVに近付くまではオススメ記事に上がってきません。

これではダメだと考えた結果、「前日のPV」を取得する方法を知りたくなったわけです。

前日なら時事ネタとかのトレンドも反映しやすいですしね。

「Analytics Reporting API」を使った方法

Googleのアナリティクスを使った方法です。 APIが用意されているので、指定した期間のPVをPHP上から取得できます。

ただこれ、実装も運用もすげーめんどくさくて、まず例えばページ表示時に動的に取得するとしましょう。

すると1ページ開くごとに一瞬とは言えないアナリティクスAPIのロードが入り、ページの表示が遅くなりそうです。 これが見てる人全員×ページ数とかなると、けっこうな負荷にもなりそう。

そこで。

日付更新時に一度だけアナリティクスAPIを叩き、取得した値を元に各記事のカスタムフィールドに前日のPVをいれる方法を考えました。

プログラムを走らせるトリガーは「ページ表示時」ではなく「時刻」なので、通常のWordPressのシステム上からは行えません。 そこで調べているとCRONという仕組みが見つかりました。

CRONは時刻をトリガーにプログラムを走らせることができるようで、実はこのサイトはこの構成でオススメ記事を表示しています。

僕の知らない要素が多くて、最終的にVB.netでアナリティクスAPIを叩き、サーバサイドのデータベースに更新、それをCRON側で読み込んでWordPressのカスタムフィールドに追加するという、

ものすげー不細工な格好になりました。

この方法をまとめてもいいんですが、あまりにも不細工なのでブラッシュアップしてからですね…。

PHPとかCRONとか得意な人ならWordPress上だけで完結できるシンプルな仕組みが作れそう。

あとは、アナリティクスのデータはURLでページを管理していて、WordPressはページIDで管理しているため、URLとIDを紐付ける作業にもひと手間かかります。

プラグイン「WordPress Popular Posts」を使った方法

「WordPress 前日のPV」で検索すると出てきた方法で、WordPressのプラグイン「WordPress Popular Posts」を使ったものです。

ところがこのプラグイン、上でちょっと触れたゴテゴテした系のプラグインで、アクセス解析など、今回の目的には不要な要素が盛りだくさん。

過去1週間分のPVをカウントしてくれるようですが、記録場所がカスタムフィールドではなくデータベースで、これもちょっと面倒。 データベースへ接続して記事とPVを関連づけて、それをソートして…って。

データベースとの接続を意識せずにサイト運用できるのがWordPressの良いところだと思うんですよ。

つーか、そんなめんどいことするくらいなら必要な機能だけ自分で実装すればよくね?

というわけでようやく本題です!

WordPressの上だけでシンプルに前日のPVをカウントしてみせますよ!

WordPressで前日のPVをカウントしてみせる!

ここまでダラダラ書いたので、ここからはズバッと書きます。

いきなり結論↓。

functions.phpのコード

「functions.php」に追加したコード↓です。


date_default_timezone_set('Asia/Tokyo');

define("MY_PV", "my_field_pv");
define("MY_COUNT", "my_field_count");
define("MY_DATE", "my_field_date");

add_action('wp_head', function () {
  if ( is_user_logged_in() || !is_single() ) {
    return;
  }
  
  global $post;
  
  $today = date("Ymd");
  $date = get_post_meta($post->ID, MY_DATE, true);
  
  $count = get_post_meta($post->ID, MY_COUNT, true);
  
  if ( strcmp($today, $date) == 0 ) {
    update_post_meta($post->ID, MY_COUNT, $count+1);
  } else {
    update_post_meta($post->ID, MY_PV, $count);
    update_post_meta($post->ID, MY_COUNT, 0);
    update_post_meta($post->ID, MY_DATE, $today);
  }
});

想像していたよりかなり短いコードになりました。

解説を入れたもの↓。


//時刻がずれることがあるのでタイムゾーンの変更
date_default_timezone_set('Asia/Tokyo');

//カスタムフィールドのキーを定数で宣言
//MY_PVが前日のPV、MY_COUNTが今日カウント中のPV
//MY_DATEは日付変更を検知するための今日の日付
define("MY_PV", "my_field_pv");
define("MY_COUNT", "my_field_count");
define("MY_DATE", "my_field_date");

//ページ表示時に動いてもらうためにwp_headでアクションフック
add_action('wp_head', function () {
  //ログインユーザは除外、投稿ページ以外も除外
  if ( is_user_logged_in() || !is_single() ) {
    return;
  }
  
  global $post;
  
  //今日の日付を「20220202」形式で取得
  $today = date("Ymd");
  カスタムフィールドから日付を取得
  $date = get_post_meta($post->ID, MY_DATE, true);
  
  カスタムフィールドから本日のPVを取得
  $count = get_post_meta($post->ID, MY_COUNT, true);
  
  //日付が同じ場合はPV数を+1してカスタムフィールドに戻す
  if ( strcmp($today, $date) == 0 ) {
    update_post_meta($post->ID, MY_COUNT, $count+1);
  //日付が変わった場合
  } else {
    //前日のPVに本日カウントしたPVを設定
    update_post_meta($post->ID, MY_PV, $count);
    //明日(今日)カウントするPVを初期化
    update_post_meta($post->ID, MY_COUNT, 0);
    //日付を明日(今日)のものに変更
    update_post_meta($post->ID, MY_DATE, $today);
  }
});

「今日かどうか」を判定する「MY_DATE」に日付を文字列として入れておいて、現在日時と一致すればPVをカウント。 そうでなければ明日の処理用に初期化、といった具合です。

固定ページでもカウントしたい場合は、除外処理の部分を調整してください。 カテゴリページとかのインデックス系ページは一覧の最初の投稿にカウントしてしまうので、もうひと手間必要です。

あとはカスタムフィールドのキーが固有のものになるよう調整が必要な場合がありますが、基本はこのままコピペでいけると思います。

オススメ記事表示部分の処理

トップページ(front-page.phpかhome.php)や記事ページ(single.php)など、オススメ記事を表示する部分のコード↓です。


$query = array(
        'post_type' => 'post', 
        'post_status' => 'publish', 
        'posts_per_page' => 5,
        'orderby' => 'meta_value_num',
        'order' => 'DESC',
        'meta_key' => MY_PV,
);

$posts = new WP_Query($query);

WP_Queryで記事を取得していると思うので、パラメータに次の3つを追加してください。

  • 「orderby」を「meta_value_num」にして、カスタムフィールドを数値としてソート
  • 「order」を「DESC」にして、降順ソート(数値の大きい順)
  • 「meta_key」を「MY_PV」にして、先ほど追加した前日のPVのカスタムフィールドを指定

これで前日のPVでソートできます!

現在の数値の確認

管理画面に追加する方法があるんですが、めんどくさいので今回はパスして簡易な方法にしました。 知りたい人は「WordPress カスタムフィールド 追加」とかで検索してください。

簡易バージョンでよければsingle.phpなどにこの↓ようなコードを追加していてください。


if ( is_user_logged_in() ) {
  $pv = get_post_meta($post->ID, MY_PV, true);
  $count = get_post_meta($post->ID, MY_COUNT, true);
  $date = get_post_meta($post->ID, MY_DATE, true);
  
  echo '<p>前日のPV = ' . $pv . '、今日のPV = ' . $count . '、今日の日付 = ' . $date . '</p>';
}

ログインユーザ限定で「前日のPV = 100、今日のPV = 10、今日の日付 = 20220422」みたいに表示されます。

使う場合の注意事項

当然ですが導入したその日には前日のPVが記録されていません。

なのでまずはfunctions.phpのコードだけ導入して1日待ってください。

表示部分のコードは24時を越えたら導入してください。

そうしないと意図した順序でソートが行われません。

コピペで使えるまとめ

「functions.php」に以下のコードを追加してください。


date_default_timezone_set('Asia/Tokyo');

define("MY_PV", "my_field_pv");
define("MY_COUNT", "my_field_count");
define("MY_DATE", "my_field_date");

add_action('wp_head', function () {
  if ( is_user_logged_in() || !is_single() ) {
    return;
  }
  
  global $post;
  
  $today = date("Ymd");
  $date = get_post_meta($post->ID, MY_DATE, true);
  
  $count = get_post_meta($post->ID, MY_COUNT, true);
  
  if ( strcmp($today, $date) == 0 ) {
    update_post_meta($post->ID, MY_COUNT, $count+1);
  } else {
    update_post_meta($post->ID, MY_PV, $count);
    update_post_meta($post->ID, MY_COUNT, 0);
    update_post_meta($post->ID, MY_DATE, $today);
  }
});

オススメ記事を表示する部分のオプションに赤字で書かれた3行を追加してください。


$query = array(
        'post_type' => 'post', 
        'post_status' => 'publish', 
        'posts_per_page' => 5,
        'orderby' => 'meta_value_num',
        'order' => 'DESC',
        'meta_key' => MY_PV,
);

$posts = new WP_Query($query);

以上、WordPressからお届けしました!

シェアする: