MTCommentTree プラグインと JavaScript

Posted by
ぴろり
Posted at
2006/04/17 20:01
Trackbacks
関連記事 (0)
Comments
コメント (1)
Post Comment
コメントできます
Category
プラグイン カテゴリ

 MovableType のコメント欄でツリー掲示板を実現するプラグインMTCommentTree は、MovableType のテンプレートタグを拡張するだけですから、返信用のリンクなどの処理は JavaScript なりを使って自前で用意してやる必要があります。先日、FOX通信Irana さんから、このあたりの処理や書き方について詳しく知りたいとの要望がありましたので、 こちらのエントリに起こさせて頂きましたm(_ _)m
 このエントリでは、MTCommentTree プラグインを使用して、ツリー型掲示板を設置する際に必要なテンプレートタグの書き方や JavaScript について説明しています。

このエントリーをはてなブックマークに追加  

MTCommentTree プラグイン動作の基礎

親子関係を持つコメントの例  MTCommentTree で表示されるコメントには二つの種類があります。
  1. 親を持たないコメント(右図の [1])
  2. 親を持つコメント(右図の [2][3][4])
 とはそのコメントの返信先コメント([2]から見た[1]、[4]から見た[2]、[3]から見た[1])のことを言い、 返信元コメントから見た返信コメントのことを([1]から見た[2]と[3]、[2]から見た[4])と言います。

子の子を孫と言いますが、MTCommentTree では重要ではありません

 また、一つのコメントは高々一つの親と、0 個以上の子を持つことができますが、 親を二つ以上持つことは決してありません。 親を持たないコメントは列の一番左に表示され、特にルート(root; 根っこの意味)と呼ばれます。
 MTCommentTree プラグインでは、このようなコメントの親子関係を 「このコメントの親はどのコメントか?」という紐付けで管理しています。つまり、
  1. コメント[1]は親を持たない
  2. コメント[2]はコメント[1]を親に持つ
  3. コメント[3]はコメント[1]を親に持つ
  4. コメント[4]はコメント[2]を親に持つ
という情報が必要になります。

 MTCommentTree プラグインでは、特定のコメントへの返信がされる時、 「どのコメントに対する返信なのか=どのコメントを親に持つのか」という情報を、 コメント投稿欄の URL 欄から判断します。 そのため、URL 欄を本来の目的で使用することはできなくなってしまいますが、 その反面、MovableType 本体に特に改造を必要とすることもなく導入することが可能としているのです。
 URL 欄に 1 と入れて投稿されたコメントは コメント 1 を親に持つ、1 の子となります。 また、URL 欄が空欄の場合、投稿されたコメントは親を持たないルートになります。

説明のために 1, 2, 3 ... という数字を使っていますが、実際にはコメント ID を指定します。

テンプレートの書き方

 先ず、従来のコメント表示の部分を、MTCommentTree プラグインを使ってコメントの親子関係を表示できるよう、 MovableType のテンプレート管理画面からエントリアーカイブテンプレートを修正します。
<MTCommentTree>
<$MTCommentAuthor$> at <$MTCommentDate$><br />
<$MTCommentBody$>
<MTCommentHasChild><blockquote>
	<$MTCommentChildRecurse$>
</blockquote></MTCommentHasChild>
</MTCommentTree>
 <$MTCommentChildRecurse$> が少し理解に苦しまれるかもしれませんが、 この部分には <MTCommentTree></MTCommentTree> の部分が、 写し鏡のように繰り返し書かれていると考えてください。 <MTCommentTree> コンテナタグで一つの親と子が、 どのように HTML に表現されるかを書いておくことで、 親と子、子と孫、孫と曾孫…という関係でも再帰的に扱うことができます。

親子関係の再帰的な表現

コメント投稿フォームの下準備

 投稿されたコメントをツリー形式で表示するための準備はできたので、 次に親子関係にあるコメントを投稿できるように作業を行います。
 本来、URL を入力していた URL 用のフィールドは MTCommentTree が占有してしまうため、 一般ユーザに好き放題な値を代入されるのは問題があります。 そこで、コメント入力フォームを生成する HTML のうち、 URL 用フィールドを生成している部分を隠し(type=hidden)フィールドに置き換えます。
<form name="comments_form" method="post" action="http://www.example.com/mt/mt-comments.cgi">
:
// 書き換え前
ホームページなどの URL を入力してください:<br />
<input type="text" name="url" value="" />
↓
// 書き換え後
<input type="hidden" name="url" value="" />
:
</form>
 また、ブラウザの Cookie から、 以前に入力された URL をフォームに自動設定する処理があるので、こちらも消しておきます。
// ↓以下のコードを削除しておきます
if (document.comments_form.url != undefined)
    document.comments_form.url.value = getCookie("mtcmtauth");
// ↑ここまで

返信用のリンクを作成

コメント横の返信用リンクの例  このままでは URL 欄が見えないので、ユーザが値を入力することができません。 そのため JavaScript を使って、返信したいコメントをクリック一つで指定できるようにしてみます。 例えばコメント毎に"このコメントに返信する"といったようなリンクを用意しておき、 リンクがクリックされると、親コメントを URL フィールドに設定する、という処理を追加します。
<script>
function ReplyTo (cid) {
	// cid で指定された コメントID を URL フィールドに指定します
	document.comments_form.url.value = cid;
}
</script>
 そして、コメント毎に"このコメントに返信する"というリンクを作るため、 MovableType のエントリアーカイブテンプレートを編集します。
<MTCommentTree>
<$MTCommentAuthor$> at <$MTCommentDate$>
<a href="#" onclick="ReplyTo(<$MTCommentID$>)">このコメントに返信する</a><br />
<$MTCommentBody$>
<blockquote>
	<$MTCommentChildRecurse$>
</blockquote>
</MTCommentTree>
 これで、コメント毎に用意されたリンクをクリックすると、 JavaScript 関数 ReplyTo によって コメント ID が URL フィールドに設定されます。 そして、この状態で投稿されたコメントは親子関係を持って表示されることになります。

更に進んで 〜 返信対象のコメントを分りやすくする

返信先のコメントを目立たせてみる例  この段階で、返信コメントを投稿する基本的な部分の改造は全て終わりました。 しかしこれを使ってみると気が付かれると思うのですが、 何れかのコメントにある"このコメントに返信する"のリンクをクリックしても画面には一切変化がありません。 そのため、書いているコメントがどのコメントへの返信であったのかだとか、 間違ってリンクをクリックしてしまったために予期せぬコメントが付いてしまったり…と云った事故(?)を防げません。
 そこで、返信用リンクがクリックされた場合には、どのコメントへの返信なのか分りやすく明示できるようにしてみます。 例えば、返信元コメントの背景色を変えて、これを目立たせてみます。
<MTCommentTree>
<span id="cid<$MTCommentID$>">
  <$MTCommentAuthor$> at <$MTCommentDate$>
  <a href="#" onclick="ReplyTo(<$MTCommentID$>)">このコメントに返信する</a>
</span><br />
<$MTCommentBody$>
<MTCommentHasChild>
<blockquote>
	<$MTCommentChildRecurse$>
</blockquote>
<MTCommentHasChild>
</MTCommentTree>
<script>
// cid で指定された コメントID を URL フィールドに指定します
function ReplyTo (cid) {
	// 指定されたコメントのヘッダ部分の背景を変化します
	document.getElementById('cid' + cid).style.backgroundColor = 'orange';
	// cid で指定された コメントID を URL フィールドに指定します
	document.comments_form.url.value = cid;
}
</script>

更に進んで 〜 返信をキャンセルする

返信キャンセルのリンクの例  先の改造で返信先コメントを分りやすくすることはできましたが、 間違って"返信する"リンクをクリックしてしまった場合には、二度とルートコメントを投稿できません。 また、"返信する"リンクを次々とクリックすると、背景の色が変わったまま残ってしまいます。
 この節では、先のコードを改造し、もう少し使い勝手を増してみます。
  • 返信のためのガイダンスメッセージを表示する
  • "返信のキャンセル"リンクを追加

<form name="comments_form" method="post" action="http://www.example.com/mt/mt-comments.cgi">
<input type="hidden" name="url" value="" />
:
//↓ガイダンスメッセージの表示用
<div id="guidance_msg"></div>
:
</form>
<script>
// cid で指定された コメントID を URL フィールドに指定します
function ReplyTo (cid) {
	// コメントの背景を元に戻して
	ReplyReset (document.comments_form.url.value);
	// 指定されたコメントのヘッダ部分の背景を変化します
	document.getElementById('cid' + cid).style.backgroundColor = 'orange';
	// cid で指定された コメントID を URL フィールドに指定します
	document.comments_form.url.value = cid;
	// ガイダンスメッセージと返信キャンセルのためのリンク
	document.getElementById('guidance_msg').innerHTML =
			'このコメントへの<a href="javascript:ReplyReset('+cid+')">返信を取消し</a>ます';

}

// 返信の取消し
function ReplyReset (cid) {
	var e = document.getElementById('cid' + cid);
	if (e)
		e.style.backgroundColor = 'transparent';
	// 返信先コメントをなし(=ルートコメント)に指定しなおす
	document.comments_form.url.value = '';
	// ガイダンスメッセージを表示
	document.getElementById('guidance_msg').innerHTML =
			'特定のコメントに対して返信するには、' +
			'返信したいコメントの"このコメントに返信する"をクリックしてください';
}
ReplyReset ();
</script>

親や子の時に処理を変える

 MTCommentTree プラグインには、 MTCommentHasChildMTCommentHasNoChildMTCommentIsRoot と云った条件タグが用意されていますので、ルートコメントにのみアイコンを表示したり、 子コメントが無い場合でデザインを変えたり、と云ったカスタマイズも可能です。

コレ!と云った具体例が挙げられないのですけれど(^^;

このエントリーをはてなブックマークに追加  



関連記事/トラックバック

関連記事/トラックバックはまだありません

この記事にトラックバックを送るには?

寄せられたコメント (全 1 件中、最新 5 件まで表示しています)

Posted by
IranaIrana
at
2006/04/17 22:58
ID
4vYBLehU
あああああ、すいませんすいません、わざわざのエントリ立てありがとうございます。
これでうちの掲示板(の代わりのエントリ)をもう少しそれっぽくすることができそうです。
次のおやすみにでもチャレンジしてみます。
ありがとうございました。

コメントを投稿する

 
 (必須, 匿名可, 公開, トリップが使えます)
 (必須, 匿名可, 非公開, Gravatar に対応しています)
 (必須)
スパム コメント防止のため「投稿確認」欄に ランダムな数字 CAPTCHAについて を入力してから送信してください。お手数ですがご協力のほど宜しくお願いいたします。