Movable Type 備忘録

 

 Movable Type のコメントを Ajax で投稿する2

こんばんわ^^

わたしのサイトで配布してますテンプレートでは、Ajax を使ってコメント投稿するようにカスタマイズされてます。
ただし、今までだとコメント設定にて「自動的に公開しない」にしておかないとダメなものでした。

その理由は・・・わたしが「自動的に公開にしない」にしているからですねぇ (; ̄∇ ̄A はは

でも人によっては即時投稿の人もいるかと思いますので、重いおしり(腰)を上げてコメントの即時投稿が選択された場合、ページをリロードして即座にコメント表示するよう対応しました。

また、以前にもコメント投稿の Ajax 化は記事にしてますが、参考までに改めて説明してみたいと思います。

Movble Type のコメント投稿のしくみ

Movable Type のコメント投稿は、各ブログで設定されている即時公開の条件によって異なります。

「自動的に公開しない」を選択された場合、「コメントプレビュー」、「コメント完了」システムテンプレートが使用されます。 反面、「すべて自動的に公開する」が選択された場合、コメント投稿したページが表示されるようです。

ディレクトリ構成

コメント投稿の Ajax 化は以下のようなディレクトリ構成として説明していきます。

http://●●●.com/
  |
  +-- index.html( トップページ )
  |
  +-- js/
  |    +-- prototype/
  |        +-- prototype.js
  |        +-- prototype.comment.js
  |        |
  |        +-- image/
  |            +-- ajax-loader.gif

カスタマイズ

コメント投稿の Ajax 化は以下の手順で行います。
[2008.04.26] HTML ヘッダの記述について説明してなかったので追記しました。

  1. prototype.js 入手
    prototype.js をこちらの prototype のページから入手して、js/prototype/ フォルダの下にアップロードします。

  2. コメントフォームの修正
    コメントフォームを修正します。 具体的にはプレビューボタンと投稿ボタンを以下のように修正します。

    <input type="submit" accesskey="v" id="comment-preview" tabindex="15" value="Preview" onkeypress="javascript:void(0);" onclick="return ajaxcomment_preview('comment_results');" />
    <input type="submit" accesskey="p" id="comment-submit"	tabindex="16" value="Post"	onkeypress="javascript:void(0);" onclick="return ajaxcomment_post('comment_results');" />
    

    青字にはプレビュー、またはコメント投稿結果を表示する ID 名称を指定します。
    次にプレビュー、コメント投稿結果を表示したい場所に以下を追加します。

    <div id="comment_results">&nbsp;</div>
    

    青字は先ほどの各ボタンで説明した青字の ID 名称と同じにしてください。
    一通り修正したら保存します

  3. コメント投稿用スクリプト
    コメント投稿用のスクリプトを作成します。以下のコードをテキストエディタにコピー & ペーストしてください。

    var ajaxloader        = 'http://●●●.com/js/prototype/image/ajax-loader.gif';
    var ajaxcomment_divid = '';
    var ajaxcomment_cgi   = ['http://●●●.com/mt/', 'mt-comments.cgi'].join('');
    /*
     * ローダーイメージの表示/非表示
     */
    function show_ajaxloader(elem, enable)
    {
        if (enable) {
            elem.innerHTML        = '';
            elem.style.height     = '100px';
            elem.style.background = 'transparent url('+ajaxloader+') no-repeat center center';
        }
        else {
            elem.style.height     = 'auto';
            elem.style.background = 'none';
        }
    }
    /*
     * コメント投稿
     */
    function ajaxcomment_post(divid)
    {
        ajaxcomment_divid = divid;
        show_ajaxloader($(ajaxcomment_divid), true);
    
        var form = $('comments-form');
        if (form.bakecookie.checked) rememberMe(form);
    
        var pars = Form.serialize('comments-form')+'&post=post';
        new Ajax.Request(ajaxcomment_cgi, {
                        method: 'post',
                        parameters: pars,
                        onComplete: function (req) {
                            if (0 < req.responseText.indexOf('DOCTYPE', 0)) {
                                document.location.reload();
                            }
                            else {
                                if (0 < req.responseText.indexOf('コメントを投稿しました。', 0)) {
                                    $('comments-form').style.display = 'none';
                                }
    
                                var divid = $(ajaxcomment_divid);
                                show_ajaxloader(divid, false);
                                divid.innerHTML = req.responseText;
                            }
                        },
                        onFailure: function (req) {
                            $('comments-form').style.display = '';
    
                            var divid = $(ajaxcomment_divid);
                            show_ajaxloader(divid, false);
                            divid.innerHTML = req.responseText;
                        }
                    });
        return false;
    }
    /*
     * コメントプレビュー
     */
    function ajaxcomment_preview(divid)
    {
        ajaxcomment_divid = divid;
        show_ajaxloader($(ajaxcomment_divid), true);
    
        var pars = Form.serialize('comments-form')+'&preview=preview';
        new Ajax.Request(ajaxcomment_cgi, {
                        method: 'post',
                        parameters: pars,
                        onComplete: function (req) {
                            var elem = $(ajaxcomment_divid);
                            show_ajaxloader(elem, false);
                            elem.innerHTML = req.responseText;
                        },
                        onFailure: function (req) {
                            var divid = $(ajaxcomment_divid);
                            show_ajaxloader(divid, false);
                            divid.innerHTML = req.responseText;
                        }
                    });
        return false;
    }
    

    赤字の URL を各自の環境に合わせて変更します。
    ちなみに上記スクリプトは prototype.js 版となります。他の JavaScript フレームワークを使用している人は各自で変更してください。

    青字の部分は「自動的に公開しない」を設定した場合に正常終了/エラーを識別するための文字列を指定します。
    たとえば、デフォルトのテンプレートですと、「コメント完了」システムテンプレートの 9 行目の「コメントを投稿しました。」が送られてきた場合には正常終了とみなしています。

    また、1 行目の ajax-loader.gif はこちらの Ajaxload - Ajax loading gif generator などからお好みで作成できます。

    一通り変更したら適当な名前(たとえば、prototype.comment.js)で保存します。 そして、js/prototype/ フォルダの下にアップロードしてください。

  4. HTML ヘッダを変更
    HTML ヘッダ(<head>~</head>)内に以下を追加します。

    <mt:if name="feedback_template">
    <script type="text/javascript" src="http://●●●.com/js/prototype/prototype.js"></script>
    <script type="text/javascript" src="http://●●●.com/js/prototype/prototype.comment.js"></script>
    </mt:if>
    

    赤字の部分ではフィードバックテンプレート(エントリページ、ウェブページ)の場合のみスクリプトをロードするよう条件設定してます。
    青字の部分を各自の環境に合わせて変更します。

    追加したらエントリページ、ウェブページのみ再構築します。

  5. 動作確認
    動作確認します。コメントプレビュー、コメント投稿がページ移動せずに正しく動作することを確認してください。

以上でコメント投稿の Ajax 化は完了です ( ̄∇ ̄)/

コメントプレビュー時やコメント投稿時でページ移動という煩わしさから解放されますので、お試しください。
また、週末の間だけコメントの即時投稿に設定しておきますので、ご確認頂けたらと思います。

 Trackback Pings(0)

No trackbacks found.

 Comments(6)

#1: Posted by aiko_m Author Profile Page [RES]

bzbellさん、お忙しいところ有難うございました。

ちょっと大がかりになりそうなので、落ち着いてから試させて頂きたいと思っていますが、何点か質問させて下さい。

>1.Movble Type のコメント投稿のしくみ

私の処では、サインインした方のみ、即時公開になっています。ゲストの方は承認後公開。
で、即時公開の場合は[コメント完了]ページは表示されず、画面がリロードされコメントが表示されます。
[承認後公開]の場合は[送信]を押した後、[コメント完了]ページになります。

ちなみに管理画面のコメントポリシーは「自動的には公開しない」になっています。
それなのにサインインしたユーザー書き込みが公開されてしまう動作がちょっと怪しいのですが、このパターンでも大丈夫でしょうか?。

prototype.js は他のものでも使っていますので既に読み込む設定になっているのですが、prototype.comment.js もヘッダ部分で読み込みをさせれば良いのでしょうか?。

あと、大ぼけかもしれませんけど、私のブログはダイナミックパブリッシングでもなければPHP化もしていないのですが…大丈夫でしょうか?。

#2: Posted by bzbell Author Profile Page [RES]

>>1 aiko_m さん

こんにちわ^^

> ちなみに管理画面のコメントポリシーは「自動的には公開しない」になっています。
> それなのにサインインしたユーザー書き込みが公開されてしまう動作がちょっと怪しいのですが、このパターンでも大丈夫でしょうか?。

えっ!? 「自動的には公開しない」にも関わらず即時公開されるんですかあせあせ
それって「認証サービスで認証されたコメント投稿者のみ」or 「ブログで承認されたコメント投稿者のみ」を選択した場合の動作っぽいですね。

でも大丈夫だと思います。
即時公開される場合は mt-commets.cgi からの応答はコメント投稿したページがそのまま返ってきます。逆に公開待ちだとシステムテンプレートの「コメント完了」の内容が返ってきます。

要するに、どの即時公開する条件を設定しても動作するパターンは 2 通りなので問題ないかと思われまするうぅ~ん

> prototype.comment.js もヘッダ部分で読み込みをさせれば良いのでしょうか?

そこら辺はお好みでしょうか。
テンプレート内に埋め込んでもいいですが、テンプレートの中がスッキリします。それに XHTML 的には JavaScript は外部ファイルにしましょう・・・といわれてますのでうぅ~ん

> 大ぼけかもしれませんけど、私のブログはダイナミックパブリッシングでもなければPHP化もしていないのですが…大丈夫でしょうか?。

はい。問題ないですワクワク

#3: Posted by aiko_m Author Profile Page [RES]

>>2 bzbell さん

>えっ!? 「自動的には公開しない」にも関わらず即時公開されるんですか

はい(^^ゞ。ですから最初、正しい動作が分からなくてネットを検索しまくりましたが、サインインに関してのトピックも少ないですね。無料ユーザーなので質問する訳にもいかず、マニュアルがしっかりしたものが製品版に付いているなら、購入しようかと考えています。
(HPにあるマニュアル程度しか付いてないなら考え物ですが…)

ちなみに、この辺りの動作はいじっていませんし、メンバー登録って「何?」って未だにその動作がよく分かりません。あと、LiveJournalでログインしようとするとエラーが出るそうなんですが、bzbellさん、オープンIDで登録なさって下さっていません?。それも何故出来たのか不思議です(^^ゞ。

初歩的な質問にお答え下さって有難うございます≦(._.)≧。

>XHTML 的には JavaScript は外部ファイルにしましょう・・・

確かにそのほうが管理も楽ですよね。テンプレートに書いちゃうとちょっとした修正の度に再構築が必要ですし、出来る限り外部ファイルにしたいのですが、FC2なんかだと外部ファイルが別サーバーに保存される仕組みなので、それだとよくサーバーが落ちるとエラー頻発なので困ることもあって、環境によって何がベストか?を見極めるのもカスタマイズには大切なことと痛感しました。

ps:
ちょっと違うお話しですが、「res」を押した時に表示される
「>>2 bzbell さん」
ですが、コメント入力領域にカーソルを合わせると消えてしまいます。
それでそのまま書き込むと、その部分が無くなった状態になり、
ですから念のためもう一度[res]を押すと今度は

>>2 bzbell さん
>>2 bzbell さん

と二つ表示されて、書き込んでも消えません。
勿論、ダブっている一つは消しますが、これ、「>>2 bzbell さん」が
表示つれた後、カーソルを置く場所にコツがあるのでしょうか?。
それともこれもAikoのパソだけでしたら…。まじリカバーしてみたほうが
良いかもしれませんね。

#4: Posted by bzbell Author Profile Page [RES]

>>3 aiko_m さん

> マニュアルがしっかりしたものが製品版に付いているなら、購入しようかと考えています。

どうですかねぇ。
機能的な差異があるだけでマニュアルはいっしょのような気がしないでもないですガーン

ユーザ登録はコミュニティ・ソリューションってのを別途インストールしないと意味ないようです。わたしも最初わっけ分からなくって悩みました。
要するに MT を CMS として使う・・・といった関連のことではないですかねあせあせ 普通にブログする程度なら関係ないと思って無視してます。

> bzbellさん、オープンIDで登録なさって下さっていません?

わたし前にコメント残したことありますから、その時に確か OpenID を使ったように思います。

> ・・・コメント入力領域にカーソルを合わせると消えてしまいます。

えっあせあせ!?
また新たな事実です。確かに IE6 だとそのような現象がでました。

textarea タグに JavaScript を使用してまして、初期表示時に「Leave your comment here.」って文字列を表示させてます。
フォーカスが入った時にその文字列クリアってことをやってるのですが、IE だとそれが正常動作しないようです。

IE に限っては、一度テキストエリアをフォーカス(入力状態)して、それから RES をポチッ!! とするとよさそうですあせあせ

何だか面倒ですね。対策考えますもじもじ

#5: Posted by bzbell Author Profile Page [RES]

>>3 aiko_m さん

ユーザ登録通常の MT でもできるようです。
以下にその手順を記します。

  1. MT の管理画面から「ブログの設定」>「登録/認証」を選択

  2. 「ユーザー登録」をチェックして「変更を保存」ボタンクリック

  3. コメント投稿時のサインインで Movable Type を選択

  4. 下にある「アカウントがないときはサインアップしてください。」でユーザ登録可能

でしたワクワク

#6: Posted by aiko_m Author Profile Page [RES]

>>4 bzbell さん
なるほど、コメントを書く前。[res]を押す前にココをクリっとしておけば大丈夫です!。なんか重箱の隅を突くようなことばかりですみません。でももう分かったので大丈夫ですよσ(^^)。

って多分、bzbell さんの性格だと完璧を目指すのかな(^_^;。

多分ブログを持たない普通の観覧者の方は、細かい動作など気にされないと思いますし、クロスブラウザを考えると、もうキリがないですよね。

 Post a Comment

コメント用フィード