Popflyブロックの作り方

Popflyもすっかりパブリックベータになってから結構時間がたちましたね。ということで久しぶりにログイン。プライベートアルファと比較するとデザインが洗練されてきてますね。そしてどんどんブロックが増殖しているのにびっくり!これはやはりPopflyのブロックの定義のシンプルさによるものでしょうね。Google Mashup Editorと比較するとやはり自分のようなWeb屋でもない人間でもかなり直感的に定義ができてしまう。

たとえば「Hotpepper」のブロックを作ってみようとすると。。。

  • 1.まずは、ブロックのインタフェース(Block Description)を定義。


ホットペッパーのグルメサーチAPIを使用。入力としてフリーキーワードと検索結果の最大出力データ数を定義し、出力としてPC用店舗トップ写真や、経度緯度などなどを定義。

<?xml version="1.0" encoding="utf-8"?>
<block class="HotpepperClass">
  <providerName>Hot Pepper</providerName>
  <providerUrl>http://www.hotpepper.jp/</providerUrl>
  <providerLogoUrl>http://api.hotpepper.jp/content/images/hp_api_m.gif</providerLogoUrl>
 <blockIconUrl>http://api.hotpepper.jp/content/images/hp_api_s.gif</blockIconUrl>

  <operations>
 
    <operation name="getPhotos">
      <description>
        Get photos.
      </description>
      <inputs>
        <input name="Keyword" required="true" type="string">
          <description>free Word for search</description>
          <defaultValue>beer</defaultValue>
          <constraints />
        </input>
        <input name="Count" required="false" type="integer">
          <description>maximum number of photos to return</description>
          <defaultValue>15</defaultValue>
          <constraints />
        </input>
      </inputs>
      <outputs>
        <output isArray="true" type="custom" object="Photo" />
      </outputs>
    </operation>
 
  </operations>
  <objects>
    <object name="Photo">
      <field name="url" type="imageUrl" isArray="false" />
      <field name="thumbnailUrl" type="thumbnailImageUrl" isArray="false" />
      <field name="id" type="id" isArray="false" />
      <field name="owner" type="userName" isArray="false" />
      <field name="title" type="title" isArray="false" />
      <field name="longitude" type="longitude" isArray="false" />
      <field name="latitude" type="latitude" isArray="false" />
    </object>
  </objects>
</block>
  • 2.次に、入力から出力への変換のためのロジックをJavaScriptで書いていく。


とはいっても、大したことはせず入力されたキーワードと出力数をホットペッパーグルメサーチに渡して(http://api.hotpepper.jp/GourmetSearch/V110/?key=guest&Count=[Count]&Keyword=[Keywork])、そのレスポンスをパースして出力に合わせるだけ。コードがおかしいところは目をつぶって下さい。

function HotpepperClass() {
 // Associate return types with each method (brackets indicate arrays):
    this.__getPhotos = [new Photo()];
    this.DEFAULT_MAX_PHOTOS = 30;
}

HotpepperClass.prototype.getPhotos = function(Keyword, Count) {
 // Retrieves photos marked with the specified text in the title, description, or tags.
 //
 // number (optional): The maximum number of photos to return (default=30)

    var photos = this._getHotpepperPhotos(Keyword, Count);

    return photos;
};


HotpepperClass.prototype._getHotpepperPhotos = function(Keyword,Count)
{
    if(!Count|| isNaN(Count)) Count= this.DEFAULT_MAX_PHOTOS;
    var root = this._getHotpepperXml(Keyword, Count);

    var photos = this._getPhotoArrayFromXml(root);
    
    return photos;
};

HotpepperClass.prototype._getHotpepperXml = function(Keyword, Count)
{
    var query = "http://api.hotpepper.jp/GourmetSearch/V110/?key=guest" +"&Count="+Count+"&Keyword="+Keyword;
    var root = environment.getXml(query);

    
    return root;
};

HotpepperClass.prototype._getPhotoArrayFromXml = function(root) 
{
    var photoArray = new Array();

    var photos = root.getElementsByTagName("Shop");
    var count = photos.length;

    for(var i = 0; i < count; i++)
    {
//only Mozilla
        var photo = photos[i];

        var id = photo.getElementsByTagName("ShopIdFront")[0].textContent;
//alert(id);

        var ownerName = photo.getElementsByTagName("ShopName")[0].textContent;
        var title = photo.getElementsByTagName("ShopName")[0].textContent;

        var lon = photo.getElementsByTagName("Longitude")[0].textContent;
//        alert(lon);

        var lat = photo.getElementsByTagName("Latitude")[0].textContent;
//        alert(lat);

        var url = photo.getElementsByTagName("PcLargeImg")[0].textContent;
  //      alert(url );

        var mediumUrl = photo.getElementsByTagName("PcMiddleImg")[0].textContent;
//        alert(mediumUrl );

        photoArray.push(new Photo(id, ownerName, title, url, mediumUrl, lon, lat));
    }
    
    return photoArray;
};

function Photo(id, ownerName, title, url, mediumUrl, lon, lat)
{
    this.id = id;
    this.owner = ownerName;
    this.title = title;
    this.url = mediumUrl;
    this.thumbnailUrl = url;
    this.longitude = lon;
    this.latitude = lat;

    this.toString = function()
    {
        return "<table><tr><td><a href='" + environment.escapeQuotes( this.url ) + "' target='_blank'><img src='" 
            + environment.escapeQuotes( this.thumbnailUrl ) + "' title='" 
            + environment.escapeQuotes( this.title ) + ", ID: " + environment.escapeQuotes( this.id ) + "'/></a></td><tr><td>" 
            + this.latitude + ", " + this.longitude + "</td></tr></table>";
    }
}

で、これらをプレビューしてみると。。。

  • HotPepperブロックインタフェース

  • PhotoSphereブロックの入力に対してHotPepper出力を合わせる


そういえば、Silvelightブロックのようなレンダリング系のブロックの定義ってどうやるんでしたっけ。

ネタ

最近はWindows Mobile端末を持っている女性の方を時々見かけるようになってきましたね。Advanced Esのようなデザインならば女性が持っていても違和感ありませんしね。iPhoneGoogle Phoneなどの大きな影が迫ってくる現状ですので、今のうちにどんどんと普及させていって欲しいものです。

確かに。特許数を稼ぐことが目的となって大企業さんもおおいですよね。

Facebookの買収ニュースを見たのをきっかけに、久しぶりにFacebookにログインしてみたら怪しいコンタクトが多々あった。金髪のお水っぽいお姉さんからのコンタクトを了承するはずもなく。。。ほぼスパムですね。