Subscribed unsubscribe Subscribe Subscribe

Google AJAX Feed API で複数のブログからフィードを取得して、しかも日付順に並び替えるコード

web Javascript

何となく「できるか?」と聞かれたので作って見ました。
Feedはサーバサイドで処理してもいいけど、それだと取得先のレスポンスがないときにページが表示できなかったり、エラーが出たりするんですよねー。
ということで、Google AJAX Feed APIでやるんですけど。


Google AJAX Feed APIには複数ブログを扱うためのggoogle.feeds.FeedControlというクラスがあって、addFeed(url, label)って書いておけば複数のフィードを扱えるらしい。
でもドキュメントを読んでいる限り、取得したフィードの内容を個々に呼び出したり、取得した全てのフィードで日付ソートしたりとかできないような気が…


そう思って、それを解決するスクリプトを書いたのです(もしも、「そんなのAPIに実装されてて簡単にできちゃうよー」って言われたら、このエントリーは非常に恥ずかしいなぁ)。
サンプルとスクリプトは、ざざっとこんな感じです。無駄なコードも少々あるかもしれぬ。


Google AJAX Feed API で複数ブログからフィードを取得して日付順に並び替えるサンプルページ

<script type="text/javascript" src="http://www.google.com/jsapi?key=取得したAPIキー"></script>
<script type="text/javascript">
<!--//
google.load("feeds", "1");
var entryArray = new Array();
var entryNum = 0;

function initialize() {
	feedAdd("http://d.hatena.ne.jp/kudakurage/rss2", 0);
	feedAdd("http://d.hatena.ne.jp/uzulla/rss2", 0);
	feedAdd("http://d.hatena.ne.jp/kent013/rss2", 1);
}

//取得するフィードの追加(rssUrl:フィードのURL , boolNum:追加するフィードURLが最後の場合「1」を入れる)
function feedAdd(rssUrl, boolNum) {
	var feed = new google.feeds.Feed(rssUrl);//フィードの取得
	feed.setNumEntries(5);//ブログ1つあたりの取得するフィード数
	feed.load(function(result) {
		if (!result.error) {
			for (var i = 0; i < result.feed.entries.length; i++) {
				entryArray[entryNum] = result.feed.entries[i];
				var date = new Date(result.feed.entries[i].publishedDate);
				entryArray[entryNum].sortDate = ( date.getFullYear()*10000 ) + ( (date.getMonth() + 1)*100 ) + date.getDate();//ソート用(日付)を連想配列に代入
				entryArray[entryNum].blogName = result.feed.title;//ブログ名を連想配列に代入
				entryNum+=1;
			}
		}
		if(boolNum==1){
			feedOutput("feed", 12);//フィードの出力
		}
	});
}

//フィードの出力(feedId:出力するオブジェクトのID , listNum:出力するリスト数。「0」の場合全て)
function feedOutput(feedId, listNum){
	var useFeed = "";
	var container = document.getElementById(feedId);//表示部分を選択
	entryArray = asort(entryArray, "sortDate");//日付でソート
	if(listNum==0){
		listNum = entryNum;
	}
	for (var i = 0; i < listNum; i++) {
		var entry = entryArray[i];
		var date = new Date(entry.publishedDate);//日付の表示変更
		useFeed += '<li>' + date.getFullYear() + '年' + (date.getMonth() + 1 ) + '月' + date.getDate() + '日 <a href="' + entry.link + '" target="_blank">' + entry.title + '</a>(' + entry.blogName + ')</li>';//HTMLで書き出し
	}
	container.innerHTML = '<ul>' + useFeed + '</ul>';
}
function asort(myArray, key){
	//return myArray.sort ( function (b1, b2) { return b1[key] > b2[key] ? 1 : -1; } );//昇順
	return myArray.sort ( function (b1, b2) { return b1[key] > b2[key] ? -1 : 1; } );//降順
}

google.setOnLoadCallback(initialize);
//-->
</script>


feedAdd(フィードのURL, 0); で複数ブログのフィードを取得します。
2つ目の引数は追加するフィードURLが最後の場合「1」を入れるというものなんですが、本当ならこんな風にしたくなかった。

function initialize() {
	feedAdd("http://d.hatena.ne.jp/kudakurage/rss2");
	feedAdd("http://d.hatena.ne.jp/uzulla/rss2");
	feedAdd("http://d.hatena.ne.jp/kent013/rss2");
	feedOutput("feed", 12);//フィードの出力
}

こういう風にしようと思ってたのに、これだとなぜかどうしても上手くいかなかった。
取得したフィードの配列のentryArray.lengthが0を返してしまうのです。
それで「feed.load(function(result) {});」の中に入れたらちゃんと動く。なので仕方なくこんな意味不明な引数が…orz
誰かいい方法があったら教えてください。


フィードの出力は「feedOutput("feed", 12)」ってなってて1つ目の引数は出力するオブジェクトのID、2つ目の引数は出力するフィードの数です。
feedAdd関数の中にあるfeed.setNumEntries(5)はそれとは違って1つのブログで取得するフィードの数です。
要はそれぞれのブログからいくつ(feed.setNumEntries(5))取得して、それをいくつ(feedOutput("feed", 12))表示するかってことです。


asort関数は連想配列のソート関数です。
昇順にしたい場合はコメントアウトを入れ替えればOKです。


Google AJAX Feed API で複数ブログからフィードを取得して日付順に並び替えるサンプルページ


と、ここまで書いて「だから、APIに実装されてて簡単にできちゃうよー」ってなってたらどうしよう。そのときは教えてください。


※追記…entryArray.lengthが0なのはローカル変数とかグローバル変数とかのはなしかなぁ?未だに分からん。