とりあえず、強引ながらもサイト全体のコンテンツについて「いいね!」された数を集計することができました。次に、得られた集計結果を元に、いよいよ「いいね!」ランキングのページを生成することを考えます。
集計された結果には、「いいね!」された数とそのコンテンツの URL が含まれていますが、肝心のタイトルが含まれていません。一般的なランキングページを考えると、記事タイトルが並んでいるようなもの(Web 担当者 Forum の例)を想像しますが、このままではそれを作ることができません。得られた URL を、そのコンテンツのタイトルにマッピングする必要があることがわかります。
そこで、MovableType を CMS として利用しているのであれば、記事の URL と記事タイトルのマッピングを、テンプレートタグを用いて自動的に生成することが可能ですので、今回はそれを利用します。「いいね!」ランキングの集計結果が XML で得られているので、これに一度 URL →記事タイトルのマッピングを行ってから、ランキングページの HTML を生成することを考えます。
ところで、こういった XML を他のデータ形式(今回は HTML)に変換するような処理には XSLT を利用するのが最適です。今回、最終的なランキングページの HTML を取得するために、それ用のスタイルシートを記述することにします。
そのために、XML に XSL を適用して処理する Perl スクリプトを作成しました*1。任意の XML データに XSL を適用した結果を標準出力に書き出しますので、これをファイルに保存してやれば、ランキングページなどを生成することができます。
先ほど、URL を記事タイトルにマッピングを行う必要があると書きましたが、その処理もついでにスタイルシートの中に書き込んでしまいましょう。こういうことが簡単にできるのも XSLT の強みですねヽ(´ー`)ノ
以下のようなインデックス テンプレートを作成してビルドしてみてください。この例では、左サイドバー上部に設置している「いいね!ランキング」の HTML を生成しています。
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/"> <xsl:apply-templates select="link_stats" /> </xsl:template> <xsl:template match="link_stats"> <ul><xsl:for-each select="stat"><xsl:if test="0<like_count"> <xsl:variable name="title"><xsl:choose> <MTEntries lastn="0"> <xsl:when test="url='<$MTEntryPermalink encode_xml="1"$>'"><$MTEntryTitle encode_xml="1"$></xsl:when> </MTEntries> <xsl:otherwise>(不明なタイトル)</xsl:otherwise> </xsl:choose></xsl:variable> <li><a href="{url}"><xsl:copy-of select="$title" /></a> (<xsl:value-of select="like_count" /> Like)</li> </xsl:if></xsl:for-each></ul> </xsl:template> </xsl:stylesheet>
スタイルシートが得られたら、早速、ランキングの集計結果の XML に適用してみます。
# perl compile.pl ranking.xml link_stat.xsl > ranking.html
サイトマップを元に、Facebook に対して「いいね!」数の問い合わせを行い、その結果にスタイルを適用する処理は、次のようにまとめて書くことができます。これを cron などを用いて定期的に実行することで、「いいね!」ランキングページを自動的に生成することができるようになります。
# perl ranking.pl sitemap.xml > ranking.xml # perl compile.pl ranking.xml link_stat.xsl > ranking.html