NORIのFlashユーザのためのMovable Type講座 gihyo.jp版

第7回コメントをXMLでフィードバック

前回FlashからMTへコメントを送信する仕組みを活かして、写真の★の数を送信しました。今回は、その★の数を再びFlashで表示するため、起動時に読み込むXMLに反映させます。また、★の数を求めるためにMTの演算機能も使用します。

 MTにコメントを送信するFlash
図 MTにコメントを送信するFlash

★の数に対応したXMLを定義する

XMLに★の数を挿入するために、現在のXMLデータの仕様を改造します。

現在のXMLは、MTのインデックステンプレートによって出力されているphoto.xmlです。 フォーマットは次のようになっています。⁠見やすいように1件分のデータだけ示しました)

<?xml version="1.0" encoding="utf-8"?>
<entries>
<entry id="9" title="お台場">
<img src="http://www.3oclock.com/my_first_blog-gihyojp/images/2007-03-25-FromDaiba.jpg" />
</entry>
</entries>

そこで、<entry>要素の中にratingという属性を追加し、そこに現在の★の数から求めた平均値を挿入することにします。 その平均値は、小数点以下で四捨五入した整数とします。

<?xml version="1.0" encoding="utf-8"?>
<entries>
<entry id="9" title="お台場" rating="3">
<img src="http://www.3oclock.com/my_first_blog-gihyojp/images/2007-03-25-FromDaiba.jpg" />
</entry>
</entries>

実は、MT4.1系から、変数を利用した四則演算が可能になりました。

そこで、コメント欄に入っている数字を取り出して計算し、その結果をXMLに反映させます。

MTで計算を行うには変数を扱うMTタグ<$mt:SetVar$><$mt:GetVar$>などにopモディファイアという演算のモディファイアを追加して行います。

そこで、今回はMTタグでの基本的な変数の使用方法から紹介します。

MTタグで変数を設定する

MTで変数を扱う場合に基本になる部分です。変数を設定する場合は、name属性で変数名を、value属性で値を設定します。

<$mt:SetVar name="age" value="38"$>
//age=38

<$mt:SetVar name="name" value="NORI"$>
//name="NORI"

 //ではじまる行は、ActionScriptに置き換えた場合のスクリプト例です。

また、MTタグで出力した値を、さらに変数に代入する場合は<mt:SetVarBlock>を利用します。このタグを利用すると、<mt:SetVarBlock>ではさまれた部分が変数の値になり、MTタグの場合は実際の値に置き換わってから変数に代入されます。

<mt:SetVarBlock name="blogurl"><$mt:BlogURL$></mt:SetvarBlock>
//blogurl=<$mt:BlogURL$>

 <mt:SetVarBlock>は、タグの間の改行も値として変数に入るため、改行しないで1行で書きます。

MTタグで変数を出力する

上記の方法で設定した変数を出力する場合は、<$mt:GetVar$>を使用します。name属性には変数名を指定します。

<$mt:GetVar name="age"$>
//trace(age)

<$mt:GetVar name="name"$>
//trace(name)

<$mt:GetVar name="blogurl"$>
//trace(blogurl)

MTタグで変数の値を参照する

変数を利用するときにもっとも利用価値があるのは、他のタグで変数の値を参照できることだと思います。他のMTタグの中で変数を参照するときは、変数名の頭に$をつけます。例では、変数age2に変数ageの内容をコピーしています。

<$mt:SetVar name="age2" value="$age"$>
//age2 = age

MTタグで変数を使用して計算する

MTタグを使用して四則演算をするには、<$mt:SetVar$>でopモディファイアを使用します。すると、自動的にその変数に演算結果が代入されます。

このopモディファイアは、変数の値が数値同士の場合のみ有効です。

  • add または +: 加算
  • sub または -: 減算
  • mul または *: 乗算
  • div または /: 除算
  • mod または %: 剰余
  • inc または ++: インクリメント(1増加)
  • dec または --: デクリメント(1減少)

たとえば、変数ageを使って計算をする場合は、次のように書きます。

<$mt:SetVar name="age" op="+" value="100"$>
//age+=100

<$mt:SetVar name="age" op="-" value="2"$>
//age-=2

<$mt:SetVar name="age" op="*" value="3"$>
//age*=3

<$mt:SetVar name="age" op="/" value="4"$>
//age/=4

<$mt:SetVar name="age" op="%" value="5"$>
//age%=5

<$mt:SetVar name="age" op="++"$>
//age++

<$mt:SetVar name="age" op="--"$>
//age--

上記のMTタグだけでは、計算結果を出力しません。出力したいタイミングで<$mt:GetVar name="age"$>を使用します。

 opモディファイアは、<$mt:SetVar>でも使用できますが、演算結果を計算と同時に出力するため、変数そのものは演算前のままであることなどの時とは違う動作をします。

変数がひと通り使えるようになったので、次は実際にコメント欄に挿入されている値を取り出し、合計値を取得してみましょう。

詳細はMovable Type 4.1で強化されるMTタグの新機能 opモディファイアをご覧ください。

エントリーごとにコメント欄を調べる

エントリー毎のコメント欄をみたい場合は、ブロックタグ<mt:Entries>の中にさらに、<mt:Comments>というブロックタグを記述します。

コメントの本文は、<$mt:CommentBody$>で取得でき、<mt:Comments>ブロックタグの中は自動的にコメントの数だけループ処理されます。同様に、<mt:Entries>もエントリーの数だけ自動的にループ処理されます。そのため、すべてのエントリーとコメントを調べることができます。

まとめると、次のようになります。

 コメントとして<mt:Ignore>タグを使用しています。このタグの間のテキストはコメントとして処理され、再構築しても無視されます。

<mt:Entries>
<mt:Ignore>***********エントリー開始***********</mt:Ignore>
<mt:Comments>
<$mt:CommentBody$>
</mt:Comments>
<mt:Ignore>***********エントリー終了***********</mt:Ignore>
</mt:Entries>
 テスト用インデックステンプレート
図 テスト用インデックステンプレート

テスト用にインデックステンプレートを新規作成し、出力ファイル名もtest.txtなどとしてMTタグを試します。

再構築すると、<$mt:CommentBody$>の中にすでに入っている<p>タグもいっしょに出力されています。このままでは計算できませんので、htmlタグを削除するモディファイア(remove_html="1")をいっしょに指定して削除します。

また、エントリーのタイトルを表示(<$mt:EntryTitle$>)して、切れ目をわかりやすくしました。

<mt:Entries>
<mt:Ignore>***********エントリー開始***********</mt:Ignore>
<$mt:EntryTitle$>
<mt:Comments>
<$mt:CommentBody remove_html="1"$>
</mt:Comments>
<mt:Ignore>***********エントリー終了***********</mt:Ignore>
</mt:Entries>

これで、コメント欄から数値だけが抜き出されました。

次は、それを変数に代入して加算処理を繰り返すことで合計値を求めてみましょう。

コメントの数値を合計する

コメントの中の数値を加算していくのは、op="+"で行います。この処理をするためにresultという変数を使用しました。

resultがすべてのエントリーを対象にして合算するのを防ぐため、<mt:Comments>が始まる前に、毎回初期化します。⁠<$mt:SetVar name="result" value="0" $>)

<mt:Entries>
<mt:Ignore>***********エントリー開始***********</mt:Ignore>
<$mt:EntryTitle$>
<$mt:SetVar name="result" value="0" $>
<mt:Comments>
<mt:SetVarBlock op="+" name="result"><$mt:CommentBody remove_html="1"$></mt:SetVarBlock>
</mt:Comments>
<mt:Ignore>***********エントリー終了***********</mt:Ignore>
</mt:Entries>

コメント総数を調べる

平均値は、コメントの数値の合計÷コメント総数 で求められます。コメント総数は、次のMTタグ <$mt:EntryCommentCount$> を使用すると求められます。

その値を変数countに代入するために<mt:SetVarBlock name="count"><$mt:EntryCommentCount$></mt:SetVarBlock>を使用して、ブロックタグ<mt:Entries>のあと、かつ<mt:Comments>の前に記述します。

<mt:Entries>
<mt:Ignore>***********エントリー開始***********</mt:Ignore>
<$mt:EntryTitle$>
<$mt:SetVar name="result" value="0" $>
<mt:SetVarBlock name="count"><$mt:EntryCommentCount$></mt:SetVarBlock>
<mt:Comments>
<mt:SetVarBlock op="+" name="result"><$mt:CommentBody remove_html="1"$></mt:SetVarBlock>
</mt:Comments>
<mt:Ignore>***********エントリー終了***********</mt:Ignore>
</mt:Entries>

MTタグで平均値を求める

平均値は、ここまでで求めた以下の変数を利用することで、求められます。

  • コメントの合計値…result
  • コメントの総数…count
  • 平均値=result÷count

これを、MTタグで表現すると、次のようになります。valueの値は、変数countを指定したいので、$countとしています。

次の行では、resultに演算結果が代入されます。

<$mt:SetVar name="result" op="/" value="$count"$>

MTタグで四捨五入する

四捨五入は、opモディファイアには用意されていません。そこで、次のように考えます。

「resultに0.5をプラスして、整数部分だけを取り出す」

 四捨五入のアイデアは、yoshiさんのブログ【Under the Bridge】⁠MT4.2:テンプレートタグのみで切り捨て、切り上げ、四捨五入の演算」を参考にしました。

整数部分だけを取り出すために、sprintfというモディファイアを使用します。これは、C言語のprintf関数と同じフォーマット指定子を出力結果に指定できます。たとえば、sprintf="%d" とすると「整数部分だけを出力せよ」という意味になります。

sprintfモディファイアは、出力するMTタグにしか使用できないため、<$mt:SetVar$>などでは無効です。そこで一度、<$mt:GetVar$>で出力した結果を再び<mt:SetVarBlock>でresultに戻します。

<$mt:SetVar name="result" op="+" value="0.5"$>
<$mt:SetVarBlock name="result"><$mt:GetVar name="result" sprintf="%d"$></mt:SetVarBlock>

MTタグをまとめる

さて、以上のMTタグをまとめて、photo.xmlを出力するインデックステンプレートとして作成しましょう(エントリーの区切り用目印につけていた<$mt:EntryTitle$>は、削除しました⁠⁠。

<?xml version="1.0" encoding="utf-8"?>
<entries>
<mt:Entries>
<mt:Ignore>***********エントリー開始***********</mt:Ignore>
<$mt:SetVar name="result" value="0" $>
<mt:SetVarBlock name="count"><$mt:EntryCommentCount$></mt:SetVarBlock>
<mt:Comments>
<mt:SetVarBlock op="+" name="result"><$mt:CommentBody remove_html="1"$></mt:SetVarBlock>
</mt:Comments>
<$mt:SetVar name="result" op="/" value="$count"$>
<$mt:SetVar name="result" op="+" value="0.5"$>
<$mt:SetVarBlock name="result"><$mt:GetVar name="result" sprintf="%d"$></mt:SetVarBlock>
<mt:Ignore>***********以前作成したphoto.xmlのインデックステンプレート***********</mt:Ignore>
<entry id="<$mt:EntryID$>" title="<$mt:EntryTitle$>" rating="<$mt:GetVar name="result"$>">
<mt:EntryAssets type="image">
<img src="<$mt:AssetURL$>" />
</mt:EntryAssets>
</entry>
<mt:Ignore>***********エントリー終了***********</mt:Ignore>
</mt:Entries>
</entries>
 新しいphoto.xml出力用テンプレート
図 新しいphoto.xml出力用テンプレート

出力ファイル名をphoto.xmlとして、現在Flashが読み込むXMLを上書きしておきます。

Flashでrating属性に対応する

Flashのソースでは、次の3カ所を修正しました。

(1)で、属性を読みこみ(2)で表示処理を行います。⁠3)は、直接関係ないですが、何度かテストしてブラウザキャッシュを読まずに、正しい結果が表示されるようにXMLのロードで、毎回異なる変数をつけて呼び出しています。

(1)新しいrating属性をE4Xで読みます。

function onLoaded(e:Event):void {
      //XMLデータとして読み込んだテキストデータをパース
      var myXML:XML=new XML(e.target.data);
      //E4XでmyXMLを解析
      for each (var entrydata:XML in myXML.*) {
            //Objectの配列としてデータを格納
            var t_object:Object = new Object();
            t_object.src=entrydata.img.@src;
            t_object.id=entrydata.@id;
           t_object.rating=entrydata.@rating;
            t_object.title=entrydata.@title;
            image_array.push(t_object);
      }
      showPicture(0);
}

(2)読み込んだデータをさらに、★の表示に反映させるためにstarsのフレームを指定しました。

starsは5フレームまであるムービークリップです。★の数が、フレームごとに増えるように作ってあり、raitng値=フレーム番号なので、gotoAndStop()で表示する★の数を調整できます。

stars.gotoAndStop(image_array[current_image_num].rating)
 ムービークリップstars
図 ムービークリップstars

(3)Flash側で、ブラウザキャッシュを拾わないで毎回XMLを取得するようにURLRequestの内容に毎回値が変化する変数(rnd)を付けます。

var myURLRequest:URLRequest=new URLRequest("http://www.3oclock.com/my_first_blog-gihyojp/photo.xml?rnd="+Math.random()*10);

まとめ

今回は、コメントとして投稿された★の数の平均値を求め、XMLのrating属性として出力しました。

MTテンプレートはMT4.1以降、非常に強力になったので、工夫次第で簡単な数式であれば組み上げることも可能です。

コメントの内容を、とりあえずFlashに読み込み、その後で計算することも考えられますが、次回、Flashをhtmlに埋め込むときに使用したいので、Flash以前の計算にこだわりました。ぜひ、MTでの変数操作と計算に挑戦してみてください。

また、Flash側では、新たにXMLから読み込んだrating属性を★の数に反映させました。写真が切り替わると、★の数も変化するのがわかると思います。

今回作成したFlashは、サンプル(showPicture3.zip)としてダウンロードできます。

次回は、最終回です。Flashをhtmlの中に表示してWEBコンテンツとして完成させます。

おすすめ記事

記事・ニュース一覧