はてなブックマーク件数を blog に貼り付けるウィジェット
2006-02-27-1: [JavaScript][Ajax][Ruby][Code]
ウィジェットというほどのものではないけど,はてなブックマーク件数を簡単に blog に貼り付けることが出来る部品を作ってみました.
はてなブックマーク件数とは以下の画像の赤枠のようなものです.
この赤枠の中で囲まれた部品を blog に貼り付けることが出来ます.
このウィジェットの使い方はとても簡単で
<link rel="stylesheet" type="text/css" href="./styles/hatebu-count.css" />
<script type="text/javascript" src="./js/prototype.js"></script>
<script type="text/javascript" src="./js/hatebu-count.js"></script>
をヘッダに書いておいて
<p id="hatebu-count"></p>
id に hatebu-count を持つ要素 (この場合は p) を一つ用意しておくだけ.あとはこれを貼り付けたページのはてなブックマーク件数が
ここに,表示されます.
以下,サンプル.このページ (表示されている URI) のはてなブックマーク件数.
(Ajax を使って非同期で読み込んでいるので,そのうち表示されるはずです)
動作確認をしたのは,Forefox 1.5.0.1,IE 6.0,Opera 8.2,Netscape 7.1 いずれも Windows 版です.
このウィジェットを作ったきっかけは,prototype.js を読んでいたら,Ajax.Request に evalJSON なんてメソッドがあって,どうもこれは
X-JSON
というヘッダに入っている,JSON データを処理してくれるものらしいです.これを見つけて何か作ろうかなと...
このウィジェットの仕組みは
まず,ページが読み込まれると Ajax で hatebu-count.cgi を呼び出しています.
hatebu-count.cgi は何をやるかというと,はてなブックマーク件数取得 API を XML-RPC で取得して JSON で返します.
あとは,それを表示するだけですね.
図に示すと以下の通り.
今回は練習を兼ねて初めて Ruby で書いてみた.XML-RPC ライブラリが標準で入っていたりしてなかなか使いやすかった.
ちなみに,Ruby 1.8.2 より前に含まれる XML-RPC には脆弱性があるらしいので注意が必要.
CGI のソースは以下のようになっています.
#!/usr/local/bin/ruby
require 'xmlrpc/client'
require 'cgi'
def print_json(name, count)
printf "X-JSON: ({'name': '%s', 'count': '%s'})\n\n", name, count
exit
end
param = CGI.new
print_json('error', 'unkown URI.') if !param['uri']
# クライアントを準備
client = XMLRPC::Client.new('b.hatena.ne.jp', '/xmlrpc')
begin
# XML-RPC を呼び出し
result = client.call('bookmark.getCount', param['uri'])
print_json(param['uri'], result[param['uri']].to_s)
rescue XMLRPC::FaultException => e
# 例外
print_json('error', e.faultString)
end
慣れていないので,変な書き方をしていたら指摘してください.
ポイントは HTTP ヘッダで X-JSON を投げている点で,これを prototype.js の Ajax.Request が自動的に処理してくれるので楽が出来ます.
JSON のデータは以下のようにハッシュになっています.
{
name: URI
count: ブックマーク件数
}
JavaScript のソースは以下のようになっています.
var HatebuCount = Class.create();
HatebuCount.prototype = {
initialize: function(uri) {
this.doAjax(uri);
},
doAjax: function(uri) {
var url = 'hatebu-count.cgi';
var param = new Date().getTime() + '&uri=' + encodeURI(uri);
new Ajax.Request(url, {
method: 'get',
parameters: param,
onComplete: this.doResponse
});
},
doResponse: function(response, json) {
if (json.name == 'error') return false;
var tag = '';
if (json.count >= 10) {
tag = 'strong';
} else if (json.count >= 5) {
tag = 'em';
}
var anchor = document.createElement('a');
anchor.setAttribute('href', 'http://b.hatena.ne.jp/entry/' + json.name);
anchor.setAttribute('target', '_blank');
var text = json.count + ' ' + (json.count > 1 ? 'users' : 'user');
anchor.appendChild(document.createTextNode(text));
var element;
// document.createElement('') だと Firefox でうまくいかない
if (tag == '') {
element = anchor;
} else {
element = document.createElement(tag);
element.appendChild(anchor);
}
$('hatebu-count').appendChild(element);
}
};
Event.observe(window, 'load', function() {
new HatebuCount(document.URL);
}, false);
ポイントは,doResponse でレスポンスといっしょに JSON データが入ってくところ.
今回の場合は,json.name と json.count に値が入ってきます.
後は,返ってきた値を,id が hatebu-count な要素に追加しています.
Ruby をはじめて使ってすごく便利だと感じたのは,CGI のデバッグのときで,
% ruby hatebu-count.cgi
とやってコンソールで実行すると
(offline mode: enter name=value pairs on standard input)
このように,name と value の組み合わせを入れなさいと出てくるところ.
ここに,例えば,
uri=http://www.google.com/
^D
などと入れると GET のパラメータに値が入って CGI が実行されます.ちなみに,以下がその結果.
X-JSON: ({'name': 'http://www.google.com/', 'count': '16'})
これは,今回,非常に便利でした.
最後にソース一式を置いておきます.ライセンスは,Creative Commons 帰属 にします.
- ソース一式 (tar.bz2)
http://pocari.org/tools/ajax/hatebu-count/hatebu-count.tar.bz2
- Creative Commons 帰属
http://creativecommons.org/licenses/by/2.1/jp/
- ref.: はてなブックマーク件数取得APIとは
http://d.hatena.ne.jp/keyword/%a4%cf%a4%c6%a4%ca%a5%d6%a5%c3%a5%af%a5%de%a ...
- ref.: Rubyist Magazine - 標準添付ライブラリ紹介 【第 1 回】 XMLRPC4R
http://jp.rubyist.net/magazine/?0007-BundledLibraries
- ref.: prototype.js v1.4.0 の使い方
http://www.imgsrc.co.jp/~kuriyama/prototype/prototype.js.html
- ref.: まちゅダイアリー - JSON + prototype.js
http://www.machu.jp/diary/20060110.html
- ref.: 2nd life - prototype.js 1.4.0 pre6 でのJSONサポート
http://d.hatena.ne.jp/secondlife/20050927/1127814722
関連記事:
[2006-02-28-6] IE でフォーム入力された内容や JavaScript で appendChild された内容もそのままソースで表示させる Bookmarklet