Prototype.js を使って、MovableTypeで最新記事を表示する

以前に、MovableTypeの個別記事ページに最新記事を表示するjavascriptを書いたのだけれど、それを Prototype.js をちゃんと使うように書き直した。script.aculo.usのアニメーションを追加したり、色々と遊んでいると、複数のJavascriptを混在して読み込むようになってき気持ちが悪いので。

ひとまず、script.aculo.usを、最新の1.6.1にする。Prototype.jsもついでに 1.5.0_rc0 にバージョンアップされるので、Template などの新機能も使えます。script.aculo.usのページからダウンロードするか、SVNから直接入手。

$ svn co http://dev.rubyonrails.org/svn/rails/spinoffs/scriptaculous

最新の記事情報を、JSON形式で保持するMTEntries というクラスをつくることにします。JSONを書き出すMTタグの構造は変わらず。HTMLを書き出すファンクションは、prototype.jsのおかげで、かなり短くなりました。

Javascript と HTMLを分離できる、Template機能がいい感じ。HTML出力部分を一カ所にまとめられると、ソースがかなり見やすくなりますね。.each とかrubyライクな繰り返し記述が使えて、長ったらしいDom構造をいちいち書かなくてよいのもGoodです。prototype.js の便利な面を改めて確認。

var MTentries = Class.create();

MTentries.prototype = {
  
  initialize: function() {
    // 最新記事をカテゴリ毎に5件 JSON形式で出力
    this.articles = {
    
    <MTCategories>
    "<$MTCategoryID$>" : {
  	    "id" : "<$MTCategoryID$>",
  	    "label" : "<$MTCategoryLabel$>",
  	    "links" : [
        <MTEntries lastn='5'>
        {"title" : "<$MTEntryTitle encode_js="1"$>"
         ,"url" : "<$MTEntryPermalink$>"
         , "excerpt" : "<$MTEntryExcerpt encode_js="1"$>"}
        <MTEntriesFooter> <MTElse>, </MTElse> </MTEntriesFooter>
        </MTEntries>
	    ]
    },
    </MTCategories>
    "id" : "end"
    
    };
    // 記事のリストHTMLを出力するTemplate
    this.textLink =   new Template(
      '<h3><a href="#{url}">#{title}</a></h3><p>#{excerpt}</p>');
  },
  
  showArticles: function(cat_id) {
  
    // id="goodpic_new_entries" な Div をHTMLから抽出
    var myDivs = $('goodpic_new_entries');
    
    // 記事の数だけ繰り返し
    this.articles[cat_id].links.each ( function(link)
    {
      myDiv = document.createElement("div");
      
      // Template でリストのHTMLを出力
      myDiv.innerHTML = this.textLink.evaluate({
        title: link.title, url: link.url, excerpt: link.excerpt
      });
      
      // script.aculo.us のアニメーションエフェクトをつける
      myDiv.onmouseover = function() {
	      new Effect.Highlight(this, {startcolor:'#FFDD99', endcolor:'#ffffff', restorecolor:'#ffffff'});
      }
      
      myDivs.appendChild(myDiv);
    }.bind(this));

  }
  
};

// インスタンス作成&HTMLの表示
var articles = new MTentries();
articles.showArticles(cat_id[0]);

このスクリプトを、recent.js などの名前でMovableType テンプレートとして保存。再構築。

次に個別記事アーカイブのテンプレートを編集。headなどで、prototype.jsとscriptaculous.jsを読み込み。

<script src="js/scriptaculous/lib/prototype.js" type="text/javascript"></script>
<script src="js/scriptaculous/src/scriptaculous.js?load=effects" type="text/javascript">

そして、リストを表示したい場所に、以下のHTMLを挿入。

<div id="goodpic_new_entries"></div>
<script src="<MTBlogURL>recents.js" type="text/javascript" language="javascript">
</script>
<script type="text/javascript" language="javascript">
<!--
var cat_id = [<MTEntryCategories><$MTCategoryID$>,</MTEntryCategories>0];
//-->
</script>

あとは好きなように、CSSで見栄えを調整。

参考にさせていただいたサイト。