2009-12-26

Google Wave Gadgets でできることを OpenSocial や Shindig の視点で調べてみました

おはようございます。Nobuhiro Nakajima です。

OpenSocial jQuery は Google Wave Gadgets でも使えるようになりますか... という質問がありました。現状の OpenSocial jQuery のまま gadgets.* API は使えます。また wave.* API はそもそも考慮していません。が答えです。

実例として公開している YouTube ガジェット がありますが、次のとおり Google Wave Gadgets としてそのまま動きます。このように Google Wave で OpenSocial jQuery はすぐに試せます。



Wave Gadgets も iGoogle や Google Friend Connect (GFC) と同じ Apache Shindig 上で構成していると考えられます。ですので、gadgets.* API の振る舞いも同じであり、OpenSocial jQuery がそのまま使えるということになりそうです。

本当にそうなの... という疑問が残るので、Wave Gadgets を Shindig 視点でいろいろ調べてみました。調べたのは Wave Preview です。Sandbox ではありません。

ガジェットのレンダリング

iframe URL を抜粋します。見てのとおり Shindig の Gadgets Rendering Server です。HTTPS (Secure) プロトコルが特徴的です。ホストは googleusercontent.com で iGoogle や GFC の gmodules.com とは異なるので別系統なのでしょう。container パラメータも wave なので、同系統であったとしても、コンテナのプロファイルは別なのでしょう。
https://lq3n3peeciqdlq351d7pd2pqtuvr30al-a-wave-opensocial.googleusercontent.com/gadgets/ifr
?v=b893d00cffa7bf86acedda54be7a116
&container=wave
&view=canvas&
&lang=en&
&url=http://example.com/gadgets.xml
&country=ALL
&libs=core%3Adynamic-height%3Alocked-domain ...
&mid=5
&nocache=1
&parent=https://wave.google.com ...
#rpctoken=...
&st=...
libs パラメータを観察したところ、ガジェットXML の feature を表すようですので、Google Wave 側もガジェット XML の内容を認知しているのでしょう。

view パラメータは、常に canvas のようです。ガジェットXML で profile や home を指定すると、次のエラーとなりますので、canvas ビューのみサポートするのでしょう。既定のビューが canvas ということになるのかな。
Unable to locate an appropriate view in this gadget. Requested: 'canvas' Available: [home]
Unable to locate an appropriate view in this gadget. Requested: 'canvas' Available: [profile]
nocache パラメータは、常に 1 (キャッシュなし) のようです。iframe のソースコードを見ても concat されていませんので、開発中のキャッシュ制御は気にしなくてもよさそうです。

rpctoken パラメータが付与されてますので、クロスホストなデータ通信は gadgets.rpc なのでしょう。iframe のソースコードを見ると gadgets.rpc と gadgets.rpctx が含まれますので、すべてのブラウザで URL flagment (rpc_relay.html) は使われないでしょう。

st パラメータが付与されてますので、Phone home (gadgets.io.makeRequest)の仕組みも同じでしょう。

setprefs feature

Wave Gadgets のドキュメントでサポートすると記載があります。ガジェットXML の UserPref は認知しており、API でも取得できました。ただ API で設定できますが、(確認した限りは)永続化できませんでした。また、UserPref を編集するための UI も提供されていないようです。本当か。

dynamic-height feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に API は存在し、期待どおり動作しました。

settitle feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に API は存在し、呼び出してもエラーにはなりませんが、指定したタイトルがどこで表示されるのか確認できませんでした。

tabs feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に API は存在し、期待どおり動作しました。

minimessage feature

Wave Gagets のドキュメントでサポートすると記載があります。実際に API は存在し、期待どおり動作しました。

locked-domain feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に locked-domain なしでガジェットを wave に貼り付け、その後 locked-domain ありとして再表示すると、"Invalid domain" というエラーとなるため、機能しているのでしょう。

view feature

Wave Gadgets のドキュメントでサポートすると記載はありません。が、実際に API は存在しました。ただ、サポートするビューは profile と canvas という結果で、前述の結果とズレがあります。また、ビューの移動は API が無反応でした。

opensocial-0.8 feature

Wave Gadgets のドキュメントで OpenSocial API は未サポートと記載があります。が、実際に API は存在しました。実際に Person の取得を試みたところ、次のエラーとなりました。
Malformed security token ...&c=wavecom.google.gadgets.auth.AuthTokenException: Failure for container wave
Wave は Contact ベースの関係のようですので、OpenSocial に対応するなら iGoogle モデルになるのかなという印象です。もうできてたりして。

といったところを調べてみました。結果、現状の OpenSocial jQuery のまま gadgets.* API なら使えることが把握できました。役に立ちそうであれば使ってみてください。

2009-12-21

メッセージの表示に加え、明示的もしくは自動的にメッセージを閉じる強化をした OpenSocial jQuery Mini Message プラグインを公開しました

おはようございます。Nobuhiro Nakajima です。

OpenSocial jQuery は jQuery.fn.minimessage メソッドで Mini Message を限定的にサポートしてきましたが、このたび OpenSocial jQuery Mini Message としてプラグイン化して、使える機能を強化しました。従来の機能に加えて、明示的もしくは自動的にメッセージを閉じることができるようになりました。

今後、メッセージの表示は OpenSocial jQuery Mini Message プラグインを使ってください。従来の Mini Message は Deprecated 非推奨となり、OpenSocial jQuery 1.3.2.5 以後のバージョンで使えなくなります。

OpenSocial jQuery Mini Message プラグインの使い方は、次のとおりです。質問や要望がありましたら OpenSocial jQuery Discussion までお願いします。

OpenSocial jQuery 本体に続けて、OpenSocial jQuery Mini Message をロードしてください。
<script src="opensocial-jquery.js" type="text/javascript"></script>
<script src="opensocial-jquery.minimessage.js" type="text/javascript"></script>
OpenSocial jQuery Mini Message は minimessage を必要とします。
<Require feature="minimessage" />
閉じるボタン付きのメッセージを表示する

jQuery.fn.minimessage を使って、閉じるボタン付きのメッセージを表示できます。
$('<span/>').text('Say Hello!').minimessage();


また jQuery.fn.minimessage にコールバック関数を指定して、閉じるイベントをハンドリングできます。コールバック関数の戻り値を false とすると、イベントは無効となり、メッセージは閉じません。
$('<span/>').text('Dismissible Message with Callback')
  .minimessage(function() {
    return confirm('Do you close a message?'); // 閉じるかどうか?
  });
メッセージを閉じる

jQuery.fn.remove を使って、メッセージを閉じることができます。
var message = $('<a/>').text('Remove Message')
  .click(function() {
    message.remove(); return false;
  }).minimessage();
});
自動的にメッセージを閉じる

jQuery.fn.minimessage を使って、自動的に閉じるメッセージを表示できます。秒数か fast, normal, slow のいずれかを指定します。

* fast を指定すると、1秒後にメッセージを閉じます。
* normal を指定すると、3秒後にメッセージを閉じます。
* slow を指定すると、5秒後にメッセージを閉じます。
$('<span/>').text('Timer Message')
  .minimessage(3); // 3秒後に閉じる
$('<span/>').text('Timer Message with Predefined Speeds')
  .minimessage('slow');
また jQuery.fn.minimessage にコールバック関数を指定して、閉じるイベントをハンドリングできます。
$('<span/>').text('Timer Message with Callback')
  .minimessage('fast', function() { // 3秒後に閉じる
    alert('The message was closed.');
  });
実例

* OpenSocial jQuery Mini Message Test Suite

2009-12-14

mixi.util.requestExternalNavigateTo を使った外部サイトの誘導を jQuery.fn.live で自動化する方法

こんばんは。しゃっくりが止まらなくなって、丸2日になろうとしてる Nobuhiro Nakajima です。

mixi アプリは jQuery.view (= mixi.util.requestExternalNavigateTo) を使って、ユーザを外部サイトに誘導します。というネタを使って、ちょっとした Tips を紹介します。

次のソースコードは、外部サイトのリンクのクリックイベントを捕捉して jQuery.view を使って外部サイトに誘導するものです。(1) はあらかじめ用意した静的なリンク、(2) は RSS フィードを取得して動的生成したリンクで、それぞれ jQuery.view を使って外部サイトに誘導しています。
// (1) 静的リンク
  $('a[target=_blank]').click(function() {
    $.view(this.href); return false;
  });
  // (2) 動的リンク
  $.getFeed('http://rss.rssad.jp/rss/gihyo/feed/atom', function(feed) {
    $.each(feed.Entry, function(i, entry) {
      var a = $('<a target="_blank">')
        .attr('href', entry.Link)
        .text(entry.Title)
        .click(function() {
          $.view(this.href); return false;
        });
      $('<li/>').append(a).appendTo('ul');
    });
  });
<ul></ul>
Powered by <a href="http://code.google.com/p/opensocial-jquery/"
  target="_blank">OpenSocial jQuery</a>
静的リンクにせよ、動的リンクにせよ、外部サイトに誘導するというコードはまったく同じです。また、動的リンクを頻繁に生成するときは、その都度、クリックイベントと jQuery.view のコードを書くことになります。その結果、コードは冗長になりますし、テストケースも増加します。つまり、不健全です。

これ jQuery.fn.live を使うと、次のように自動化できるんです。ここでは target="_blank" のリンクは、外部サイトのリンクと決まりごとにしています。そして jQuery.fn.live を使って、target="_blank" のリンクにクリックイベントを登録し、外部サイトに誘導するようにしています。

たったこれだけで、静的リンクと動的リンクに関わらず、HTML 中に外部サイトのリンクが生成された時点で(あらかじめ存在するのも含む)、自動的にクリックイベントが登録され、外部サイトに誘導するリンクに早変わりします。live というメソッド名からもイメージできるでしょう?
$('a[target=_blank]').live('click', function() {
    $.view(this.href); return false;
  });
  $.getFeed('http://rss.rssad.jp/rss/gihyo/feed/atom', function(feed) {
    $.each(feed.Entry, function(i, entry) {
      var a = $('<a target="_blank">')
        .attr('href', entry.Link)
        .text(entry.Title); // click イベントを登録してない!?
      $('<li/>').append(a).appendTo('ul');
    });
  });
実際に上のソースコードを動かすと分かりますが、RSS フィードのリンクにクリックイベントを登録していないにも関わらず、jQuery.view で外部サイトに誘導されます。RSS フィードを再取得して再表示しても同様です。

jQuery.fn.live は、いろいろ制約があるので、使えるシーンは限られるのですが、頻繁に HTML を動的生成する中で、コールバック関数外の状態に依存しない定型的なイベントブロックを多用するとき、とても役立つと考えます。その1例が、外部サイトの誘導ということです。

2009-12-09

OpenSocial jQuery に mixi Platform 固有の拡張機能を追加する jQuery プラグインを公開しました。

おはようございます。ちょっと体調のすぐれない Nobuhiro Nakajima です。

OpenSocial jQuery mixi Platform 1.0.0 をリリースしました。
http://code.google.com/p/opensocial-jquery/ -- Downlaod
http://code.google.com/p/opensocial-jquery/wiki/PluginMixi -- Document

OpenSocial jQuery mixi Platform は mixi 固有の拡張機能を OpenSocial jQuery に追加するための jQuery プラグインです。OpenSocial jQuery 本体に続けて、OpenSocial jQuery mixi Platform をロードして使ってください。
<script type="text/javascript" src="opensocial-jquery.js"></script>
<script type="text/javascript" src="opensocial-jquery.mixi.js"></script>
外部サイトに誘導する

jQuery.view を使って、外部サイトに誘導できます。このとき、外部サイトの URL を指定します。また、パラメータを指定すると QUERY_STRING に変換して URL に付与します。
// http://www.google.com/
$.view('http://www.google.com/');

// http://www.google.com/search?q=corgi
$.view('http://www.google.com/search', { q: 'corgi' }); 


ただし mixi の URL を指定したときは、外部サイトとみなさず、即ページ遷移します。
// http://mixi.co.jp/
$.view('http://mixi.co.jp/');

// http://mixi.jp/show_profile.pl?id=0123456789
$.view('http://mixi.jp/show_profile.pl', { id: '0123456789' });
また、従来どおり、ビューの切り替えや現在のビュー名の取得もできます。
$.view('profile');
$.view('home');
$.view('canvas', { q: 'corgi' });
console.info($.view()); // profile, home, canvas
参加コミュニティを取得する

jQuery.getData を使って、ユーザの参加コミュニティを取得できます。このとき url に /communities からはじまるパスと @viewer, @owner, ユーザID のいずれかを指定します。jQuery.ajax や jQuery.get も同様です。
$.getData('/communities/@viewer/@self').next(function(communities) {
  $.each(communities, function(i, community) {
    console.info(community.id); // コミュニティID
    console.info(community.userId); // ユーザID
    console.info(community.url); // コミュニティURL
    console.info(community.name); // コミュニティ名
    console.info(community.thumbnailUrl); // コミュニティ画像
  });
  console.info(communities.totalResults); // 参加コミュニティ数
}).error(function(e) {
  alert(e+'');
});
学校を選択する

jQuery.getData を使って、VIEWER の母校や在学中の学校を選択できます。このとき url に /schools からはじまるパスと @selected を指定します。jQuery.ajax や jQuery.get も同様です。
$.getData('/schools/@selected').next(function(schools) {
  var school = schools[0];
  console.info(school.token); // 学校トークン
  console.info(school.divisionId); // 学校区分ID
  console.info(school.division); // 学校区分名
});


学校リストを取得する

jQuery.getData を使って、VIEWER の母校や在学中の学校リストを取得できます。このとき url に /schools からはじまるパスと @viewer を指定します。jQuery.ajax や jQuery.get も同様です。
$.getData('/schools/@viewer/@self').next(function(schools) {
  $.each(schools, function(i, school) {
    console.info(school.token); // 学校トークン
    console.info(school.divisionId); // 学校区分ID
    console.info(school.division); // 学校区分名
  }
  console.info(schools.totalResults); // 学校数 = schools.length
}).error(function(e) {
  alert(e+'');
});
マイミクを招待する

jQuery.invite を使って、マイミクを招待できます。このとき @friends を指定します。招待したマイミクのユーザIDリストを取得できます。
$.invite('@friends', function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
});


また @friends を省略しても同じことができます。
$.invite(function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
});
さらに Deferred チェーンを使っても同じことができます。
$.invite('@friends').next(function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
}).error(function(e) {
  alert(e+'');
});
同級生を招待する

jQuery.invite を使って、同級生を招待できます。このとき @classmates を指定します。招待した同級生のユーザIDリストを取得できます。
$.invite('@classmates', function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
});


さらに Deferred チェーンを使っても同じことができます。
$.invite('@classmates').next(function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
}).error(function(e) {
  alert(e+'');
});
コンテナを判別する

jQuery.container.mixi を使って、コンテナが mixi Platform かどうか判別できます。
他コンテナも含めて 1つの JS ファイルにまとめるときに役立ちます。
if ($.container.mixi) { ... } // mixi Platform
.mixi クラスを使って、コンテナが mixi Platform かどうか判別できます。
他コンテナも含めて 1つの CSS ファイルにまとめるときに役立ちます。
<style type="text/css">
.mixi p { color: red; } /* mixi Platform */
</style>
OpenSocial jQuery に対する質問や要望は Google Group で受け付けています。開発中の最新情報も入手できます。ぜひご参加ください。

OpenSocial jQuery Discussion
http://groups.google.com/group/opensocial-jquery

-- 2009-12-10 スクリーンキャプチャの追加

2009-12-05

Golazo MA4 - ここで何する? を閉鎖しました。ソースコードは引き続き提供します。

おはようございます。Nobuhiro Nakajima です。

Mashup Awards 5 応募者の参考になればと思い、Mashup Awards 4 受賞作品である Golazo MA4 - ここで何する? を公開し続けてきましたが、

Golazo MA4 - ここで何する?
http://golazo.offtheball.jp/
Golazo MA4 は、ウェブページや入力した文章の内容から位置情報を自動抽出し、その内容と位置情報をメモとして、簡単にクリッピングできるサービスです。

本日(12/5)、Mashup Awards 5 の受付終了と受賞者発表に伴い、サイトを閉鎖しました。アカウントの情報とデータもすべて破棄し、バックアップのデータも破棄しました。

Golazo MA4 のソースコードは、引き続き公開していきますので、ご活用ください。

golazo - Project Hosting on Google Code
http://code.google.com/p/golazo/

ありがとうございました。

2009-11-28

OpenSocial jQuery autoHeight 1.0.0 is available

OpenSocial jQuery autoHeight is plugin to adjust height of Gadgets automatically all the time.
http://code.google.com/p/opensocial-jquery/wiki/PluginAutoHeight

Edit the src attribute in the script tag to point to your copy of opensocial-jquery.autoHeight.js. Inside the ready event, add the autoHeight method to window object:
<script type="text/javascript" src="opensocial-jquery.js"></script>
<script type="text/javascript" src="opensocial-jquery.autoHeight.js"></script>
<script type="text/javascript">
$(document).ready(function() {
  $(window).autoHeight();
});
</script>
Featured Video



Downloads

You can download it from the featured downloads list.
http://code.google.com/p/opensocial-jquery/downloads/list

gadgets.window.adjustHeight で、確実に !? ガジェットの高さを自動調整する方法

おはようございます。なかじまんです。

Gadgets API の gadgets.window.adjustHeight を使うと、ガジェットの高さを自動調整できますが、実際のところは、画像のロードタイミングや、ブラウザごとに仕組みの異なる gadgets.rpc が影響して、期待どおりの高さに自動調整されないことが多々あります。

で、今までいろいろ試してきましたが、現在は、次のとおり、周期的に高さを自動調整して、期待する高さを保つという方法がもっとも確実であるという結論です。
setInterval(function() { gadgets.window.adjustHeight(); }, 1000);
また OpenSocial jQuery だと、次のようになります。
setInterval(function() { $(window).adjustHeight(); }, 1000);
1秒間隔で、ガジェットの高さの自動調整を試みています。gadgets.window.adjustHeight のソースコードを調べたところ、ガジェットの高さに変化のないときは、コンテナと RPC 通信せずに何もしないようになっていたので、1秒間隔くらいで gadgets.window.adjustHeight を呼び出しても、それほどコストはかかりません。

1秒間隔なので、高さが自動調整されるのがひと呼吸遅いかなという感じがあったり、頻繁に高さが変わるようなガジェットだと、ペコペコ高さが変わって見苦しいこともありますが、高さが自動調整されないという最悪の結果は回避できます。

-- 2009-11-28 追記

上記のガジェットの高さを自動調整し続ける... をプラグインとして公開しました。公式サイトからダウンロードして使ってください。

OpenSocial jQuery autoHeight 1.0.0 (opensocial-jquery.autoHeight.js)
http://code.google.com/p/opensocial-jquery/

使い方は、次のとおり opensocial-jquery.autoHeight.js をロードして、はじめに1度だけ window オブジェクトに対して autoHeight を呼び出すだけです。
<script type="text/javascript" src="opensocial-jquery.min.js"></script>
<script type="text/javascript" src="opensocial-jquery.autoHeight.js"></script>
<script type="text/javascript">
$(document).ready(function() {
  $(window).autoHeight();
});
</script>
ガジェットXMLの実例を用意しました。
http://opensocial-jquery.googlecode.com/svn/trunk/tests/opensocial-jquery.autoHeight.test.xml

ガジェットXMLを gooホームにも登録しましたので、体験してみてください。
http://sandbox.home.goo.ne.jp/gadget/N43bmJWwmt18/detail

ガジェットXMLが動作する様子を動画にしました。文章のフォントサイズを変更すると、その変化に応じて、ガジェットの高さが自動調整されることが見て分かります。

2009-11-25

OpenSocial jQuery から OpenSocial Host の外部データベースを操作する基本手順を紹介します

おはようございます。なかじまんです。

OpenSocial jQuery から OpenSocial Host の Core API を使って、OpenSocial Host の外部データベースを操作する手順とソースコードを紹介します。

OpenSocial Host の外部データベースを使うメリットは、次のとおりです。

* OpenSocial AppData とは異なり、すべてのユーザが同じデータ領域を共有できる
* OpenSocial AppData とは異なり、個々のデータに対して、パーミッションを指定できる
* OpenSocial AppData とは異なり、個々のデータに対して、データ容量の制約がない
* OpenSocial AppData とは異なり、個々のデータに対して、ワード検索できる
* 外部データベースは HeartRails によって、安全、確実にホストされ、負荷対策も期待できる(に違いない)

OpenSocial Host の外部データベースにできなこともあります。

* OpenSocial AppData とは異なり、友達リストのソーシャルグラフが使えない

なので、OpenSocial API と OpenSocial Host の特徴をよく理解して、組み合わせて使うことになるのだろうと考えます。

ユーザの登録

はじめに OpenSocial Host のユーザ登録をしてください。
ユーザ登録は無料です。Open ID を使えば、パスワードを預ける必要はありません。



アプリケーションの登録

次に OpenSocial Host にログインして、新しいアプリケーションを登録してください。
アプリケーションの変更や削除はいつでもできますので、アプリケーション名は仮のものでも構いません。



アプリケーションを登録すると、アプリケーションキーが発行されますので、動作対象とするコンテナのアプリケーションキーを手元に控えてください。



アプリケーションの関連付け

ガジェット XML を用意して、動作対象とするコンテナにガジェット XML を登録してください。ガジェット XML は OpenSocial Host でホストしてもよいですし、自社サーバや Google AppEngine、Amazon S3 など、どこでホストしてもかまいません。

そして、次のように、ガジェット XML から /app/register を呼び出します。
このとき、前述のアプリケーションキーをパラメータとして、リクエストを署名します。
呼び出しが成功すると、OpenSocial Host とガジェット XML が関連付き、これ以降、ガジェット XML から OpenSocial Host の外部データベースが使えるようになります。
なお、関連付いた後は /app/register の呼び出しは不要です。アプリケーションの開発をはじめるとき、1度だけ呼び出してください。
// Register Application
  var url = 'http://opensocialhost.com/app/register';
  var data = { application_key: '( Your Application Key )' };
  
  $.ajax({
    type: 'post', url: url, oauth: 'signed', data: data, dataType: 'json'
  }).next(function(r) {
    if (r.hadError)
      throw r.errorCode; // call error
  }).error(function(e) {
    console.error(e+'');
  });
}}}
データの追加

/data/insert を呼び出して、データを追加できます。このとき、Key-Value 形式のデータとパーミッションをパラメータとして、リクエストを署名します。

* 既存のデータは上書きできます。ただし、パーミッションは上書きできません。パーミッションを変更するときは、データを削除した後、データを再挿入します。
* 読み込みと書き込みのパーミッションは別々です。書き込みは読み込みを兼ねません。
* パーミッションは public, private, specified を指定できます。specified のときは、カンマ区切りで、複数のユーザ ID を指定できます。
// Insert Data
  var url = 'http://opensocialhost.com/data/insert';
  var data = {
    comment: { text: 'Say Hello!', lastModified: new Date().getTime() },
    feeling: 'well',
    footprint: true
  };

  // Object を OpenSocial Host のパラメータに変換する
  // Key はそのまま、Value は JSON (String) に変換する
  var _data = {}, i = 1;
  $.each(data, function(k, v) {
    _data['key'+i] = k;
    _data['value'+i] = gadgets.json.stringify(v);
    i++; 
  });

  // 読み込みパーミッションを指定する
  //_data.read_permission = 'public'; // 誰でも(初期値)
  //_data.read_permission = 'private'; // 自分のみ
  //_data.read_permission = 'specified'; // 特定のユーザのみ
  //_data.read_permission_specified = '( User ID ),( User ID ), ...';  

  // 書き込みパーミッションを指定する  
  //_data.write_permission = 'public'; // 誰でも(初期値)
  //_data.write_permission = 'private'; // 自分のみ
  //_data.write_permission = 'specified'; // 特定のユーザのみ
  //_data.write_permission_specified = '( User ID ),( User ID ), ...';  
  
  $.ajax({
    type: 'post', url: url, oauth: 'signed', data: _data, dataType: 'json'
  }).next(function(r) {
    if (r.hadError)
      throw r.errorCode;
  }).error(function(e) {
    console.error(e+'');
  });
データの更新

/data/update を呼び出して、データを更新できます。このとき、Key-Value 形式のデータをパラメータとして、リクエストを署名します。
// Update Data  
  var url = 'http://opensocialhost.com/data/update';
  var data = { feeling: 'bad', footprint: false };

  // Object を OpenSocial Host のパラメータに変換する
  // Key はそのまま、Value は JSON (String) に変換する
  var _data = {}, i = 1;
  $.each(data, function(k, v) {
    _data['key'+i] = k;
    _data['value'+i] = gadgets.json.stringify(v);
    i++; 
  });

  $.ajax({
    type: 'post', url: url, oauth: 'signed', data: _data, dataType: 'json'
  }).next(function(r) {
    if (r.hadError)
      throw r.errorCode;
  }).error(function(e) {
    console.error(e+'');
  });
データの削除

/data/delete を呼び出して、データを削除できます。このとき、Key をパラメータとして、リクエストを署名します。
// Delete Data  
  var url = 'http://opensocialhost.com/data/delete';
  var data = [ 'comment', 'feeling' ];

  // Array を OpenSocial Host のパラメータに変換する
  var _data = {};
  $.each(data, function(i, v) {
    _data['key'+(i+1)] = v; 
  });

  $.ajax({
    type: 'post', url: url, oauth: 'signed', data: _data, dataType: 'json'
  }).next(function(r) {
    if (r.hadError)
      throw r.errorCode;
  }).error(function(e) {
    console.error(e+'');
  });
データの取得

/data/select を呼び出して、データを取得できます。このとき、Key をパラメータとして、リクエストを署名します。
// Select Data  
  var url = 'http://opensocialhost.com/data/select';
  var data = [ 'comment', 'feeling', 'footprint' ];

  // Array を OpenSocial Host のパラメータに変換する
  var _data = {};
  $.each(data, function(i, v) {
    _data['key'+(i+1)] = v; 
  });

  $.ajax({
    type: 'post', url: url, oauth: 'signed', data: _data, dataType: 'json'
  }).next(function(r) {
    if (r.hadError)
      throw r.errorCode;
    
    // OpenSocial Host のレスポンスを Object に変換する
    // Key はそのまま、Value は JSON (String) から Object に戻す
    var data = {};
    $.each(r.data, function(i, v) {
      data[v.key] = gadgets.json.parse(v.value);
    });   
    return data;
  
  }).next(function(data) {
    console.info(data.comment.text);
    console.info(data.comment.lastModified);
    console.info(data.feeling);
    console.info(data.footprint);
  }).error(function(e) {
    console.error(e+'');
  });
データの検索

/data/search を呼び出して、データを検索できます。このとき、フィルタ条件、ソート条件、ページング条件をパラメータとして、リクエストを署名します。

* 指定した文字列を Key に含むデータを検索できます。部分一致のみです。
* 指定した文字列を Value に含むデータを検索できます。部分一致のみです。
* Key と Value の両方を指定したときは、上記の AND 条件になります。
* page はページ番号です。インデックスではありません。
* sort は asc, desc を指定できます。ソート順はデータの追加日時です。更新日時ではありません。
// Search Data
  var url = 'http://opensocialhost.com/data/search';
  var data = {
    key: 'feeling', value: 'well', page: 1, per_page: 10, sort: 'asc'
  };

  $.ajax({
    type: 'post', url: url, oauth: 'signed', data: data, dataType: 'json'
  }).next(function(r) {
    if (r.hadError)
      throw r.errorCode;

    // OpenSocial Host のレスポンスを Object に変換する
    // Key はそのまま、Value は JSON (String) から Object に戻す    
    $.each(r.data, function(i, v) {
      v.value = gadgets.json.parse(v.value);
    });
    return $.extend(r.data, {
      page: r.page, per_page: r.per_page, total_counts: r.total_counts
    });
  
  }).next(function(data) {
    $.each(data, function(i, v) {
      console.info(v.key, v.value);
    });
    console.info(data.page, data.per_page, data.total_counts);
  }).error(function(e) {
    console.error(e+'');
  });
データのグループ化や階層化

OpenSocial Host の外部データベースは、すべてのユーザで共有して、パーミッションでアクセス件をコントロールします。ですので、どのユーザのデータなのか、どの種類のデータなのかは、次のように Key の文字列を使って表現する必要があります。
// VIEWER ID を使って、どのユーザのデータなのかを区別する
  var key = viewer.id + '$comment';
  var data = { text: 'Say Hello!', lastModified: new Date().getTime() };
データの確認 -- 2009/11/26 追加

OpenSocial Host にログインして、外部データベースの内容を確認できます。

* 指定した文字列を Key または Value に含むデータを検索できます。
* データの Key や Value、パーミッション、作成日時など、詳しく表示できます。
* データを削除できます。



関連リンク

* OpenSocial Host Core API
* OpenSocial Host ユーザフォーラム

2009-11-19

Gadgeta GeoNotes - Building Social Mashup Container with OpenStack

おはようございます。Nobuhiro Nakajima です。

Mashup Awards 5 というマッシュアップをテーマとしたコンテストに、次の作品を応募しました。



Gadgeta GeoNotes - Building Social Mashup Container with OpenStack
http://golazo.aptanacloud.com/

Gadgeta GeoNotes は、位置情報付きのテキストを投稿し、タイムライン風に共有することで、場所や地域を軸とした人の繋がりを作り出すことを目的とした OpenSocial 対応の SNS サイトです。海外への紹介も考慮し、英語サイトにしています。



投稿したテキストから位置情報を自動抽出し、それぞれを関連付けて時系列に保存します。テキストは日本語と英語に対応し、英語なら日本に限らず、世界の国や地域の位置情報も抽出できます。

投稿したテキストに、様々なガジェットを貼り付けできます。ガジェットは位置情報を受け取り、場所や地域に応じた情報を提示できます。ガジェットは OpenSocial に対応し、プロフィールや友達リスト、アクティビティを活用して、相互作用やバイラル効果を促進できます。

Gadgeta GeoNotes は OpenStack を活用した Social Mashup Container です。オープンな仕様、オープンソース、オープンなサービスから構築しています。SNS サイトの主要な特徴を備え、ガジェットの拡張により、他サービスやコンテンツとの融合の可能性を開きます。

デモビデオ

Nobuhiro Nakajima が仮想イベントの開催告知と参加を呼びかける例です。

* イベントの開催内容のテキストを投稿し、新橋付近の位置情報を検出しています。
* 参加者との連絡のために Comments ガジェットを追加しています。
* 参加表明のために Attends ガジェットを追加しています。
* 懇親会の会場を探すために、近所のバーガジェットを追加し、新橋付近のお店をリストアップしています。



まんてん が仮想イベントに参加を表明する例です。

* Friends' Activity からイベントの開催告知を知ります。
* Comments ガジェットを使って、開催者と連絡をとっています。
* Attends ガジェットを使って、参加を表明しています。また、友達の参加状況を確認しています。
* 観光スポットを紹介するために Tokyo's Art and Design Events ガジェットを追加し、新橋付近のアートなイベントをリストアップしています。



デモガジェット

となりのチャンネー
この辺りで見かけたチャンネーを紹介します。気に入った髪型のチャンネーをクリックして投票してね。投票できるチャンネーは全国各地で合計10人までですよ。となりのチャンネーは weboo さんが開発した みんなのチャンネー のアイディアを勝手に借りたものです。ありがとうございます。


Tokyo's Art and Design Events
Tokyo Art Beat is Tokyo's bilingual art & design events guide. Offering event listings, reviews and a shop, the site is updated daily and lists more than 500 current & upcoming art events, at any moment.


近所のバー
BAR-NAVI は、サントリーが提供する日本最大級のバー検索サイトです。バーを楽しむというスタイルを提案しています。エリアやバーのタイプ、特徴、雰囲気で検索できます。自分だけの隠れ家を探したり、珍しいカクテルと出会うことができます。


OpenSocial というと、大きな受け皿としてのコンテナが存在し、その上のアプリケーションという構図で考えがちですが、Gadgeta GeoNotes によって、オリジナルのコンテンツを所有する小中規模のサイトやサービスが、自らソーシャルなマッシュアップコンテナになる(なれる)という可能性を示せたと考えています。

追記です。-- 2009/11/10

SocialWeb Japan 主催 SocialWeb Conference vol.4 〜OpenSocial Night #1〜 のライトニングトークの中で Gadgeta GeoNotes を紹介しました。そのときのスライドです。



追記です。-- 2009/11/19

Gadgeta GeoNotes のソースコードを公開しました。
http://golazo.googlecode.com/svn/branches/geonotes/

2009-10-12

opensocial-jquery のディスカッショングループを立ち上げました。

こんにちは。なかじまんです。

Google グループを使って opensocial-jquery のディスカッショングループを立ち上げました。

opensocial-jquery Discussion
http://groups.google.com/group/opensocial-jquery

opensocial-jquery に関係する話題であれば、なんでも OK です。opensocial-jquery を使っている方はもちろんのこと、opensocial-jquery に関心があるという方も歓迎します。

疑問や質問、要望などを受け止める場となることを期待していますので、ぜひ活用してください。

opensocial-jquery based on jQuery 1.3.2 is available

Hello,

My name is Nobuhiro Nakajima, Japanese programmer.

I'm afraid my expressions may be rude or hard to read, because I'm not so good at English. But please, please be patient! I will try hard to learn English!

opensocial-jquery based on jQuery 1.3.2 is available:
http://code.google.com/p/opensocial-jquery/

opensocial-jquery is jQuery based concise JavaScript Library for rapid OpenSocial Applications development.

opensocial-jquery is designed to change the way that you write OpenSocial Applications When you use it, you can develop OpenSocial Applications by the method of developing the website by jQuery.

Therefore OpenSocial JavaScript API is good, Lightweight JavaScript API is better, and opensocial-jquery is best.

opensocial-jquery 1.3.2.5

* The opensocial-jquery 1.3.2.5 is based on jQuery 1.3.2 (courtesy of @lackac @jonca.rafal)
* The function of this release is the same as opensocial-jquery 1.0.5

opensocial-jquery 1.2.6.5

* The opensocial-jquery 1.2.6.5 is based on jQuery 1.2.6.
* The function of this release is the same as opensocial-jquery 1.0.5.
* This release is supported but is not currently the recommended release for jQuery 1.2.6.

Changelog

* issue #18
* issue #20

Thank you.

お待たせしました。jQuery 1.3.2 ベースの opensocial-jquery をリリースしました。

こんにちは。なかじまんです。

お待たせしました。jQuery 1.3.2 版の opensocial-jquery をリリースしました。

OpenSocial JavaScript API is good, Lightweight JavaScript API is better, and opensocial-jquery is best.
http://code.google.com/p/opensocial-jquery/

opensocial-jquery 1.3.2.5

jQuery 1.3.2 ベースの opensocial-jquery です。機能は jQuery 1.2.6 ベースである opensocial-jquery 1.0.5 とまったく同じです。

opensocial-jquery 1.2.6.5

jQuery 1.2.6 ベースの opensocial-jquery です。機能は jQuery 1.2.6 ベースである opensocial-jquery 1.0.5 とまったく同じです。

このとおり、バージョン番号の体系を見直して振り直しています。上位 3桁はベースとなる jQuery のバージョンを、末尾 1桁は opensocial-jquery のバージョンを表すようにしました。

今後もしばらくは jQuery 1.3.2 ベースと jQuery 1.2.6 ベースの両方とも提供していく予定ですが、状況によっては jQuery 1.2.6 ベースをサボることも考えています。ですので、何かタイミングがありましたら jQuery 1.3.2 ベースへの移行をおすすめします。

opensocial-jquery 1.3.2.5 は @lackac と @jonca.rafal からソースコードの提供を受けてリリースすることができました。ありがとうございました。

2009-09-24

opensocial-jquery templates 0.1.0 is available. It's HTML DOM based JavaScript template library for OpenSocial Application.

Hello,

My name is Nobuhiro Nakajima, Japanese programmer.

I'm afraid my expressions may be rude or hard to read, because I'm not so good at English. But please, please be patient! I will try hard to learn English!

opensocial-jquery templates 0.1.0 is available.
http://code.google.com/p/opensocial-jquery/

opensocial-jquery templates is HTML DOM based JavaScript template library for OpenSocial Application. It is based on implementation of Apache Shindig and has compatibility with subset of OpenSocial Templates.

opensocial-jquery templates supports the following markup in OSML:

* ${Expr} variables and expressions into a element text and a attribute
* Set of special variables: Top, Cur, Context.index, Context.Count and Msg
* Set of special attributes: if, repeat, and var

This example is fetching and rendering a group of people using Ajax and Template.



The HTML template is as follows:
<div id="wrapper" style="display:none;">
<div repeat="${people}" class="person">
<img alt="${Cur.displayName}" src="${Cur.thumbnailUrl}" />
<a title="${Cur.displayName}" href="${Cur.profileUrl}">${Cur.displayName}</a>
</div>
<div if="${people.length > 0}" class="pager">
Showing friends from ${people.startIndex + 1}
to ${people.startIndex + people.length }
of ${people.totalResults}
</div>
<div if="${people.length == 0}" class="pager">
There's no friend yet.
</div>
</div>
The JavaScript is as follows:
$.getData('/people/@owner/@friends', function(data) {
$('#wrapper').render({ people: data }).show();
});
View of the finished source code

opensocial-jquery templates is usable with the container which does
not support OpenSocial v0.9. And different from OpenSocial Templates of the XML base, you can edit opensocial-jquery templates by an HTML authoring tool visually. It will make a programmer and a designer happy.

Thank you.

2009-09-22

OpenSocial Templates サブセットの opensocial-jquery templates 0.1.0 をリリースしました

こんにちは。なかじまんです。

opensocial-jquery の付加機能として opensocial-jquery templates をリリースしました。opensocial-jquery templates は OpenSocial Templates (v0.9) のマークアップ言語である OSML のサブセットとその互換性を提供します。

テンプレートエンジンの中核は Apache Shindig のソースコードを使っています。が、OpenSocial Templates は XML ベースのテンプレートですので、これを HTML ベースになるように書き換えて(かなり苦労してます) jQuery との親和性を高めています。

新しいマークアップ言語を覚える必要はありますが、OpenSocial Templates と互換性があるため、OpenSocial v0.9 時代になっても、その知識や実績が無駄になりにくいと考えていますので、ちょっとした先行投資の意味合いも兼ねて、使ってみて貰えるとうれしいです。

opensocial-jquery templates は、別ファイルにしてありますので、opensocial-jquery に続けて script をロードしてください。
<script src="opensocial-jquery.min.js"></script>
<script src="opensocial-jquery.templates.min.js"></script>
jQuery.getData を使って友達リストを取得し、jQuery.fn.render とテンプレートを使って、その内容を表示する例を紹介します。iGoogle US で実行した結果です。



次の HTML がテンプレートです。友達リストを repeat 属性で繰り返し、サムネイルとニックネームを表示します。また、友達リストの取得位置、1ページあたりの取得件数、総件数を表示します。友達リストが 0件のときは、メッセージを表示します。
<div id="wrapper" style="display:none;">
<div repeat="${people}" class="person">
<img alt="${Cur.displayName}" src="${Cur.thumbnailUrl}" width="30" height="30">
<a title="${Cur.displayName}" href="${Cur.profileUrl || '#'}"
target="_top">${Cur.displayName}</a>
</div>
<div if="${people.length > 0}" class="pager">
Showing friends from ${people.startIndex + 1}
to ${people.startIndex + people.length }
of ${people.totalResults}
</div>
<div if="${people.length == 0}" class="pager">There's no friend yet.</div>
</div>
次は JavaScript です。jQuery.getData を使って OWNER の友達リストを取得します。そして jQuery.fn.render を使って、その友達リストをテンプレートに適用します。
  var url = '/people/@owner/@friends';
var data = { fields: 'profileUrl' };
$.getData(url, data, function(data) {
$('#wrapper').render({ people: data }).show();
});
詳しくは opensocial-jquery のドキュメント にまとめましたので、参照してください。OpenSocial Templates のサポート範囲や未実装の機能を確認できます。

今のところ opensocial-jquery templates では OpenSocial Templates の全仕様を実装しようとは考えていません。JavaScript のヒアドキュメントの代替として、小さな HTML の組み立てをサポートできるような存在を目的としています。とはいってもまだ発展段階です。何かありましたらコメントください。要望や状況に応じて対応していきます。

opensocial-jquery templates は Apache Shindig の実装を使っているため Apache License 2.0 ライセンスを採用しています。opensocial-jquery 本体とは異なりますので注意してください。今後 opensocial-jquery templates が使えると判断できて opensocial-jquery 本体に組み込むことがあれば、opensocial-jquery 本体も Apache License 2.0 にしたほうがいいのかなと考えています。

2009-09-05

opensocial-jquery 1.0.5 をリリースしました。OAuth リクエストと認証、Album と MediaItem の取得、People と AppData の同時取得に対応しました。

おはようございます。なかじまんです。

opensocial-jquery 1.0.5 をリリースしました。今回のリリースは、OAuth リクエストと認証、アルバムと写真の取得、プロフィールとアプリデータの同時取得という 3つの対応が柱です。

OAuth リクエストと認証

jQuery.ajax を使って、OAuth リクエストを認証して、外部ホストからデータを取得したり送信したりできるようにしました。

gooホームのガジェットから FriendFeed にメッセージを投稿する サンプルのソースコードと解説 を用意していますので、ソースコードの雰囲気を体感してみてください。また、このガジェットが動作する様子をキャプチャして動画にしましたので、再生してみてください。



jQuery.ajax を使って、リクエストを OAuth 認証して、外部ホストにデータを送信できます。
  $.ajax({
type: 'post',
url: 'http://friendfeed-api.com/v2/entry',
data: { body: 'Say Hello!' },
dataType: 'json',
oauth: 'friendfeed',
success: function(data, status) {
console.info(data, status);
},
error: function(xhr, status, e) {
if (status == 'oauth')
$('<a href="#signin"/>')
.text('Sign in with FriendFeed')
.click(function() {
$.oauth('friendfeed', function() {});
return false;
})
.minimessage();
console.error(xhr, status, e);
}
});
このとき、jQuery.ajax の oauth オプションに、ガジェットXML の OAuth/Service@name を指定します。
  <OAuth>
<Service name="friendfeed">
<Request url="https://friendfeed.com/account/oauth/request_token"
param_location="uri-query"/>
<Authorization url="https://friendfeed.com/account/oauth/authorize"/>
<Access url="https://friendfeed.com/account/oauth/access_token"
param_location="uri-query"/>
</Service>
</OAuth>
jQuery.ajax は OAuth リクエストの認証を必要とするとき、エラーイベントをコールバックします。このとき status は oauth を表します。続けて jQuery.oauth を使って OAuth リクエストを認証できます。このとき、指定した OAuth/Service@name の認証ページをポップアップウィンドウで開きます。OAuth 認証してポップアップウィンドウを閉じると、コールバックしますので、その中から処理を再開できます。

詳しくは API リファレンス を見てください。なお OAuth リクエストと認証は gooホームでのみ動作確認しています。今後、他のコンテナでも動作確認をしつつ対応を進めていきます。

アルバムリストの取得

jQuery.ajax を使って VIEWER の アルバムリストを取得できます。
  $.ajax({
url: '/albums/@viewer/@self',
data: {},
dataType: 'data',
success: function(albums) {
$.each(albums, function(i, album) {
console.info(album.id);
console.info(album.title);
console.info(album.description);
console.info(album.thumbnailUrl);
console.info(album.ownerId);
console.info(album.mediaItemCount);
});
},
error: function(xhr, status, e) {
console.error(xhr, status, e);
}
});
詳しくは API リファレンス を見てください。なお、アルバムリストの取得は orkut 仕様に準じていて orkut のみで動作確認をしています。mixi での動作確認はしていませんので、フィードバックを期待してます。

アルバムの写真リストの取得

jQuery.ajax を使って VIEWER の アルバムの写真リストを取得できます。URL でアルバムID を指定します。
  $.ajax({
url: '/mediaitems/@viewer/@self/1251149609611',
data: {},
dataType: 'data',
success: function(mediaitems) {
$.each(mediaitems, function(i, mediaitem) {
console.info(mediaitem.id);
console.info(mediaitem.url);
console.info(mediaitem.title);
console.info(mediaitem.description);
console.info(mediaitem.thumbnailUrl);
console.info(mediaitem.albumId);
});
},
error: function(xhr, status, e) {
console.error(xhr, status, e);
}
});
詳しくは API リファレンス を見てください。なお、写真リストの取得は orkut 仕様に準じていて orkut のみで動作確認をしています。mixi での動作確認はしていませんので、フィードバックを期待してます。

プロフィールとアプリデータの同時取得

プロフィールや友達リストを取得するとき、appData パラメータを指定して、アプリケーションのデータを同時に取得できます。アプリケーションのデータ項目はカンマ区切りで指定します。

今までは、プロフィールや友達リストの取得と、アプリケーションのデータの取得が別々の 2段構えでしたが、これが 1回の jQuery.ajax で取得できるようになりますので、さらにソースコードがシンプルになるのではと期待しています。
  $.ajax({
url: '/people/@viewer/@self',
data: { appData: 'comment,feeling' },
dataType: 'data',
success: function(people) {
var person = people[0];
console.info(person.appData.comment);
console.info(person.appData.feeling);
},
error: function(xhr, status, e) {
console.error(xhr, status, e);
}
});
詳しくは API リファレンス を見てください。

質問や不具合の報告などのフィードバックは大歓迎です。また、修正パッチや拡張コードの提供も歓迎します。

海外の方から opensocial-jquery 1.0.4 や 1.0.5 を jQuery 1.3.2 に書き直したものの提供も受けています。近いうちに公開しますので、もう少しお待ちください。

追記です。jQuery.param のエンコード方法を書き換えました。今までは、空白を + にエンコードしていましたが、これを %20 でエンコードするようにしました。おそらく影響はないと思いますが、お伝えしておきます。

追記です。@datoka さん。フィードバックありがとうございました。
@datoka @nakajiman opensocial jquery v1.0.5 album, mediaitemともmixiで動いております!パラメータ指定は(元々)無視されますが

2009-08-20

opensocial-jquery と Google Gadget Editor を使って iGoogle production でガジェットを開発しよう

おはようございます。なかじまんです。

2009年8月12日 米国の iGoogle は OpenSocial に正式対応しました。残念ながら日本はまだですが、近いうちに対応することが予想できます。なので、今後 iGoogle に向けた OpenSocial ガジェット (アプリ) の開発も広がってくるでしょう。

もちろん opensocial-jquery も iGoogle を熱烈サポートしていきます。なんたって最終的には全世界がターゲットになるのですからね。そこで iGoogle を使った opensocial-jquery のチュートリアルを用意しました。Google アカウントさえあれば WEB ブラウザ 1つだけで体験できる構成にしています。

それではチュートリアルをはじめます。

はじめに iGoogle (米国) http://www.google.com/ig?hl=en にログインしてください。



続けて iGoogle に Developer Gadget を追加してください。



続けて iGoogle に Google Gadget Editor を追加してください。そして Hello, world! ガジェットのソースコードが表示されるのを確認してください。



Google Gadget Editor で File メニューから Save を選択してください。続けて playground.xml と入力して OK ボタンをクリックし、Hello, world! ガジェットを保存してください。



playground.xml の URL を確認します。playground.xml のリンクを開いてください。



このときの playground.xml の URL を手元に控えてください。次のような URL になるはずです。数値の部分は各自によって異なります。

http://hosting.gmodules.com/ig/gadgets/file/(数値)/playground.xml

Developer Gadget で、手元に控えた playground.xml の URL を入力して Add ボタンをクリックし、iGoogle にガジェットを登録してください。



iGoogle に playground.xml として保存したガジェットが表示されます。



iGoogle が playground.xml をキャッシュしないように cached チェックボックスを OFF にします。



Google Gadget Editor で playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example" />
<Content type="html"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10 results</option>
<option value="20">20 results</option>
<option value="30">30 results</option>
</select>
<input type="submit" value="Search">
</form>

]]></Content>
</Module>
ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして、検索ボックスが表示されるのを確認してください。

※ playground.xml に HTML を記述すると、そのままガジェットで表示されます。



Google Gadget Editor で playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example" />
<Content type="html"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10 results</option>
<option value="20">20 results</option>
<option value="30">30 results</option>
</select>
<input type="submit" value="Search">
</form>
<script src="http://scripts.lrlab.to/opensocial-jquery-1.0.4.min.js"></script>
<script>
jQuery(function($) {
$(document.form).submit(function() {
alert(this.q.value + ' ' + this.c.value);
return false;
});
});
</script>

]]></Content>
</Module>
ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そしてSearch ボタンをクリックし、入力内容が alert 表示されるのを確認してください。

※ opensocial-jquery は http://scripts.lrlab.to/opensocial-jquery-1.0.4.min.js のアドレスで配信しています。詳しくは opensocial-jquery on the cloud を見てください。
※ playground.xml に JavaScript を記述すると、そのままガジェットで実行されます。



Google Gadget Editor で playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example" />
<Content type="html"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10 results</option>
<option value="20">20 results</option>
<option value="30">30 results</option>
</select>
<input type="submit" value="Search">
</form>
<div id="videos"></div>
<script src="http://scripts.lrlab.to/opensocial-jquery-1.0.4.min.js"></script>
<script>
jQuery(function($) {
$(document.form).submit(function() {
var url = 'http://gdata.youtube.com/feeds/videos';
var data = { alt: 'json',
vq: this.q.value,
'max-results': this.c.value
};
$.getJSON(url, data, function(json) {
$.each(json.feed.entry, function() {
$('<img />')
.attr('src', this.media$group.media$thumbnail[0].url)
.appendTo('#videos');
});
});

return false;
});
});
</script>
]]></Content>
</Module>
ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして Search ボタンをクリックし、入力内容にしたがって YouTube から動画を検索し、サムネイルがリスト表示されるのを確認してください。

※ opensocial-jquery は jQuery の Ajax API をクロスドメイン対応に拡張します。
※ YouTube の動画検索は YouTube Data API を使っています。



Google Gadget Editor で playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example">
<Require feature="dynamic-height" />
</ModulePrefs>

<Content type="html"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10 results</option>
<option value="20">20 results</option>
<option value="30">30 results</option>
</select>
<input type="submit" value="Search">
</form>
<div id="videos"></div>
<script src="http://scripts.lrlab.to/opensocial-jquery-1.0.4.min.js"></script>
<script>
jQuery(function($) {
$(document.form).submit(function() {
var url = 'http://gdata.youtube.com/feeds/videos';
var data = { alt: 'json',
vq: this.q.value,
'max-results': this.c.value
};
$.getJSON(url, data, function(json) {
$.each(json.feed.entry, function() {
$('<img />')
.attr('src', this.media$group.media$thumbnail[0].url)
.appendTo('#videos');
});
});
$(window).adjustHeight();
return false;
});
});
</script>
]]></Content>
</Module>
ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして Search ボタンをクリックし、サムネイルの数に応じて、ガジェットの高さが自動調整されるのを確認してください。

※ playground.xml に <Require feature="dynamic-height"> を記述すると、jQuery.fn.adjustHeight がロードされます。



Google Gadget Editor で playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example">
<Require feature="dynamic-height" />
</ModulePrefs>
<Content type="html"><![CDATA[
<style>
#videos img { margin: 2px; width: 80px; hegith: 60px; }
</style>

<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10 results</option>
<option value="20">20 results</option>
<option value="30">30 results</option>
</select>
<input type="submit" value="Search">
</form>
<div id="videos"></div>
<script src="http://scripts.lrlab.to/opensocial-jquery-1.0.4.min.js"></script>
<script>
jQuery(function($) {
$(document.form).submit(function() {
var url = 'http://gdata.youtube.com/feeds/videos';
var data = { alt: 'json',
vq: this.q.value,
'max-results': this.c.value
};
$.getJSON(url, data, function(json) {
$.each(json.feed.entry, function() {
$('<img />')
.attr('src', this.media$group.media$thumbnail[0].url)
.appendTo('#videos');
});
});
$(window).adjustHeight();
return false;
});
});
</script>
]]></Content>
</Module>
ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして Search タンをクリックし、CSS が適用されるのを確認してください。

※ playground.xml に CSS を記述すると、そのままガジェットで適用されます。



これでチュートリアルはおしまいです。

これ以降は opensocial-jquery のドキュメント を参照してください。その中で質問や要望が出てきましたら、お気軽にコメントください。

2009-08-19

opensocial-jquery on the cloud (大げさなタイトルでごめんなさい)

おはようございます。なかじまんです。

OpenSocial ガジェット (アプリ) を開発するとき、jQuery や Dojo、YUI などメジャーなライブラリを Google AJAX Libraries API からロードしてるのをよく見かけます。

Google AJAX Libraries API を使うと...

* ライブラリをホストする必要がない
* ライブラリのロード効率がロケーションに左右されない
* ライブラリのブラウザ(コンテナ?)キャッシュを共有できる

といったよいことがあり、システム上の都合のみならず、ユーザ体験の向上にもつながる効果が期待できます。

そこで opensocial-jquery でも同じ効果を期待して Amazon CloudFront という CDN サービスを使って opensocial-jquery を配信することにしました。

アドレスは、次のとおりです。特に制限などはしませんので、自由に使ってください。

http://scripts.lrlab.to/opensocial-jquery-1.0.4.min.js

不審な点がありましたら、レスポンスヘッダを参照してください。こんな感じです。
x-amz-id-2: (省略)
x-amz-request-id: (省略)
Date: Fri, 14 Aug 2009 01:54:08 GMT
Expires: Wed, 01 Jan 2020 00:00:00 GMT
Last-Modified: Fri, 14 Aug 2009 01:23:02 GMT
Etag: "1b7460e4035ac8cb3d0f1c4a9e2c1d59"
Content-Type: text/javascript
Content-Length: 73683
Server: AmazonS3
Age: 86386
X-Cache: Hit from cloudfront
Via: 1.0 d8c8b41b52e430ca9dc4842099bfe99a.cloudfront.net:11180 (CloudFront), 1.0 dfd248577076af79b5214034bb864f31.cloudfront.net:11180 (CloudFront)
Connection: keep-alive
Amazon CloudFront は転送量で課金されますが、よっぽど膨大なアクセスがない限り、ちょっとした課金で済みますので、今のところ心配はしていません。もしも高額になったり、負担が増えることがあれば、事前に相談の周知をします。むしろそのくらい使って貰えたらうれしいです。

また Expires ヘッダを使って 2020年1月1日までキャッシュを促すようにしていますので、ブラウザやコンテナがキャッシュ制御してくれれば、思ってるほどアクセスは発生しなかもしれませんね。

2009-08-14

opensocial-jquery と Google Gadget Editor を使って gooホーム sandbox でガジェットを開発しよう

こんばんは。なかじまんです。

opensocial-jquery のチュートリアルを用意しました。Google と goo のアカウントさえあれば、WEB ブラウザ 1つだけで体験できる構成にしています。

opensocial-jquery は jQuery を使って WEB サイトを開発する手法を OpenSocial のガジェットにも持ち込もうという目的ではじめたものです。

ですので、このチュートリアルは、日々 jQuery を使って WEB サイトを開発しているがOpenSocial 環境でガジェットを開発したことがないとか、開発しようとしたが新しいことを覚えるのに抵抗を感じているという方々に体験して貰いたいものです。

まずは OpenSocial のガジェットは特別なもの... という感覚をリセットして、jQuery を使って WEB サイトを開発した経験を opensocial-jquery によって OpenSocial のガジェット開発にも再活用できないか...という視点で再確認してはどうかと提案します。その中で新しい発見があればうれしい限りです。

それではチュートリアルをはじめます。

はじめに Google にログインしてください。



次に Google Gadget Editor を開いてください。そして Hello, world! ガジェットが表示されるのを確認してください。



Hello, world! ガジェットを赤字のとおり修正してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example"
description="hello world example" />
<Content type="html" view="profile,home,canvas"><![CDATA[
Hello, world!
]]></Content>
</Module>
File メニューから Save を選択してください。続けて playground.xml と入力して OK ボタンをクリックし、Hello, world! ガジェットを保存してください。



playground.xml の URL を確認します。playground.xml のリンクを開いてください。



このときの playground.xml の URL を手元に控えてください。次のような URL になるはずです。数値の部分は各自によって異なります。

http://hosting.gmodules.com/ig/gadgets/file/(数値)/playground.xml

続けて goo ホーム sandbox にログインしてください。そして、ガジェット開発管理へをクリックしてください。

※ goo ホーム sandbox のアカウントを持っていないときは ディベロッパー申請 をしてください。数営業日で受理されます。



手元に控えた playground.xml の URL を入力して新規作成ボタンをクリックし、ガジェットを登録してください。



そして、このガジェットを追加ボタンをクリックし、ガジェットをインストールしてください。



ガジェットを追加ボタンをクリックしてください。



このガジェットを見るボタンをクリックしてください。



playground.xml として保存したガジェットが表示されます。

このときのガジェットの URL を手元に控えてください。次のような URL になるはずです。gooID や英数字の部分は各自によって異なります。

http://sandbox.home.goo.ne.jp/gadget/canvas/(gooID)/(英数字)/(英数字)



Google Gadget Editor に戻り、playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example"
description="hello world example" />
<Content type="html" view="profile,home,canvas"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10件</option>
<option value="20">20件</option>
<option value="30">30件</option>
</select>
<input type="submit" value="検索">
</form>

]]></Content>
</Module>
goo ホーム sandbox に戻り、ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして、検索ボックスが表示されるのを確認してください。

※ playground.xml に HTML を記述すると、そのままガジェットで表示されます。



Google Gadget Editor に戻り、playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example"
description="hello world example">
<Require feature="opensocial-jquery" />
</ModulePrefs>

<Content type="html" view="profile,home,canvas"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10件</option>
<option value="20">20件</option>
<option value="30">30件</option>
</select>
<input type="submit" value="検索">
</form>
<script>
jQuery(function($) {
$(document.form).submit(function() {
alert(this.q.value + ' ' + this.c.value);
return false;
});
});
</script>

]]></Content>
</Module>
goo ホーム sandbox に戻り、ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして、検索ボタンをクリックし、入力内容が alert 表示されるのを確認してください。

※ playground.xml に <Require feature="opensocial-jquery"> を記述すると、opensocial-jquery がロードされます。
※ playground.xml に JavaScript を記述すると、そのままガジェットで実行されます。



Google Gadget Editor に戻り、playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example"
description="hello world example">
<Require feature="opensocial-jquery" />
</ModulePrefs>
<Content type="html" view="profile,home,canvas"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10件</option>
<option value="20">20件</option>
<option value="30">30件</option>
</select>
<input type="submit" value="検索">
</form>
<div id="videos"></div>
<script>
jQuery(function($) {
$(document.form).submit(function() {
var url = 'http://gdata.youtube.com/feeds/videos';
var data = { alt: 'json',
vq: this.q.value,
'max-results': this.c.value
};
$.getJSON(url, data, function(json) {
$.each(json.feed.entry, function() {
$('<img />')
.attr('src', this.media$group.media$thumbnail[0].url)
.appendTo('#videos');
});
});

return false;
});
});
</script>
]]></Content>
</Module>
goo ホーム sandbox に戻り、ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして、検索ボタンをクリックし、入力内容にしたがって YouTube から動画を検索し、サムネイルがリスト表示されるのを確認してください。

※ opensocial-jquery は jQuery の Ajax API をクロスドメイン対応に拡張します。
※ YouTube の動画検索は YouTube Data API を使っています。



Google Gadget Editor に戻り、playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example"
description="hello world example">
<Require feature="opensocial-jquery" />
<Require feature="dynamic-height" />
</ModulePrefs>
<Content type="html" view="profile,home,canvas"><![CDATA[
<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10件</option>
<option value="20">20件</option>
<option value="30">30件</option>
</select>
<input type="submit" value="検索">
</form>
<div id="videos"></div>
<script>
jQuery(function($) {
$(document.form).submit(function() {
var url = 'http://gdata.youtube.com/feeds/videos';
var data = { alt: 'json',
vq: this.q.value,
'max-results': this.c.value
};
$.getJSON(url, data, function(json) {
$.each(json.feed.entry, function() {
$('<img />')
.attr('src', this.media$group.media$thumbnail[0].url)
.appendTo('#videos');
});
});
$(window).adjustHeight();
return false;
});
});
</script>
]]></Content>
</Module>
goo ホーム sandbox に戻り、ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして、検索ボタンをクリックし、サムネイルの数に応じて、ガジェットの高さが自動調整されるのを確認してください。

※ playground.xml に <Require feature="dynamic-height"> を記述すると、jQuery.fn.adjustHeight がロードされます。



Google Gadget Editor に戻り、playgorund.xml を赤字のとおり修正してください。そして File メニューから Save を選択して、ガジェットを保存してください。
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="hello world example"
description="hello world example">
<Require feature="opensocial-jquery" />
</ModulePrefs>
<Content type="html" view="profile,home,canvas"><![CDATA[
<style>
#videos img { margin: 2px; width: 80px; hegith: 60px; }
</style>

<form name="form">
<input type="text" name="q" />
<select name="c" />
<option value="10">10件</option>
<option value="20">20件</option>
<option value="30">30件</option>
</select>
<input type="submit" value="検索">
</form>
<div id="videos"></div>
<script>
jQuery(function($) {
$(document.form).submit(function() {
var url = 'http://gdata.youtube.com/feeds/videos';
var data = { alt: 'json',
vq: this.q.value,
'max-results': this.c.value
};
$.getJSON(url, data, function(json) {
$.each(json.feed.entry, function() {
$('<img />')
.attr('src', this.media$group.media$thumbnail[0].url)
.appendTo('#videos');
});
});
$(window).adjustHeight();
return false;
});
});
</script>
]]></Content>
</Module>
goo ホーム sandbox に戻り、ブラウザの更新ボタンをクリックし、ガジェットをリロードしてください。そして、検索ボタンをクリックし、CSS が適用されるのを確認してください。

※ playground.xml に CSS を記述すると、そのままガジェットで適用されます。



これでチュートリアルはおしまいです。

これ以降は opensocial-jquery のドキュメント を参照してください。その中で質問や要望が出てきましたら、お気軽にコメントください。

2009-08-13

opensocial-jquery 1.0.4 をリリースしました



こんばんは。なかじまんです。opensocial-jquery 1.0.4 をリリースしました。

opensocial-jquery
http://code.google.com/p/opensocial-jquery/

1.0.4 は Google Friend Connect (GFC) 対応の強化とバグ対応です。

言語の選択

jQuery.container.locale を使って、サイトの言語を指定できるようにしました。あらかじめ GFC の管理画面でサイト言語を設定しておけますが、その設定よりも優先します。省略したときは、既定のサイト言語になります。

jQuery.container.locale = 'en';

jQuery.fn.gadget を使って、ガジェットを表示するとき、対象の要素に lang か xml:lang 属性があれば、その言語でガジェットを表示するようにしました。このときjQuery.container.locale より優先します。

<script type="text/javascript">
$('div.gadget').gadget('http://example.com/gadgets.xml');
</script>
<div class="gadget" lang="ja"></div>
<div class="gadget" xml:lang="ja"></div>

キャンバスビュー

jQuery.fn.gadget を使って、ガジェットを表示するとき、対象の要素のクラス名に canvas を含むとき、ガジェットをキャンバスビューで表示するようにしました。

<script type="text/javascript">
$('div.gadget').gadget('http://example.com/gadgets.xml');
</script>
<div class="gadget" class="canvas"></div>

スキン

jQuery.skin を使って、スキンを参照できるようにしました。BG_COLOR といった Gadgets API 形式のほかにも bgColor といった JavaScript ライクなキー名でも参照できるようにしてあります。以下の実例は、同じ結果になります。

$.skin('BG_COLOR');
$.skin('bgColor');

バグ対応

Issue 19: fields.split(',') した後、trim すべきじゃないか。

その他

ガジェットや Google Friend Connect でもない普通のサイトで、普通の jQuery としても使えるようにしました。

デモ

Google Friend Connect In-page integration



Golazo GeoNotes

2009-08-12

Golazo GeoNotes is available. It's social web app that integrated with Google Friend Connect highly.

Hello,

I'm afraid my expressions may be rude or hard to read, because I'm not so good at English. But please, please be patient! I will try hard to learn English!

Thank you very much for the chance to introduce Golazo GeoNotes.

Golazo GeoNotes
http://golazo.aptanacloud.com/



Golazo GeoNotes is the social web application that integrated with Google Friend Connect (GFC) highly. I developed this demo app from the following purpose.

* What kind of a social web application can we build when we use GFC platform and API?

* When we use GFC platform and API, how far we can develop a social Web application effectively?

In this app, you post a geographic text, and can associate a geographic coordinate automatically. And you can share the text with a friend.

This app depends on GFC platform and API for the following social functions.

* With sign-in button of GFC and and two-legged OAuth by fcauth this app authenticate an account and link a profile.

* This app displays Site View, Home View, Profile View, and Canvas View with a social graph of GFC.

* This app displays members, friends, footprints, activities, chat, comment, and recommend with a Social Gadgets in each
view.

* This app depends on Members Gadgets for the management of the profile, a search and the invitation of the friend.

A development environment and the volume of this app are as follows.

* Aptana Cloud (Jaxer, Apache2, MySQL5)
* ActiveJS
* opensocial-jaxer-client
* opensocial-jquery
* jQuery XML to JSON Plugin
* CSS Browser Selector

* 896 lines of JavaScript on client and server.
* 10 pages of HTML
* 2 tables on database
* 9 social gadgets

I want to contribute to the Jaxer, GFC, and OpenSocial with this demo app. Did you think to develop the custom social web application that used Jaxer and GFC?

Thank you.