Tam-calendar.js に Google Calendar の祝日データを取り込む

先日紹介した Tam-calendar.js の話のなかで、クラスを追加指定する例として祝日の日付に holiday クラスをセットするというのを取り上げましたが、肝心な祝日の日付をどうやって取得すればよいのか、詳しい説明を省いていました。今回はその話をしたいと思います。

Google Calendar Data API

Google は Google Calendar のデータを操作できる Google Calendar Data API を公開しています。この API を使うことで Google Calendar 上に保存されたイベントデータを XML フィードとして取得することができます。

各国の休日はイベントの一種として扱われているので、同様に API 経由で取得することが可能です。Google Calendar Data API から祝日のデータを得るメリットとしては、

  • Google がメンテナンスしているので自前でデータを管理しなくて済む
  • Google がメンテナンスしているデータだから間違いがない(たぶん)

といった点がまず挙げられますが、さらに重要なポイントとしてクライアントサイドからデータを取得してそのまま処理できるという点も挙げておきたいと思います。

以下、Google Calendar Data API から祝日のデータを取得して Tam-calendar.js に取り込む方法について詳しく解説していきます。

フィード URL

日本の祝日データのフィード URL は以下の形式になっています:

http://www.google.com/calendar/feeds/
japanese@holiday.calendar.google.com/public/projection

projection の部分にはいくつか用意されている値の中からひとつを選んで指定します。この指定によりフィードを構成する要素の組み合わせが異なってきますので、用途に最適なものを選びます。今回は title (祝日の名前) と gd:when (祝日の日付) の2つの要素が必要なので、それらを含む full を指定します。

ちなみに japanese のかわりに usa__en を指定するとアメリカ合衆国の休日が、australian__en を指定するとオーストラリアの休日が得られます。

取得する期間は GET パラメタ start-min と start-max で指定します。取得できる最大の件数は GET パラメタ max-results で指定できます(デフォルトで25)。2007年中の日本の祝日を20件取得するなら URL の GET パラメタは次のようになります。

start-min=2007-01-01&start-max=2008-01-01&max-results=20

今回の用途では必要がないので触れませんが、そのほかにも指定できるパラメタがいくつか用意されています。詳しくは Google のドキュメントを参照してください。

JSON フィード

祝日のデータが手に入ることはわかりました。さて、次にこれをクライアントサイドで取り込んで Tam-calendar.js とマッシュアップするにはどうすればいいでしょうか。

いわゆる Ajax 的な手法、つまり XMLHttpRequest を利用して動的にフィードを取得すればよさそうですが実際にはうまくいきません。というのもほとんどのブラウザの XMLHttpRequest 実装には潜在的なセキュリティリスクを回避する目的で、異なるドメインの URL に対する非同期のリクエストを許可しないというポリシーがあるらしいです。ということはあなたのドメインに属するページの JavaScript からは google.com ドメインに属するデータを取得できないということになります。

そこで Google Data API がサポートしている JSON フォーマットのフィードを利用することにします。次の URL のように少し GET パラメタを付け足すことで JavaScript の関数呼び出しとしてのフィードを取得できるようになります。

http://www.google.com/calendar/feeds/
japanese@holiday.calendar.google.com/public/full
?start-min=2007-01-01&start-max=2008-01-01&max-results=20
&alt=json-in-script&callback=handleJson

Google Data API がサポートしている JSON フィード一般については Official Google Data APIs Blog に優れた解説があるのでそちらを手がかりにするとよいでしょう。ここでは Tam-calendar.js とのマッシュアップの実際例に限定して話を進めます。

Tam-calendar.js + Google Calendar Data API マッシュアップのサンプル

Google Calendar Data API の JSON フィードを取得して得た祝日のデータを Tam-calendar.js に取り込むサンプルを以下に提示します。日付をもとに祝日をピックアップし、それに holiday というクラスを追加し、さらに title 属性に祝日の名称をセットします。

以下に掲載しているコードにはレイアウトの都合で本来必要のない改行をはさんでいる行があるので注意してください。実際に使ってみたい場合は Google Code で公開しているコードをダウンロードした方が確実です。

<html>
<head>
  <title>Calendar Sample</title>
  <script src="prototype.js" type="text/javascript"></script>
  <script src="tam_calendar.js" type="text/javascript"></script>
  <script type="text/javascript">
    //<![CDATA[
    
    function load() {
      var cal = new Calendar($('calendar'));
      
      cal.afterRenderHook = function() {
        holidaysJson.feed.entry.each(function(entry) {
          var title = entry.title.$t;
          var start = entry['gd$when'][0].startTime;
          var year = start.slice(0, 4);
          var month = start.slice(5, 7);
          var date = start.slice(8, 10);
          var class_names = ".y" + year + ".m" + month + ".d" + date;
          var holidays = document.getElementsByClassNames(class_names, $('calendar'));
          holidays.each(function(holiday) {
            Element.addClassName(holiday, 'holiday');
            holiday.title = title;
          });
        });
      }
      
      cal.render();
    }
    
    var holidaysJson;
    
    function handleJson(json) {
      holidaysJson = json;
    }

    //]]>
  </script>
  <script src="http://www.google.com/calendar/feeds/
        japanese@holiday.calendar.google.com/public/full
        ?start-min=2007-01-01&start-max=2008-01-01&max-results=20
        &alt=json-in-script&callback=handleJson" type="text/javascript"></script>
</head>
<body onload="load()">
  <div id="calendar"></div>
</body>
</html>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s