WordPress コメントをスレッド対応にする

管理画面WordPress 2.7 から、プラグイン等を導入せずともコメントをスレッド(入れ子)表示できるようになりました。
対応するテーマを使っていれば、管理画面の [設定] – [ディスカッション] で [コメントをN階層までのスレッド (入れ子) 形式にする] にチェックを入れてやれば良いのですが、使用しているテーマが対応していないと修正する必要があります。
このテーマの修正が、意外と面倒なので自分用のメモも兼ねて修正方法をエントリしておきます。

comments.php の修正

まずは、テーマの comments.php。
ここでは WordPress 2.6 に付属されていた default テーマを対象に説明します。

コメントループの修正

コメントループの中身を修正しましょう。

	<ol class="commentlist">

	<?php foreach ($comments as $comment) : ?>

		<li <?php echo $oddcomment; ?>id="comment-<?php comment_ID() ?>">
			<?php echo get_avatar( $comment, 32 ); ?>	
			<?php printf(__('<cite>%s</cite> Says:', 'kubrick'), get_comment_author_link()); ?>
			<?php if ($comment->comment_approved == '0') : ?>
			<em><?php _e('Your comment is awaiting moderation.', 'kubrick'); ?></em>
			<?php endif; ?>
			<br />

			<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title=""><?php printf(__('%1$s at %2$s', 'kubrick'), get_comment_date(__('F jS, Y', 'kubrick')), get_comment_time()); ?></a> <?php edit_comment_link(__('edit', 'kubrick'),'&nbsp;&nbsp;',''); ?></small>

			<?php comment_text() ?>

		</li>

	<?php
		/* Changes every other comment to a different class */
		$oddcomment = ( empty( $oddcomment ) ) ? 'class="alt" ' : '';
	?>

	<?php endforeach; /* end for each comment */ ?>

	</ol>

こんな感じにします。

	<ol class="commentlist">
	<?php wp_list_comments();?>
	</ol>

foreach$comments をループさせて <li> 要素を書き出していた部分(27 〜 48 行目)をゴッソリと削り、代わりにテンプレートタグ <?php wp_list_comments();?> を挿入します。

ただし、これだと default テンプレート互換の (X)HTML コードが書き出されます。
独自の (X)HTML コードに変更したい場合はさらに手を加える必要があります。(後述)

コメント入力欄の変更

続いて、コメント入力フォームの修正。

<h3 id="respond"><?php _e('Leave a Reply', 'kubrick'); ?></h3>

<div id="cancel-comment-reply"> <small><?php cancel_comment_reply_link() ?></small> </div> 

<?php if ( get_option('comment_registration') && !$user_ID ) : ?>
<p><?php printf(__('You must be <a href="%s">logged in</a> to post a comment.', 'kubrick'), get_option('siteurl') . '/wp-login.php?redirect_to=' . urlencode(get_permalink())); ?></p>
<?php else : ?>

<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">

<?php if ( $user_ID ) : ?>

<p><?php printf(__('Logged in as <a href="%1$s">%2$s</a>.', 'kubrick'), get_option('siteurl') . '/wp-admin/profile.php', $user_identity); ?> <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="<?php _e('Log out of this account', 'kubrick'); ?>"><?php _e('Log out &raquo;', 'kubrick'); ?></a></p>

<?php else : ?>

<p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" <?php if ($req) echo "aria-required='true'"; ?> />
<label for="author"><small><?php _e('Name', 'kubrick'); ?> <?php if ($req) _e("(required)", "kubrick"); ?></small></label></p>

<p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" <?php if ($req) echo "aria-required='true'"; ?> />
<label for="email"><small><?php _e('Mail (will not be published)', 'kubrick'); ?> <?php if ($req) _e("(required)", "kubrick"); ?></small></label></p>

<p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
<label for="url"><small><?php _e('Website', 'kubrick'); ?></small></label></p>

<?php endif; ?>

<!--<p><small><?php printf(__('<strong>XHTML:</strong> You can use these tags: <code>%s</code>', 'kubrick'), allowed_tags()); ?></small></p>-->

<p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p>

<p><input name="submit" type="submit" id="submit" tabindex="5" value="<?php _e('Submit Comment', 'kubrick'); ?>" />
<input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" />
</p>
<?php comment_id_fields(); ?> 
<?php do_action('comment_form', $post->ID); ?>

</form>

2つの新しいテンプレートタグを挿入する必要があります。

  • 69行目
    <form> タグ開始前にテンプレートタグ <?php cancel_comment_reply_link(); ?> を挿入しておきましょう。
  • 101行目
    </form> の前にテンプレートタグ <?php comment_id_fields(); ?> を挿入しておきましょう。

header.php または functions.php の修正

返信用の JavaScript を読み込めるように以下のコードを追加しておきましょう。

<?php
if ( is_singular() ) wp_enqueue_script( 'comment-reply' );
?>

header.php に追加する時は wp_header(); より前に。
functions.php に追加する時は、どこでも良いです。
これで、返信用の JavaScript (wp-includes/js/comment-reply.js) がロードされます。

実は default テーマ互換のテーマを使用している場合は、たったコレだけで修正完了です。
後は css を修正して、スレッド形式になった場合の見た目を調整してやってください。

コメントループ部分が default テンプレートと違う場合

厄介なのが comment.php のコメントループ部分を default テンプレートとは違う形式にしている場合です。

これは wp_list_comments() を呼び出す時に callback オプションを付加してやります。
具体的には、こんな感じ

	<ol class="commentlist">
	<?php wp_list_comments('callback=custom_comments');?>
	</ol>

ただし、これだけではダメで callback オプションが呼び出すコールバック関数を functions.php 等に書いておく必要があります。

default テーマを例に挙げると、コールバック関数は以下のような感じで行けます。

<?php
function custom_comments($comment, $args, $depth) {
	$GLOBALS&#91;'comment'&#93; = $comment;
?>
		<li id="comment-<?php comment_ID() ?>">
			<?php echo get_avatar( $comment, 32 ); ?>	
			<?php printf(__('<cite>%s</cite> Says:', 'kubrick'), get_comment_author_link()); ?>
			<?php if ($comment->comment_approved == '0') : ?>
			<em><?php _e('Your comment is awaiting moderation.', 'kubrick'); ?></em>
			<?php endif; ?>
			<br />

			<small class="commentmetadata">
				<a href="#comment-<?php comment_ID() ?>" title=""><?php printf(__('%1$s at %2$s', 'kubrick'), get_comment_date(__('F jS, Y', 'kubrick')), get_comment_time()); ?></a>
				<?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'reply_text' => '返信', 'before' => ' | ', 'after' => ' | ') ) ); ?>
				<?php edit_comment_link(__('edit', 'kubrick'),'&nbsp;&nbsp;',''); ?>
			</small>

			<?php comment_text() ?>
<?php
}
?>

要は、元々の comments.phpforeach($comments as $comment) でループしていた部分の中身を書いておけばいいのです。
# default テーマであれば 29 〜 46 行目

ここで注意点を3つ

  • 3行目
    初期処理として、グローバル変数に引数として受け取った $comment を代入しておきましょう。
  • 15行目
    <?php comment_reply_link(); ?> は返信用のリンクを追加するための新しいテンプレートタグです。
    オプションは、配列で渡します。
  • li の閉じ要素(</li>)は記述しない。
    wp_list_comments() 関数が </li> を末尾に自動挿入するため、</li> を挿入する必要がありません。
    っていうか挿入してはいけません、余計に閉じてしまいます。
    div でリスティングしている時は wp_list_comments() 関数を呼び出す時に style=div オプションを付与する必要があります。
    もし、div, li 以外(dl とか)でリスティングしている時は、wp_list_comments() 関数を呼び出す時に end-callback オプションを付加して、end-callback 用の関数を書かねばいけません。

でも、実はこのサイトのコメント欄は、まだスレッドに対応していません。
デザインをどうしようかと検討している最中です。

WordPress コメントをスレッド対応にする」への17件のフィードバック

  1. NEX-C3

    それはそこにいくつかの興味深いものだった。それを投稿いただきありがとうございます。

    返信
  2. かずい

    スレッド(入れ子)表示できるようになりました。

    スレッド一覧として表示することは出来ますか。

    返信
    1. をかもと 投稿作成者

      かずいさん、はじめまして。

      「スレッド一覧として表示」と云うのは具体的にはどのような表示方法でしょうか?
      こちらに書いてある方法は、WordPress 2.7 から実装された「コメントを入れ子形式で表示する」ための方法です。

      返信
  3. ピンバック: 日報と社内情報共有 | HibachiyaHacks

  4. ピンバック: WordPress掲示板(ゲストブック)を設置してみました

  5. ピンバック: mono-stock» Blog Archive » wordpressでオリジナルアバターを実現

  6. ピンバック: Hinemosu

  7. ピンバック: WordPressに関する気になる記事いろいろ | Take It Crazzzy!

  8. をかもと 投稿作成者

    デモ一つだけ問題が僕の使っているブラックだけは表示が変ですわ。他の色は
    すべてOKなのに 🙁

    ホントだ。ブラックの時だけ、周りの線が無い。
    あとで時間のある時に Firebug で css を見てみます。

    返信
  9. yutaka

    やっとわかりました。あのタグ部分を外さないとwp-thread-commentのような
    スレッド表示にならないんですね。作者のサイトのデモでもあのタグが入ってますから
    スレッドの見え方が違いますね。タグを外した見え方の方がいいです。
    文字が大きくなってしますのは改造したときにどっかおかしくなっているようです。
    オリジナルのテーマに変更したら大丈夫でした。
    デモ一つだけ問題が僕の使っているブラックだけは表示が変ですわ。他の色は
    すべてOKなのに 🙁
    Quick Commentsが新しくなった時点でテーマ作り直してみます。

    返信
  10. yutaka

    http://fish1091.com/testwordpress/archives/830
    テストサイトで動かしてみました。なにか他のプラグインと干渉するような動きをしますが
    再読込をするとコメントは出来ているしスレッドになっているようです。
    最初に教えて貰ったように不要な タグがある (495行目付近)
    これを外して試してみましたが、このタグを外すとスレッドが一つ増えるたびに文字がだんだん
    大きくなります。スレッドが五つ目になりますとバカでっかい文字になり笑えました。
    こりゃ使い物にならないわと思ったのですが作者のサイトのデモを見ると文字がだんだん大きく
    なっていないのですよね。おかしいなぁと思ってタグを元に戻すと文字の大きくなるのは直りました :mrgreen:
    何か他のプラグインとの干渉が有るようです。調べてみますです

    返信
  11. yutaka

    おはよう〜

    最新版 Ver.3.2.3 では、これに対応していますよ

    そうなの〜〜 知らなかったわ 😳
    幸せ〜 早速教えて貰った方法でやってみるです!

    返信
  12. をかもと 投稿作成者

    yutaka さん、どもです。

    yutaka さんがお使いの Elegant box テーマは、最新版 Ver.3.2.3 では、これに対応していますよ。
    管理画面の [設定] – [ディスカッション] で [コメントをN階層までのスレッド (入れ子) 形式にする] にチェックを入れるだけで良いです。
    ただ、functions.php の custom_comments() 関数に、不要な </li> タグがある (495行目付近) ので、そこだけ行ごと消せばおっけです。

    返信
  13. yutaka

    こんばんわ〜
    こ、これは一筋縄じゃいかんなぁ 😳 難しいですねぇ
    wp-thread-commentがすんなり動いてくれると有りがたいんですが
    なんか不具合が出るそうですねぇ。とするとこの方法で改造するしかないわけですかぁ
    かなり高度ですね :mrgreen:

    返信

コメントを残す

メールアドレスが公開されることはありません。