ブログネタ
JavaScript に参加中!

前回の記事でGoogle Ajax Feed APIのJSON(JSONP)について少し触れたので、もう少し詳しく書いておきます。

このAPIは前回のような使い方以外にも、フィードをJavaScriptで扱えるライブラリがいろいろ揃っていますね。
とはいうものの、個人的にはやっぱり任意のフィードをJSONで受け取れるFeed to JSONが魅力です。今回はjQueryでJSONを取得するための簡単なプラグインを作ってみました。

Google AJAX Feed APIのJSON用jQueryプラグイン


jQueryのサイトでも似たようなプラグインがあったと思いますが、今回作ったものはcharsetの指定をすることができます。UTF-8以外のエンコードを使っているサイトでは多少便利になるかもしれないです。

プラグインのソース

<script type="text/javascript">
jQuery.extend({

  // GETパラメータのデフォルト
  jGFeedJSettings: {
    v: '1.0',         // version
    output: 'json',   // 出力形式
    num: '5'          // 出力数
  },

  // プラグイン本体
  // data: GETパラメータ (ハッシュ、フィードURLは必須)
  // callback: コールバック関数 (必須)
  // charset: JSON側の文字コード(省略可)
  jGFeedJ: function(data, callback, charset) {
    data = jQuery.extend(jQuery.jGFeedJSettings, data);
    var s = {
      type: "GET",
      url: 'http://ajax.googleapis.com/ajax/services/feed/load?callback=?',
      data: data,
      success: callback,
      dataType: 'json'
    }
    if(charset)  s.scriptCharset = 'utf-8';
    return jQuery.ajax(s);
  }
});

使い方は、

$.jGFeedJ( { q:'フィードのURL', num:'10' }, function(json) {
  〜ここにJSON取得後の処理を記述〜
});

という感じでお願いします。

第一引数はAPIに渡すGETパラメータをハッシュで書きます。デフォルトの方に大体設定されているので殆どのパラメータは省略可能ですが、「q:'フィードのURL'」だけは必須です。

第二引数はコールバック関数です。JSON取得後に実行されます。コールバック関数の引数はJSONです。JSONPが初めての方は、前回の記事でも参考にしてJSONの処理を書いてみてください。

GETパラメータ

RESTfulですが取得するのがJSONと決まっているので、案外できることは少ないです。

この辺はオフィシャルに詳しい内容があります。

Google Ajax Feed API - 標準URL引数

ちなみにJSONの取得のみなら「key?」は不要、「context?」は設定すると、コールバック関数の引数の並びがjQuery.ajax()にマッチしなくなるので、指定しないでください。

JSONの形式

同じフィードでもATOMとRSSで要素名は変わりますが、Google AJAX Feed APIのJSONでは同じ名前になるように変更されます。フィード形式で分岐する必要がないので便利ですね。

こちらもオフィシャルのコンテンツに詳しい内容があります。

JSON形式の結果 - Google AJAX Feed API

動作サンプル

フィードのURLを入力して「get」ボタンをクリックすると、リスト表示されるサンプルを作りました。
一つのテキストボックスに一つのフィード入力してください。
テキストボックスを追加したいときは「add」ボタンをクリックします。

ここに表示されます。

サンプルのソース

上記サンプルのソースコードです。

jQuery.extend({
  // GETパラメータ初期値
  jGFeedJSettings: {
    v: '1.0',         // version
    output: 'json',   // 出力形式
    num: '5'          // 出力数
  },

  // Google Ajax Feed APIのJSONPを取得するプラグイン
  // data: GETパラメータ
  // callback: コールバック関数
  // charset: API側のエンコード
  jGFeedJ: function(data, callback, charset) {
    data = jQuery.extend(jQuery.jGFeedJSettings, data);
    var s = {
      type: "GET",
      url: 'http://ajax.googleapis.com/ajax/services/feed/load?callback=?',
      data: data,
      success: callback,
      dataType: 'json'
    }
    if(charset)  s.scriptCharset = charset;
    return jQuery.ajax(s);
  },

  // 複数のフィードのリストを表示するプラグイン
  // elms: リストを挿入するターゲット要素のSelector(jQuery形式)
  // feedURL: フィードのURL. 複数指定するときは配列にする
  jGFeedJList: function(elms, feedURL, data, charset) {
    var ul0;
    if(typeof feedURL === 'string') {
      var feedURL = [feedURL];
    }
    if(data) {
      if(typeof data === 'string') {
        charset = data;
        data = {};
      }
    } else  data = {};

    jQuery(elms).empty().append(ul0 = jQuery('<ul/>').addClass('GFeed-list'));

    // 指定されたフィード数だけ繰り返す
    return $.each(feedURL, function() {
      if(!this.match(/^http:\/\//)) return true;
      data.q = this;
      jQuery.jGFeedJ(data, callback, charset);
    });

    // jGFeedJに渡すコールバック関数
    function callback(json) {
      if(json.responseStatus != '200') return;
      var f = json.responseData.feed;
      var ul1 = jQuery('<ul/>').css('display', 'none');
      var li = jQuery('<li/>').append(
        jQuery('<a/>').text('\u25B6').css('cursor', 'pointer').addClass('toggle-button').toggle(
          function() {
            jQuery(this).text('\u25BC');
            ul1.show('fast');
          },
          function() {
            jQuery(this).text('\u25B6');
            ul1.hide('fast');
          }
        ),
        jQuery('<a/>').attr({href:f.link, title:f.description}).text(f.title),
        ul1
      ).appendTo(ul0);
      for(var i in f.entries) { (function(e) {
        var sn = jQuery('<div/>').text(e.contentSnippet).css('display', 'none');
        jQuery('<li/>').append(
          jQuery('<a/>').text('\u25B6').css('cursor', 'pointer').addClass('toggle-button').toggle(
            function() {
              jQuery(this).text('\u25BC');
              sn.show('fast');
            },
            function() {
              jQuery(this).text('\u25B6');
              sn.hide('fast');
            }
          ),
          jQuery('<a/>').attr('href', e.link).text(e.title),
          sn
        ).appendTo(ul1);
      })(f.entries[i]); }
    }

  }
});


$(function() {
  var $fl = $('#feed_list');

  // addボタン
  $('#add_feed').click( function() {
    var n = 'feed_' + $fl.find('input[type="text"]').length;
    $('<input type="text"/>').attr({name:n,id:n}).css({ display:'block', width:'300px' }).appendTo($fl);
    $('#rem_feed').removeAttr('disabled');
  });

  // removeボタン
  $('#rem_feed').click( function() {
    var $il = $fl.find('input[type="text"]');
    $il.filter(':last').remove();
    if($il.length < 3)
      $(this).attr({ disabled:'disabled' });
  });

  // getボタン
  $('#get_feed').click( function() {
    var feedURL = [];
    $fl.find('input[type="text"]').each( function(i) {
      feedURL[i] = $(this).val();
    });
    $.jGFeedJList('#target', feedURL, 'utf-8');
  });
});

更新

ソースの効率が悪そうなので少し変えました。(2009/08/12)