WordPress

コメントされたときのみ、コメント最新リストを更新する

最新コメント5件を表示するような共通エリアを、すべてのページに用意するお話しです。

実現したいこと

最新コメント5件を表示するような共通エリアを用意する際の要件をまとめました。

  • ある記事に複数のコメントがある場合はユニークとして最新のコメントのみカウントとし、記事が重複しないようにする
  • ページをアクセスするたびにデータベースを参照するのではなく、コメントされたときにスタティックなファイルを事前に生成しておき、それを参照する
  • 対象のコメントは、公開されている・許可されているコメントのみで、保留やスパム判定されたコメントやPINGは対象外とする

実装までの思考

WordPressのテンプレートには、コメントを軸としたテンプレートはないので、別途、固定ページなどで専用ページを用意する必要がある。とりあえず、page-comments.php を用意して、コメント一覧を表示するページを作ろう。

このままだと、ページにアクセスするたびに、page-comments.phpを呼び出す、つまり都度データベースを参照してしまうのでよろしくない。とはいえ、サーバーキャッシュ対応はレンタルサーバーだとできないので、別案を考える。

コメントされたタイミングで、スタティックファイルを作る。ページにアクセスするたびに、そのスタティックファイルを参照するようにする。

つまりは、重要なポイントは2つ。
それは「コメント一覧を表示する」ことと「コメントがあったタイミングをフックにする」ことだ。
それではそれぞれ実装していきます。

下準備

実装するためのテスト用ファイルを用意します。
WordPressが有効になる必要があります。どのテンプレートファイルでも対応しますので、トップページなり、固定ページなり、投稿ページなり、エラーページなり、お好きなように。

コメント一覧を表示する → get_comments

コメント情報を取得するには、関数 get_comments を利用します。
引数には多くの条件を指定できるので、大概のことはこの関数で絞り込みや並び替えを行うことができるでしょう。
詳しくは、公式リファレンスを参照します。
関数リファレンス/get comments - WordPress Codex 日本語版

今回は、取得対象を「公開許可しているコメント」として情報を取得します。とりあえず、コメント本文を出力する例です。

$args_comment = array(
  'type' => 'comment',
  'status' => 'approve',
);

foreach ($comments as $comment) {
  echo $comment -> comment_content;
}

これだけで、サイト内のすべての許可したコメントの本文のみが表示されます。
htmlやCSSの反映はここでは省きますが、よしなに。
ちなみに、本文以外にもコメントごとに下記のような情報が返却されています。

戻り値

comment_ID (整数) コメントの ID
comment_post_ID (整数) コメントが付いた投稿または固定ページの ID
comment_author (文字列) コメント投稿者の名前
comment_author_email (文字列) コメント投稿者のメールアドレス
comment_author_url (文字列) コメント投稿者のウェブサイト
comment_author_IP (文字列) コメント投稿者の IP アドレス
comment_date (文字列) コメントの日時 (YYYY-MM-DD HH:MM:SS)
comment_date_gmt (文字列) コメントの GMT 日時 (YYYY-MM-DD HH:MM:SS)
comment_content (文字列) コメント内容
comment_karma (整数) コメントのカルマ値 (訳注: 常に0です)
comment_approved (文字列) コメントの承認レベル (0, 1 または "spam")
comment_agent (文字列) コメント投稿者のユーザーエージェント (ブラウザーやオペレーティングシステムなど)
comment_type (文字列) 該当すればコメントの種類 (pingback|trackback), 普通のコメントなら空
comment_parent (文字列) 入れ子になったコメントなら親コメントの ID (トップレベルなら0)
user_id (整数) コメント投稿者が登録済みならユーザー ID (未登録なら0)

コメントありの記事を5件取得するためにカスタマイズする

$comment_maxnum = 5;    // 5件取得する

$comment_num = 0;    // 記事数をカウントする
$comment_array = array();    // 記事IDを格納する

$args_comment = array(
  'type' => 'comment',
  'status' => 'approve',
);

$comments = get_comments($args_comment);

foreach ($comments as $comment) {
  $post_id = $comment -> comment_post_ID;    // 記事IDを取得する

  // 記事IDが重複していないか判別する
  if (in_array($post_id, $comment_array)) {
    
    // 重複しているため、次のコメントあり記事を参照する
    continue;

  // 記事数が所得したい件数より少ないか判別する
  } else if ($comment_num < $comment_maxnum) {
    
    $comment_num++;    // 取得記事数を追加する
    $comment_array[] = $post_id;    // 記事IDを格納する
                                            
    echo $comment -> comment_content; 
  } else {
    
    // 取得したい件数に達したので、このループから抜ける
    break;
  }
}

これで、一つ目の「コメント一覧を表示する」は実装完了。この記述をすべてのテンプレートに適用させてもいいのだが、このままだとサイト内の各ページにアクセスするたびにデータベースを参照するので、コメントがあったときにファイルを更新して、スタティックファイルを用意する。

コメントがあったタイミングをフックにする → wp_insert_comment

公式サイトを漁っていたら、コメントがあったタイミングをフックにする関数を見つけたので、これをfunctions.php に適用するのみ。
【注意】functions.php を修正する場合は、必ずファイルをバックアップしてから修正することを強くオススメします。コードに誤りがあるとサイトが閲覧できなくなる可能性があるので、扱い要注意です。

function mp_comment_inserted($comment_id, $comment_object) {
  
    // do something  
}
add_action('wp_insert_comment', 'mp_comment_inserted', 99, 2);

これで、コメントがあったタイミングをフックにする処理ができます。関数名「mp_comment_inserted」は任意です。ご自身の命名ルールで。
do something の箇所に、さきほどテストしたコードをこちらに差し替え、echoではなく、file_put_contentsでファイルを作成するようにすれば完成です。

function mp_comment_inserted($comment_id, $comment_object) {

  $comment_maxnum = 5;

  $comment_num = 0;
  $comment_array = array();
  $comment_text = '';    // 保存用テキスト

  $args_comment = array(
    'type' => 'comment',
    'status' => 'approve',
  );

  $comments = get_comments($args_comment);

  foreach ($comments as $comment) {
    $post_id = $comment -> comment_post_ID;

    // 記事IDが重複していないか判別する
    if (in_array($post_id, $comment_array)) {

      continue;
    } else if ($comment_num < $comment_maxnum) {

      $comment_num++;
      $comment_array[] = $post_id;

      $comment_text .= $comment -> comment_content;    // テキストを追加する
    } else {
      break;
    }
  }
      
  // テキストを保存する
  file_put_contents(__DIR__.'/include_comment.html', $comment_text);
}
add_action('wp_insert_comment', 'mp_comment_inserted', 99, 2);

include_comment.html というファイルを生成 or 上書きするように指定していますが、もちろんファイル名や階層もよしなに変更で。
ちなみに、functions.php 内に移動した場合は、先に用意したテスト用のテンプレートは不要となり、include_comment.html をincludeするようにします。

最後に

この記事で紹介した内容で、このブログの全ページに「最近の記事」「人気の記事」がありますが、ここに「コメントありの記事」というエリアを追加しました。

最近の記事

文章のユーザビリティ

この書籍の中で、ライティングのユーザビリティについて触れている項目があり、激しく共感する部分だったので、ここで備忘録としてピックアップする。 ・・・

ライティング

インタフェースデザイン

この書籍は、I部 リサーチ、II部 デザイン、III部 インプリメンテーションと三部構成になっている。この記事では、その中から、I部 リサーチ、・・・

デザイン思考

フルHD映像を4Kにする → スーパースケール

これを知ったときはマジか!と飛び跳ねた。あらためて思い返してみると、確かに公式チュートリアルでも触れていたことをうっすら思い出す。そしてそのときとやり方がなん・・・

DaVinci Resolve

Macで編集時と書き出し後で色味が変わってしまう場合に試してみたいこと

試したことはまだないけど、Macで編集時と書き出し後で色味が変わって困ったときのために備忘録。 プロジェクト設定 > 「カラーマネジメント・・・

DaVinci Resolve

プロジェクト設定と環境設定

プロジェクト設定と環境設定について詳しく解説されている情報がなかなか見つからないので、要所要所で知り得た情報を更新していきます。 プロジェクト設定 ・・・

DaVinci Resolve

項目”Clipy”は開いているため、ゴミ箱に入れることができません。←アンインストールしようとしたときの話し

Clipyが超絶便利そうだったので、macOS Big Sur にインストール&再起動して使ってみた。ところが、command + c を複数の箇所で行い、c・・・

徒然なままに

setTimeout は requestAnimationFrame に変えるべき?

requestAnimationFrame をはじめて見たので調べていたら、setTimeout や setInterval は requestAnimati・・・

JavaScript

書籍「小さなチーム、大きな仕事」からピックアップ

6年ぶりに読み返したが、今なおハッとさせられることが多く見つかる。 この本で忘れないようにしたい項目をピックアップするだけでも役に立ちそ・・・

起業向け情報

書籍「完全網羅 起業成功マニュアル」からピックアップ

この記事では、以前に読んだ際に付箋を付けていたが、その部分だけを備忘録としてピックアップするため、本の要約ではない。実際は、何倍も濃い内容で、練・・・

起業向け情報

書籍「はじめの一歩を踏み出そう」から気になったフレーズをピックアップ

もう一回、全部読み返したいところだが、書籍がありすぎるので、当時付箋紙をつけていたところだけをピックアップ。書籍内ではより具体的な説明があるので・・・

起業向け情報

人気の記事

可視性とフィードバック

これまでに扱ったことのないようなものを取り扱うときには、次のような問いを参考にすると何をしたらよいかが分かってくる。 どの部分が可動部で、どの部分が固定部か。・・・

デザイン思考2007年8月12日

このサイトのリニューアル2014

以前に書いた「このサイトのリニューアル」で、リニューアル意思を示しつつも結局保留にして、先送りしてしまっていたけど、このあいだの週末(2013.3.29-30)・・・

お仕事・制作日記2014年4月2日

エラーに備えてデザインする

エラーが起こっても大丈夫なシステムを作ると、みんなそれに頼るようになるので、信頼性を高くしておいたほうがよいだろう。 エラーの原因を理解し、その原因が最も少な・・・

デザイン思考2007年8月12日

理解しやすさと使いやすさのためのデザインの原則

こんな製品は使いたくない例1 教示がよくない。 システムの操作が可視的でない。 操作した結果が目に見えない。 こんな製品は使いたくない例2 デザイナーは良か・・・

デザイン思考2007年8月12日

このサイトのリニューアル

先日、SEO関連のセミナーに参加してきました(レポート「SEO 2013(CSS Nite LP29)」)。 セミナーで取り上げられていた対象サイト規模とこの・・・

お仕事・制作日記2013年9月29日

Sassファイルを保存するとcssファイルが自動作成されて困る→サイト管理

sassファイルを保存すると、cssファイルが自動生成されるという症状でしばらくの間、ストレスだったがようやく解決。 例えば、var.scssを修正して保存す・・・

Dreamweaver2018年9月27日

名刺代わりの超絶ミニマムなブランディングページ

このたび、ハンドメイドアクセサリー作家さんのWebサイト制作させていただきました! Sunny Side Accessory(サニーサイド アクセサリー・・・

お仕事・制作日記2021年2月11日

透明GIF画像の書き出し方法

たとえば、白文字が混じった画像を透明GIFにする場合、背景だけでなく白文字までが透明化されてしまう。 ずっと悩んでいたがようやく解決できたので覚え書き。 形・・・

Fireworks2008年7月11日

Webサービス「超シンプルブログ・joruno」を作ってみました

マイペースに書けるブログがほしい ぼくの場合、FacebookやTwitterでは読む側を意識してしまうことが多い。あとは投稿ボタン押すだけというところまで書・・・

お仕事・制作日記2017年2月1日

カスタム投稿をつくる最強プラグイン「Custom Post Type UI」

この「Custom Post Type UI」というプラグインのおかげで、WordPressは「ただのブログに特化したCMS」というイメージから「あらゆる利用シ・・・

WordPress2017年7月23日

コメントありの記事

インタフェースデザイン

「test」

デザイン思考

Instagram API を使ってインスタに投稿した画像データを取得する

「>ころころさん コメントありがとうございます! 確かに、APIドキュメント見ましたが、ライブに関する情報は今のところ取得できないようですね。 インスタライ・・・」

API

Sony Eマウント フルサイズ対応のカメラレンズを収集するページを作ってみた

「SIGMAから超軽量で明るい単焦点レンズが2本発売になりましたので、リストにレンズ情報追加しました!」

お仕事・制作日記

overflowをautoにした要素のスクロール位置を変更する → scrollTop scrollLeft

「>名無しさん ご指摘、ありがとうございます! 記事冒頭の「まずはサンプル」のサンプルが動いていませんでしたので修正しました。」

JavaScript

えっ!?Yahooの検索結果から遷移しようとしたら全く違うサイトにリダイレクトされてしまった...

「>前田さん コメントありがとうございます。 環境は分かりかねますが、修正したいファイルのパーミッションを604や644に変更すると書き込みできるようになります(・・・」

お仕事・制作日記

記事の投稿IDなどの投稿者(ユーザー)情報を取得する方法 → get_the_author_meta

「アバターを取得する「get_avatar」についても追記しました!」

WordPress

jQueryでformを操る【nameの値を取得する/クリアする】

「「値をクリアする」を追加しました。チェックボックスやラジオボタンの値を何も選択していない状態に戻すときについて触れています。」

JavaScript

iframeの高さを自動調整する

「>匿名さん コメントありがとうございます。 サンプルでは、beforeは何も処理していないので期待する表示にならない、で正解です。 クリックした後が、対応・・・」

JavaScript

MAMPでMySQL Serverが突然起動しなくなった時 → ログファイル削除

「(匿名)さん コメントありがとうございます。何も設定変更していないのに、それまで使用できていたサーバーが突然使えなくなるのは辛いですよね、、。 ここで紹介したや・・・」

MAMP

イラストレーターでレイヤーごとにPNGで書き出す

「コメントありがとうございます! そもそもできるかはわかりませんが、ソースを書き換える必要はあります。 下記記事などが参考になるかもしれません。 illustra・・・」

Illustorator

WEB制作アプリケーションWordPressコメントされたときのみ、コメント最新リストを更新する | シンプルシンプルデザイン