記事内に商品プロモーションが含まれる場合があります
WordPressテーマSANGOのカスタマイズガイドのコメント数がいつのまにか2500を超えていました。ユーザーの方から「コメントを探しにくい」「投稿ページの下までスクロールするのが大変」などという声をいただいたので、サイト内の全コメント一覧ページを作りました。
プラグインなしでコメント一覧を実装する
はじめに良いプラグインがないか調べてみたのですが、丁度良いものが見つかりませんでした。一覧のデザインまでこだわろうとすると全滅です。というわけで自分でコードを書いて実装することにしました。
ググっても参考になる記事がほとんどなかったので、この投稿では具体的な方法を紹介したいと思います。
大まかな流れ
- 固定ページを新規作成し、パーマリンクを
commentsなどにする - テーマのディレクトリ直下に
page-comments.phpというファイルを作成する page-comments.phpにコメント一覧を表示するためのコードを書く
いろいろなやり方がありますが、今回は最もお手軽な方法を紹介します。
手順1:コメント一覧を載せるページを用意する
まず、コメント一覧をどこに載せるかを考えました。他のテンプレートファイル(single.phpやpage.phpなど)に依存しないようにしたかったので、専用の固定ページのファイルを作ることにしました。というわけで、まず固定ページを新規作成し、パーマリンクをcommentsにします。
手順2:page-comments.phpを新規作成
今回はcommentsというパーマリンクを設定したので、page-comments.phpというファイルを作成します。これでhttps://example.com/commentsにアクセスしたときにpage-comments.phpが表示されるようになります。
固定ページの場合「page-パーマリンク名.php」というファイルが存在していると、page.phpではなく、それを読み込んでくれるのです。
手順3:コードを書く
それではコードを書いていきます。まずは単純にコメント一覧を取得して、全て表示するためのコードを紹介します。
まずはコメント一覧を取得する
<?php
// コメントを取得するための引数
$get_comments_args = [
"type" => "comment",
"status" => "approve",
];
// コメント一覧を取得して1つずつ出力
foreach(get_comments($get_comments_args) as $comment) :
?>
★ここにコメントを表示する★
<?php endforeach; ?>コメント一覧はget_comments()で取得できます。引数に配列で「どのコメントを取得するか」という条件を指定します。たとえば
get_comments(
[
"type" => "comment",
"status" => "approve",
]
)とすると、コメントを("type"=>"comment")、承認されたものだけ("status"=>"approve")表示するという意味になります。他にも様々な条件を指定できるので公式のリファレンスをチェックしてみてください。
例えば、"parent"=>0を追加することで、コメント一覧から返信を除くことができます。
コメントの内容を出力する
get_comments()によりコメント一覧のオブジェクトが配列で返ってくるので、これをforearchで出力します。例えば、以下のような形。
<?php
foreach(get_comments($get_comments_args) as $comment) :
?>
<?php echo get_avatar($comment, 50); //投稿者のアイコン(50pxで)?>
<?php echo $comment->comment_author; //投稿者の名前 ?>
<?php echo comment_date("Y/m/d", $comment); //投稿日 ?>
<?php comment_text( $comment->comment_id ); //コメントの本文 ?>
<?php endforeach; ?>それぞれdivタグやpタグなどでマークアップすれば良いですね(この記事ではスタイリングは省略します)。
ページネーションを実現する

このままだと、1つのページに全てのコメントが出力されてしまいます。サーバーへの負荷、読み込み速度などを考えるとページ分割したいですね。さきほどのコードをページネーションできるように改良します。
<?php
// 1ページあたりのコメント数
define("COMMENT_NUMBER_PER_PAGE", 15);
// ページ数をURLパラメータから判定。なければ1ページ目
$page = (int) @$_REQUEST["page_number"] ?: 1;
// オフセット(現在のページを基準としたコメント数)
$offset = ($page * COMMENT_NUMBER_PER_PAGE) - COMMENT_NUMBER_PER_PAGE;
// コメントを取得するための基本引数
$comment_base_args = [
"parent" => 0,
"type" => "comment",
"status" => "approve",
];
// サイト内の合計のコメント数
$total_comment_count = count(get_comments($comment_base_args));
// コメントの合計ページ数
$total_pages = ceil($total_comment_count/COMMENT_NUMBER_PER_PAGE);
// 各ページのコメントを取得するための引数(さきほどの引数と結合)
$get_comments_args = array_merge($comment_base_args, [
"offset" => $offset,
"number" => COMMENT_NUMBER_PER_PAGE,
]);
// コメントを出力
foreach(get_comments($get_comments_args) as $comment) :
?>
★ここにコメントを表示する★
<?php endforeach; ?>
<?php
//ページネーション
echo paginate_links([
"format" => "?page_number=%#%",
"total" => $total_pages,
"current" => $page,
"prev_text" => "前へ",
"next_text" => "次へ",
"type" => "list"
]);
?>
コメント一覧のページネーションをサクッと実現するための関数はWordPressには無いようなので、少し回りくどいコードになっています。以下かんたんな解説です。
URLに「いま何ページ目にいるか」の情報を持たせる
URLパラメータという形でこれを実現します。たとえば2ページ目ならhttps://example.com/comments?page_number=2というURLにします。これで(int) @$_REQUEST["page_number"]というコードでページ数を取得できるようになります。
合計のコメント数やページ数を地道に計算する
サイト内の合計コメント数は、count(get_comments(~))という形で取得しています。コメントの出力時にもget_comments(~)するわけなので、2度関数を読みに行っていて効率が悪いのですが、他にあまり良い方法が思いつきませんでした(こうするしかない?)。
コメントを取得するためのget_comments(~)の引数には「このページでは○番目のコメント(offset)から、いくつ(number)表示するか」という指示も与えてやります。
WordPressでコメント一覧を実現するコード(完成形)
ここまでの内容をまとめると、最終的には以下のようなコードになります。いちおうテーマヘッダーやフッターも含めています。
<?php get_header(); ?>
<?php
define("COMMENT_NUMBER_PER_PAGE", 15);
$page = (int) @$_REQUEST["page_number"] ?: 1;
$offset = ($page * COMMENT_NUMBER_PER_PAGE) - COMMENT_NUMBER_PER_PAGE;
$comment_base_args = [
"parent" => 0,
"type" => "comment",
"status" => "approve",
];
$total_comment_count = count(get_comments($comment_base_args));
$total_pages = ceil($total_comment_count/COMMENT_NUMBER_PER_PAGE);
$get_comments_args = array_merge($comment_base_args, [
"offset" => $offset,
"number" => COMMENT_NUMBER_PER_PAGE,
]);
?>
<h1>コメント一覧(<?php echo $page; ?>ページ目)</h1>
<div class="comments-list">
<?php foreach(get_comments($get_comments_args) as $comment) : ?>
<div class="comment">
<?php echo get_avatar($comment, 50); ?>
<?php echo $comment->comment_author; ?>
<?php echo comment_date("Y/m/d", $comment); ?>
<?php comment_text( $comment->comment_id ); ?>
</div>
<?php endforeach; ?>
</div>
<div class="pagination">
<?php
echo paginate_links([
"format" => "?page_number=%#%",
"total" => $total_pages,
"current" => $page,
"prev_text" => "<i class='fa fa-chevron-left'></i>",
"next_text" => "<i class='fa fa-chevron-right'></i>",
"type" => "list"
]);
?>
</div>
<?php get_footer(); ?>少し複雑になってしまうので、foreachの中身(コメントの中身)なんかは別のファイルに分けても良いですね。