Movable Type 4 での Five Star Rating 実現方法

blog.li.nu >
この記事が役に立ったら
 最近無駄にアクセスがあるので、特にどこかに宣伝したわけでもないのに一体誰が見に来ているのだろうと調べたら、Google で Movable Type 関連の検索をしてここにたどり着いたというのが大半を占めていた。その中でも、Five Start Rating (五つ星評価) の検索数はそれなりに多いが、それは、Movable Type では、テンプレートタグリファレンスに Five Star Rating 関連のタグがあるにもかかわらず、なぜかそれを使うには別途プラグインを導入しなければならないというよく分からない事態、つまり初期状態では使えないということから来ているものだ。このブログで取り上げたというか題材にしたのは、ここがそれを導入したという記事のみ。おそらく検索でそこにたどり着いた人は、導入方法を知りたかったのだろうが、さすがに単に導入できたという情報を検索で掴んでも何も面白くないだろうから、改めてここではどうやって導入すればいいかを記しておくことにする。ここでは、以下のような Five Star Rating を実現できる。どれも触れるので、適当に遊んでみるとよい。
Five Star Rating 実現のための道具を入手する
 Five Star Rating 関連のタグは用意されているものの、使うためには別途導入のプラグイン扱いというのならば、どうせならもっと高機能なものを使おうということで、ここでは五つ星評価系の中では非常に優秀な Starbox というもので五つ星評価を実現させることを試してみる。ここでもこれを使っている。まず、これは最初無料だったが、突然有料になったらしい。クレジットカードで払えるし 3 ユーロだからそんなに値段も、手間もかからないのだが、いくら優秀だからといって、さすがにお金を払ってまでやるくらいなら・・・という人も多いと思うので、ここでは過去版が無料でされているから、それを使う。といってもこれは作者自身が公開しているものではなく、ライセンス条件を変更してしまった以前は MIT ライセンス (自由に再配布などをして構わず、さらに無償である) を適用していたことにより、それらの版は MIT ライセンスに基づいて無償で、再配布してもよいだろうという考えに基づいて公開されているようである。まあ何というか外国らしい考え方だと思う。
001.png
ダウンロードする場所にアクセスしたら、Downloads タブではなく Source タブを押す。
002.png
次に、Browse を押す。
003.png
すると、ファイル構成が出てくるので左のツリービューから trunk を選ぶと、0.3.0.4 というのが出てくるので、さらに押して css, images, js を出す。これらにはそれぞれ、画像のようにファイルがいくつか入っている。これらをダウンロードする前に、0.3.0.4 以下のファイル構成を全て忠実に再現させておく。
004.png
0.3.0.4 は starbox とでもしておけばいい。これ以下はフォルダ構成を忠実に守って作成する。そして、ダウンロードページから、それぞれのフォルダに存在するファイルたちを、今作ったフォルダにコピーしていく。
005.png
そのまま右側のファイル名を右クリックして、対象をファイルに保存を押して保存しても、うまくいかないので注意。ダウンロードするには、ファイル名を押して、出てきた右側のメニューの中から "View raw file" へのリンクがあるので、これを保存すればいい。手順が多いが、ファイル数はあまり多くないからそんなに苦労しないだろう。ダウンロードが終わったら、starbox フォルダを適当な場所にアップロードする。ここでは、とりあえずルート直下にアップロードしたと想定する。これで設置自体は終わった。
Starbox の動作確認
 とりあえず細かい設定をどうのこうのする前に、まず動くかどうかだけ確かめてこよう。使い方自体は別に有料になっても変わっていないので、本家から設置方法を確認する。それによると、
1. prototype と scriptaculous のライブラリを参照するために、該当ページの head タグ内に次のコードを貼る。
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js'></script>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/scriptaculous/1/scriptaculous.js'></script>
実はStarbox は単独では動作せず、Scriptaculous と、Prototype というものがなければならない。普通はそれぞれダウンロードして・・・という面倒なことが必要なのだが、最近 Google がこの手のライブラリをオンラインで公開するサービスを始めたため、わざわざこれらのライブラリをダウンロードして設置しなくても Google 内に保存されている各ライブラリへの直リンクを貼れば良いとのことだ。
2. head タグに starbox.css への参照を貼る。
<link rel="stylesheet" type="text/css" href="http://li.nu/starbox/css/starbox.css" />
もちろん上のアドレスは私の設置環境での話なので、 http://li.nu/ は、そちらのアドレスに書き換えてほしい。要するに、先ほど作ったファイル構成の starbox -> css -> starbox.css への参照を head タグ内に入れてあげればいいだけ。とりあえず今は動くかどうかを見たいだけなので適当に作った html ファイルにこれらを既述しておこう。実際に使うときには、次の記述を加えればよい。
<div id='element'></div>
<script language='javascript' type='text/javascript'>new Starbox('element', average);</script>
div の id に指定されている値も、Starbox クラスのコンストラクタ引数も、同じ値でなければならないので、注意すること。残念ながら当方は javascript には全く触れたことがないので、どうして id 要素だけしか指定されていない div タグが Five Star Rating に置き換わるのかはよく分からないのだが、この div ブロックがそのまま Five Star Rating に化けるようなので、div だからといってコードから除外すると正しく表示してくれないから、これも必ず入れるようにする。average には、最初からいくつの評価が表示された状態かを指定する。これらのことを総合して、とりあえず一度 Starbox を呼び出してみる。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js'></script>
  <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/scriptaculous/1/scriptaculous.js'></script>
  <script type='text/javascript' src='http://li.nu/starbox/js/starbox.js'></script> 

  <link rel="stylesheet" type="text/css" href="http://li.nu/starbox/css/starbox.css" />
</head>
<body>
  <div id='test'></div>
  <script language='javascript' type='text/javascript'>new Starbox('test', 0);</script>
</body>
</html>
009.png
このようにちゃんと呼び出せていることが確認できたが、実はこれだけでは投票結果は保存されないため、投票結果を保存するように記述を加える必要がある。
投票結果の保存
 保存については、どうやらスクリプトを自作しなければならないようだ。公式サイトの Tutorials によると、savestar.php というものを呼び出しているようだが、ここでの処理は自分で作ってほしいとのことらしい。当方は php は全く触れたことがないため、ここで諦めようかと思ったが、執念でとりあえずその辺のリファレンス系サイトを見て、見よう見まねで作ったので、savestar.php をここからダウンロードして、starbox.js と同じところにアップロードする。もちろんこの php ファイルは各自で作ってもいいだろう。というより、作れるなら各自で作ってもらった方が質がよくなると思う。
 次に、ライセンスに基づいて、starbox.js に少々改変を施す。まず、長々しいコードが出てくると思うが、Starbox クラスを見つけて、さらにその中から initialize イベントを見つけ出して、そのイベントを丸ごと以下のように書き換える。
  initialize: function(element, average) {
    this.element = $(element),
    this.average = average;

    this.options = Object.extend({
      buttons: 10,
      className : 'default',
      color: false,
      duration: 0.6,
      effect: { mouseover: false , mouseout: (window.Effect && Effect.Morph) },
      hoverColor: false,
      hoverClass: 'hover',
      ghostColor: false,
      ghosting: false,
      ratedClass: 'rated',
      identity: false,
      indicator: '#{average} rating from #{total} votes',
      inverse: Starboxes.inverse,
      locked: false,
      max: 5,
      onRate: Starboxes.onRate,
      rerate: Starboxes.rerate,
      rated: false,
      overlay: Starboxes.overlay,
      stars: 5,
      total : 0
    }, arguments[2] || {});

    var result;
    var param = 'mode=current&id='+this.element.id;
    new Ajax.Request('http://li.nu/starbox/js/savestar.php',
      { method: 'post',
        parameters: param,
        asynchronous:false,
        onComplete: function(xhr) {
          // optional callback
          result = xhr.responseText.split("<>");
          
        }
      }
    );

    if(!(result[0] == 'NOT_RATED')){
      this.average = parseFloat(result[0]);
      this.options.total = parseFloat(result[1]);
    }

    this.rated = this.options.rated;
    this.total = this.options.total;
    this.locked =  this.options.locked || (this.rated && !this.options.rerate);

    if (this.options.effect && (this.options.effect.mouseover || this.options.effect.mouseout))
      Starboxes.require('Scriptaculous');

    Starboxes.queueBuild(this);
    if (Starboxes.batchLoading) Starboxes.processBuildQueue();
  },
実は赤い部分以外にもカスタマイズ部分を変えてあるのだが、大きな改変は主に赤い部分になっている。savestar.php に処理を要求する記述が加わっている。ここでの 'http://li.nu/starbox/js/savestar.php' は、各自の savestar.php のアドレスに書き換えること。次に、onClick イベントも以下のように丸ごと書き換える。
  onClick: function(event) {
    var element = event.element();
    if (!element.rating) return;

    this.updateAverage(element.rating);
    if (this.options.indicator) this.updateIndicator();
    if (this.options.ghosting) this.setBarPosition(this.ghost, this.average, (window.Effect && Effect.Morph));

    if (!this.rated) this.status.addClassName('rated');
    var rerated = !!this.rated;
    this.rated = element.rating;

    if (!this.options.rerate) {
      this.disable();
      this.status.addClassName('locked');
      this.onMouseout(event);
    }

    var info = {
      average: this.average,
      identity: this.options.identity,
      max: this.options.max,
      rated: element.rating,
      rerated: rerated,
      total: this.total
    };
    this.options.onRate(element, info);

    var param = 'mode=rating&id='+this.element.id+'&rate='+info.rated;
    new Ajax.Request('http://li.nu/starbox/js/savestar.php',
      { method: 'post',
        parameters: param,
        onComplete: function(xhr) {
          // optional callback
          var result = xhr.responseText;
          if(!(result == 'COMPLETED_SUCCESSFULLY')){
            alert("An error has occured:"+result);
          }
        }
      }
    );
    this.element.fire('starbox:rated');
  },
ここにある 'http://li.nu/starbox/js/savestar.php' も、各自の savestar.php のアドレスに書き換える。これで全て完了したので、実際に適当なページで呼び出してみればいい。使い方は先ほど動作確認したときと全く変わっていない。
010.png
アクセスすると、下に自分でカスタマイズして追加したので何とか rated from 何とか votes が表示されているが、何も変わっていないように見える。とりあえず、適当に投票する。
011.png
そして、リロードすると、今までとは違い、ちゃんと投票数と投票結果が残っている。これで、投票結果が保存されるようになったので、あとはどうやって Movable Type に適用して、記事ごとの評価を実現させればいいか考える。
Movable Type 4 の各記事への配置
 Movable Type 4 では、記事固有の値として記事 ID というのを持っている。したがって、この記事 ID に基づいて、Starbox クラス生成時の第一引数名を決定すればよい。書式は別に何でもいいが、各コメントへの評価も可能にしたい場合があることも考えて、単に ID だけにしておくとコメントと被る可能性があるので、指定を "MT_ENTRY_(記事 ID)" という書式にしておく。で、その記事 ID はどこにあるのかという話だが、これは MTEntryID ファンクションタグを挿入するだけで実現できるので、これを使えばいい。
 あとは、複数ブログがある場合、記事 ID だけで識別する方式では、やはり被るので、念のため複数ブログを持つというのはないかもしれないが、指定をもうちょっと拡張して、これも記事 ID と同じくブログ固有のブログ ID も追加することを考える。これまた記事と同じで、MTBlogID タグを使えばいいだけである。したがって、Starbox クラス生成時に渡すべき第一引数は、次のようなものであることがわかった。
MT_<$MTBlogID$>_ENTRY_<$MTEntryID$>
あとは、個別エントリーアーカイブ (テンプレート名では "ブログ記事") の投票を置きたい任意の場所に、この引数を用いて、先ほどの Starbox 生成コードを置けばいいだけになったので、早速置いてみればよい。ここで、当然空っぽの div の id も、これに揃えておかなければならないので、忘れないようにする。結局のところ、以下を任意の場所に挿入すればいい。
        読者によるこの記事の評価 :<br />
        <div id='MT_<$MTBlogID$>_ENTRY_<$MTEntryID$>'></div>
        <script language='javascript' type='text/javascript'>new Starbox('MT_<$MTBlogID$>_ENTRY_<$MTEntryID$>', 0);</script>
もちろん、前の項で述べたとおり、head タグに必要なライブラリ、Prototype, Scriptaculous, starbox.js, starbox.css の参照を忘れないこと。これがないとまず動かない。うまく行けば、以下のようにちゃんと記事ごとにこれが表示されるようになっている。
012.png
013.png
ちゃんと投票すればファイルも生成されるし、該当記事を読み込めば投票結果はそれぞれに反映されているので、これで終了となるが、私のブログのように背景が黒だと、こういう風に不格好になってしまう。それはなぜかというと、Starbox であらかじめ用意されている ★ の表示方法は、★ の形をした透過色のまわりを真っ白で囲んだ正方形の画像を並べて表示しているためである。なので、逆にこの白いのを黒くしてしまえば、黒い背景にも順応できる。適当な画像ソフトで、透過色を保存したまま色を反転させればすぐに終わるので、各自行う必要がある。
 さて、冒頭で Starbox は優秀だと書いた。何が優秀かというと、別に Five Star Rating でなくても、星の数を調整したり、整数ではなく 3 つ星半みたいな半端な値にも設定できたり、星の色を変える、あるいは形そのものを変えたりもできてしまう点である。最後に、それらのカスタマイズ方法を一部紹介する。
カスタマイズ
 
How to introduce 5 star rating system with MT4
(I cannot write [or speak] English, so the following contains a lot of grammatical mistakes.)
Go to open-starbox download site and download all the files available there.
001.png
002.png
003.png
004.png
005.png
After downloading, according to the official starbox website, you have to take these steps:
1. To use starbox, you have to insert links to "prototype.js" and "scriptaculous.js".
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js'></script>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/scriptaculous/1/scriptaculous.js'></script>
Fundamentally you should install them in your website, but, fortunately you can use them just by making links to prototype.js and scriptaculous.jp on Google API.
2. Make reference to starbox.css in webpages where you want to use starbox.
<link rel="stylesheet" type="text/css" href="http://li.nu/starbox/css/starbox.css" />
You have to substitude your address to starbox.css for the one used above. And add the following into everywhere you want to put a rating.
<div id='element'></div>
<script language='javascript' type='text/javascript'>new Starbox('element', average);</script>
Then, confirm whether it works correctly. This is an example.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js'></script>
  <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/scriptaculous/1/scriptaculous.js'></script>
  <script type='text/javascript' src='http://li.nu/starbox/js/starbox.js'></script> 

  <link rel="stylesheet" type="text/css" href="http://li.nu/starbox/css/starbox.css" />
</head>
<body>
  <div id='test'></div>
  <script language='javascript' type='text/javascript'>new Starbox('test', 0);</script>
</body>
</html>
009.png
You should confirm that it works, but when rated, the result is never to be saved bacause you have to prepare a php document that saves the result of the rating. Official site says you have to make it by yourself so I'll give you a sample php document. Looking at the details of the document, you will notice that it is quite simple and not so practical. Yes, I do not have enough knowledge of PHP, so I am sure it is better you make it by yourself if you can. (工事中)  次に、ライセンスに基づいて、starbox.js に少々改変を施す。まず、長々しいコードが出てくると思うが、Starbox クラスを見つけて、さらにその中から initialize イベントを見つけ出して、そのイベントを丸ごと以下のように書き換える。
  initialize: function(element, average) {
    this.element = $(element),
    this.average = average;

    this.options = Object.extend({
      buttons: 10,
      className : 'default',
      color: false,
      duration: 0.6,
      effect: { mouseover: false , mouseout: (window.Effect && Effect.Morph) },
      hoverColor: false,
      hoverClass: 'hover',
      ghostColor: false,
      ghosting: false,
      ratedClass: 'rated',
      identity: false,
      indicator: '#{average} rating from #{total} votes',
      inverse: Starboxes.inverse,
      locked: false,
      max: 5,
      onRate: Starboxes.onRate,
      rerate: Starboxes.rerate,
      rated: false,
      overlay: Starboxes.overlay,
      stars: 5,
      total : 0
    }, arguments[2] || {});

    var result;
    var param = 'mode=current&id='+this.element.id;
    new Ajax.Request('http://li.nu/starbox/js/savestar.php',
      { method: 'post',
        parameters: param,
        asynchronous:false,
        onComplete: function(xhr) {
          // optional callback
          result = xhr.responseText.split("<>");
          
        }
      }
    );

    if(!(result[0] == 'NOT_RATED')){
      this.average = parseFloat(result[0]);
      this.options.total = parseFloat(result[1]);
    }

    this.rated = this.options.rated;
    this.total = this.options.total;
    this.locked =  this.options.locked || (this.rated && !this.options.rerate);

    if (this.options.effect && (this.options.effect.mouseover || this.options.effect.mouseout))
      Starboxes.require('Scriptaculous');

    Starboxes.queueBuild(this);
    if (Starboxes.batchLoading) Starboxes.processBuildQueue();
  },
実は赤い部分以外にもカスタマイズ部分を変えてあるのだが、大きな改変は主に赤い部分になっている。savestar.php に処理を要求する記述が加わっている。ここでの 'http://li.nu/starbox/js/savestar.php' は、各自の savestar.php のアドレスに書き換えること。次に、onClick イベントも以下のように丸ごと書き換える。
  onClick: function(event) {
    var element = event.element();
    if (!element.rating) return;

    this.updateAverage(element.rating);
    if (this.options.indicator) this.updateIndicator();
    if (this.options.ghosting) this.setBarPosition(this.ghost, this.average, (window.Effect && Effect.Morph));

    if (!this.rated) this.status.addClassName('rated');
    var rerated = !!this.rated;
    this.rated = element.rating;

    if (!this.options.rerate) {
      this.disable();
      this.status.addClassName('locked');
      this.onMouseout(event);
    }

    var info = {
      average: this.average,
      identity: this.options.identity,
      max: this.options.max,
      rated: element.rating,
      rerated: rerated,
      total: this.total
    };
    this.options.onRate(element, info);

    var param = 'mode=rating&id='+this.element.id+'&rate='+info.rated;
    new Ajax.Request('http://li.nu/starbox/js/savestar.php',
      { method: 'post',
        parameters: param,
        onComplete: function(xhr) {
          // optional callback
          var result = xhr.responseText;
          if(!(result == 'COMPLETED_SUCCESSFULLY')){
            alert("An error has occured:"+result);
          }
        }
      }
    );
    this.element.fire('starbox:rated');
  },
ここにある 'http://li.nu/starbox/js/savestar.php' も、各自の savestar.php のアドレスに書き換える。これで全て完了したので、実際に適当なページで呼び出してみればいい。使い方は先ほど動作確認したときと全く変わっていない。
010.png
アクセスすると、下に自分でカスタマイズして追加したので何とか rated from 何とか votes が表示されているが、何も変わっていないように見える。とりあえず、適当に投票する。
011.png
そして、リロードすると、今までとは違い、ちゃんと投票数と投票結果が残っている。これで、投票結果が保存されるようになったので、あとはどうやって Movable Type に適用して、記事ごとの評価を実現させればいいか考える。
Movable Type 4 の各記事への配置
 Movable Type 4 では、記事固有の値として記事 ID というのを持っている。したがって、この記事 ID に基づいて、Starbox クラス生成時の第一引数名を決定すればよい。書式は別に何でもいいが、各コメントへの評価も可能にしたい場合があることも考えて、単に ID だけにしておくとコメントと被る可能性があるので、指定を "MT_ENTRY_(記事 ID)" という書式にしておく。で、その記事 ID はどこにあるのかという話だが、これは MTEntryID ファンクションタグを挿入するだけで実現できるので、これを使えばいい。
 あとは、複数ブログがある場合、記事 ID だけで識別する方式では、やはり被るので、念のため複数ブログを持つというのはないかもしれないが、指定をもうちょっと拡張して、これも記事 ID と同じくブログ固有のブログ ID も追加することを考える。これまた記事と同じで、MTBlogID タグを使えばいいだけである。したがって、Starbox クラス生成時に渡すべき第一引数は、次のようなものであることがわかった。
MT_<$MTBlogID$>_ENTRY_<$MTEntryID$>
あとは、個別エントリーアーカイブ (テンプレート名では "ブログ記事") の投票を置きたい任意の場所に、この引数を用いて、先ほどの Starbox 生成コードを置けばいいだけになったので、早速置いてみればよい。ここで、当然空っぽの div の id も、これに揃えておかなければならないので、忘れないようにする。結局のところ、以下を任意の場所に挿入すればいい。
        読者によるこの記事の評価 :<br />
        <div id='MT_<$MTBlogID$>_ENTRY_<$MTEntryID$>'></div>
        <script language='javascript' type='text/javascript'>new Starbox('MT_<$MTBlogID$>_ENTRY_<$MTEntryID$>', 0);</script>
もちろん、前の項で述べたとおり、head タグに必要なライブラリ、Prototype, Scriptaculous, starbox.js, starbox.css の参照を忘れないこと。これがないとまず動かない。うまく行けば、以下のようにちゃんと記事ごとにこれが表示されるようになっている。
012.png
013.png
ちゃんと投票すればファイルも生成されるし、該当記事を読み込めば投票結果はそれぞれに反映されているので、これで終了となるが、私のブログのように背景が黒だと、こういう風に不格好になってしまう。それはなぜかというと、Starbox であらかじめ用意されている ★ の表示方法は、★ の形をした透過色のまわりを真っ白で囲んだ正方形の画像を並べて表示しているためである。なので、逆にこの白いのを黒くしてしまえば、黒い背景にも順応できる。適当な画像ソフトで、透過色を保存したまま色を反転させればすぐに終わるので、各自行う必要がある。
 さて、冒頭で Starbox は優秀だと書いた。何が優秀かというと、別に Five Star Rating でなくても、星の数を調整したり、整数ではなく 3 つ星半みたいな半端な値にも設定できたり、星の色を変える、あるいは形そのものを変えたりもできてしまう点である。最後に、それらのカスタマイズ方法を一部紹介する。

その他の記事

コメント

名前 :
電子メール :
URL :
コメント