<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[iDeasilo]]></provider_name><provider_url><![CDATA[https://ideasilo.wordpress.com]]></provider_url><author_name><![CDATA[Takayuki Miyoshi]]></author_name><author_url><![CDATA[https://ideasilo.wordpress.com/author/miyoshita/]]></author_url><title><![CDATA[Tam-calendar.js に Google Calendar&nbsp;の祝日データを取り込む]]></title><type><![CDATA[link]]></type><html><![CDATA[<p>先日紹介した <a href="https://ideasilo.wordpress.com/2007/01/03/tam-calendar-js/">Tam-calendar.js</a> の話のなかで、<a href="https://ideasilo.wordpress.com/2007/01/03/tam-calendar-js/#adding-class">クラスを追加指定する</a>例として祝日の日付に holiday クラスをセットするというのを取り上げましたが、肝心な祝日の日付をどうやって取得すればよいのか、詳しい説明を省いていました。今回はその話をしたいと思います。</p>
<h4>Google Calendar Data API</h4>
<p>Google は Google Calendar のデータを操作できる <a href="http://code.google.com/apis/calendar">Google Calendar Data API</a> を公開しています。この API を使うことで Google Calendar 上に保存されたイベントデータを XML フィードとして取得することができます。</p>
<p>各国の休日はイベントの一種として扱われているので、同様に API 経由で取得することが可能です。Google Calendar Data API から祝日のデータを得るメリットとしては、</p>
<ul>
<li>Google がメンテナンスしているので自前でデータを管理しなくて済む</li>
<li>Google がメンテナンスしているデータだから間違いがない(たぶん)</li>
</ul>
<p>といった点がまず挙げられますが、さらに重要なポイントとしてクライアントサイドからデータを取得してそのまま処理できるという点も挙げておきたいと思います。</p>
<p>以下、Google Calendar Data API から祝日のデータを取得して Tam-calendar.js に取り込む方法について詳しく解説していきます。<br />
<!--more--></p>
<h4>フィード URL</h4>
<p>日本の祝日データのフィード URL は以下の形式になっています:</p>
<p><a href="http://www.google.com/calendar/feeds/" rel="nofollow">http://www.google.com/calendar/feeds/</a><br />
japanese@holiday.calendar.google.com/public/<i>projection</i></p>
<p><i>projection</i> の部分には<a href="http://code.google.com/apis/calendar/reference.html#Projection">いくつか用意されている値の中から</a>ひとつを選んで指定します。この指定によりフィードを構成する要素の組み合わせが異なってきますので、用途に最適なものを選びます。今回は title (祝日の名前) と gd:when (祝日の日付) の2つの要素が必要なので、それらを含む full を指定します。</p>
<p>ちなみに japanese のかわりに usa__en を指定するとアメリカ合衆国の休日が、australian__en を指定するとオーストラリアの休日が得られます。</p>
<p>取得する期間は GET パラメタ start-min と start-max で指定します。取得できる最大の件数は GET パラメタ max-results で指定できます(デフォルトで25)。<a href="http://www.google.com/calendar/feeds/japanese@holiday.calendar.google.com/public/full?start-min=2007-01-01&amp;start-max=2008-01-01&amp;max-results=20">2007年中の日本の祝日を20件取得する</a>なら URL の GET パラメタは次のようになります。</p>
<p>start-min=2007-01-01&amp;start-max=2008-01-01&amp;max-results=20</p>
<p>今回の用途では必要がないので触れませんが、そのほかにも<a href="http://code.google.com/apis/calendar/reference.html#Parameters">指定できるパラメタ</a>がいくつか用意されています。詳しくは <a href="http://code.google.com/apis/calendar/reference.html">Google のドキュメント</a>を参照してください。</p>
<h4>JSON フィード</h4>
<p>祝日のデータが手に入ることはわかりました。さて、次にこれをクライアントサイドで取り込んで Tam-calendar.js とマッシュアップするにはどうすればいいでしょうか。</p>
<p>いわゆる <a href="http://ja.wikipedia.org/wiki/Ajax">Ajax</a> 的な手法、つまり XMLHttpRequest を利用して動的にフィードを取得すればよさそうですが実際にはうまくいきません。というのもほとんどのブラウザの XMLHttpRequest 実装には潜在的なセキュリティリスクを回避する目的で、異なるドメインの URL に対する非同期のリクエストを許可しないというポリシーがあるらしいです。ということはあなたのドメインに属するページの JavaScript からは google.com ドメインに属するデータを取得できないということになります。</p>
<p>そこで Google Data API がサポートしている <a href="http://code.google.com/apis/gdata/json.html">JSON フォーマットのフィード</a>を利用することにします。次の URL のように少し GET パラメタを付け足すことで JavaScript の関数呼び出しとしてのフィードを取得できるようになります。</p>
<p><a href="http://www.google.com/calendar/feeds/japanese@holiday.calendar.google.com/public/full?start-min=2007-01-01&amp;start-max=2008-01-01&amp;max-results=20&amp;alt=json-in-script&amp;callback=handleJson">http://www.google.com/calendar/feeds/<br />
japanese@holiday.calendar.google.com/public/full<br />
?start-min=2007-01-01&amp;start-max=2008-01-01&amp;max-results=20<br />
<strong>&amp;alt=json-in-script&amp;callback=handleJson</strong></a></p>
<p>Google Data API がサポートしている JSON フィード一般については Official Google Data APIs Blog に<a href="http://googledataapis.blogspot.com/2006/11/calling-all-web-hackers-json-support.html">優れた解説</a>があるのでそちらを手がかりにするとよいでしょう。ここでは Tam-calendar.js とのマッシュアップの実際例に限定して話を進めます。</p>
<h4>Tam-calendar.js + Google Calendar Data API マッシュアップのサンプル</h4>
<p>Google Calendar Data API の JSON フィードを取得して得た祝日のデータを Tam-calendar.js に取り込むサンプルを以下に提示します。日付をもとに祝日をピックアップし、それに holiday というクラスを追加し、さらに title 属性に祝日の名称をセットします。</p>
<p>以下に掲載しているコードにはレイアウトの都合で本来必要のない改行をはさんでいる行があるので注意してください。実際に使ってみたい場合は <a href="http://tam-calendar.googlecode.com/files/mashup-sample-with-google-calendar-data-api.html">Google Code で公開しているコードをダウンロード</a>した方が確実です。</p>
<pre><code>&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Calendar Sample&lt;/title&gt;
  &lt;script src="prototype.js" type="text/javascript"&gt;&lt;/script&gt;
  &lt;script src="tam_calendar.js" type="text/javascript"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
    //&lt;![CDATA[
    
    function load() {
      var cal = new Calendar($('calendar'));
      
      cal.afterRenderHook = function() {
        <strong>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;
          });
        });</strong>
      }
      
      cal.render();
    }
    
    <strong>var holidaysJson;</strong>
    
    <strong>function handleJson(json) {
      holidaysJson = json;
    }</strong>

    //]]&gt;
  &lt;/script&gt;
  <strong>&lt;script src="http://www.google.com/calendar/feeds/
        japanese@holiday.calendar.google.com/public/full
        ?start-min=2007-01-01&amp;start-max=2008-01-01&amp;max-results=20
        &amp;alt=json-in-script&amp;callback=handleJson" type="text/javascript"&gt;&lt;/script&gt;</strong>
&lt;/head&gt;
&lt;body onload="load()"&gt;
  &lt;div id="calendar"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
]]></html></oembed>