開発の基礎

このドキュメントでは、ガジェットを開発するための基礎的な概念と作業手順について説明します。Gadgets API の概要については、スタート ガイドをご覧ください。

目次

  1. コンテンツ タイプの選択
    1. HTML
    2. URL
  2. 既存のウェブ ページやアプリケーションをガジェットに変換
  3. Userpref データ型の処理
    1. list データ型の使用
    2. location データ型の使用
  4. 状態の保存
  5. 特殊文字のエスケープ
  6. ログインまたは Cookie を要求するガジェットの作成

コンテンツ タイプの選択

ガジェットの開発において最初に決めなければならないのは、どのコンテンツ タイプを使用するかです。次に例を示します。

<Content type="html">

コンテンツ タイプによって以下が決まります。

  • ガジェット作成者としてどの API 機能を使用できるか。
  • ガジェットがどのようにレンダリングされるか。
  • ガジェットをどこに展開できるか。

次の表では、使用できるコンテンツ タイプを示し、それぞれどのような場合に使用するかを説明します。

コンテンツ タイプ 説明 用途
html html コンテンツ タイプを選択した場合、通常はすべてのコンテンツがガジェット仕様に保持されます。type="html" ガジェットには、HTML に加え、JavaScript、Flash、ActiveX などのブラウザ オブジェクトを埋め込むことができます。これがデフォルトのタイプです。 柔軟性が最も高く、用途の広いコンテンツ タイプが html です。迷ったときは html コンテンツ タイプを選択してください。
url url コンテンツ タイプを選択した場合、ガジェットのコンテンツは、ガジェット仕様に指定されている URL が指すリモート ウェブ ページに保持されます。このリモート ウェブ ページは、すべての HTML マークアップと JavaScript が保持される場所です。HTML マークアップと JavaScript コードは、ガジェット仕様自体には一切保持できません。 現時点の gadgets.* および OpenSocial API では、type="url" コンテンツ タイプは完全にはサポートされていません。ガジェット JavaScript ライブラリで type="url" コンテンツ タイプを使用したい場合は、レガシー Gadgets API を使用してください。

HTML

html コンテンツ タイプを選択した場合、通常はすべてのコードがガジェット仕様に保持されます。ここでいうコードには、ガジェット XML、HTML マークアップ、JavaScript が含まれます。このデベロッパー ガイドで示すほとんどのサンプルでは、html コンテンツ タイプが使用されています。最も柔軟性が高く用途の広いコンテンツ タイプですので、特別な要件のあるガジェットを記述する場合を除き、通常はこのタイプを選択します。

次に示すサンプルは、ROT13 のガジェット実装です。ROT13 では、アルファベットの各文字を右に 13 ずつずらすことによってテキストを暗号化します。ROT13 をもう一度適用すると、各文字が再び 13 ずつずれて元のテキストに戻ります。

ガジェットの仕様は次のとおりです:

<?xml version="1.0" encoding="UTF-8" ?> 

<Module>
  <ModulePrefs title="Magic Decoder"/> 
  <Content type="html">
  <![CDATA[
     <script type="text/javascript">

       // The gadget version of ROT13.
       // Encodes/decodes text strings by replacing each letter with the letter
       // 13 positions to the right in the alphabet. 
       function decodeMessage (form) {
          var alpha = "abcdefghijklmnopqrstuvwxyz";
          var input = form.inputbox.value; 
          var aChar;
          var message = "";
          for (var i = 0; i <input.length; i++)
          { 
             aChar = input.charAt(i);
             var index = alpha.indexOf(aChar.toLowerCase());

             // if a non-alphabetic character, just append to string
             if (index==-1)
             {
                message += aChar;
             }

             // if you have to wrap around the end of the alphabet
             else if(index > 12) { // compensate for 0-based index
                index = 25 - index; // last item in array is at [25]
                index = 12 - index; // because array starts with 0
                aChar = alpha.charAt(index);
                message += aChar;
             }

             // if you don't have to wrap
             else {
                aChar = alpha.charAt(index+13);
                message += aChar;
             }
          }
          document.getElementById('content_div').innerHTML = "<b>Your message: </b>" + message; 
     }
     </script>

     <FORM NAME="myform" ACTION="" METHOD="GET">Message: <BR>
<INPUT TYPE="text" NAME="inputbox" VALUE=""><P>
<INPUT TYPE="button" NAME="button" Value="Transform" onClick="decodeMessage(this.form)"> </FORM> <div id="content_div"></div> ]]> </Content> </Module>

以下に、type="html" ガジェットのルールを示します。

  • type="html" ガジェットには、CDATA セクションを挿入し、すべての HTML をこのセクションに含める必要があります。
<Content type="html"> 
    <![CDATA[ HTML here... ]]>

CDATA セクションは、通常はマークアップとして認識される文字を含むテキストをまとめてエスケープするために使用されます。CDATA セクションで認識される唯一の区切り文字は、CDATA セクションの最後にある「]]>」文字列です。

  • <html>, <head>, タグや <body> タグは使用できません。ガジェットは、独自の <html>, <head>, タグと <body> タグで生成されます。一般的に <body> タグ内に含めるコンテンツのみを含めるようにします。

html コンテンツ タイプのガジェットからは、外部の JavaScript ファイルを参照することもできます。

<Module>
  <ModulePrefs ... /> 
  <Content type="html"><![CDATA[
    <script src="http://www.example.com/gadgets/clock/clock.js" type="text/javascript"></script>

  ]]></Content> 
</Module>

URL

ガジェットに type="url" コンテンツ タイプが含まれている場合は、href= 属性で URL を指定します。ガジェット仕様内のその他のコンテンツはすべて無視されますurl コンテンツ タイプを選択した時点で、ガジェットのユーザー インターフェースやプログラム ロジックに関係するすべての情報は、URL で参照されているファイルに格納されているものと見なされます。HTML マークアップと JavaScript コードは、ガジェット仕様自体には一切保持できません。次に例を示します。

<Module>
  <ModulePrefs ... /> 
  <Content type="url" href="http://www/cgi-bin/example/gadgets/mystats.cgi" /> 
</Module>

既存のウェブ ページやアプリケーションをガジェットに変換

既存のウェブ ページやアプリケーションをガジェットに変換する場合は、以下のガイドラインに従ってください。

  • <html><head><body> タグを削除します (つまり、HTML コンテンツだけの状態にします)。このガイドラインは type="html" ガジェットにのみ適用されます。type="url" ガジェットには適用されません。
  • onload イベントの場合は、gadgets.util.registerOnLoadHandler() を使用します。
  • ガジェットでログインが必要になる場合は、URL コンテンツ タイプを使用します。注意点についてはログインまたは Cookie を要求するガジェットの作成をご覧ください。HTTPS ガジェットの場合、ユーザーが Internet Explorer でガジェットを表示すると、「混在したコンテンツ」の警告メッセージが表示されるので注意してください。
  • ページやアプリケーションが小さなガジェット領域に収まるよう、必要に応じてユーザー インターフェースに変更を加えます。プロトタイプを作成したい場合は、makeRequest() を使用してコンテンツをプロキシできます。営利を目的としてガジェットを開発した場合は、新たに簡単なページを作成し、 type="url" を使用してガジェットにリンクさせることをおすすめします。

Userpref データ型の処理

ガジェットの仕様では、すべての ユーザー設定にデータ型が割り当てられています。datatype は、属性のデータ型を指定するオプション文字列です。datatype として有効な値は、stringboolenumhidden (ユーザーが編集できない非表示文字列)、listlocation (Google マップをベースとしたガジェットで使用) です。デフォルトのデータ型は string です。

ユーザー設定のデータ型の詳細については、リファレンスをご覧ください。

このセクションでは、listlocation の 2 つの特殊なデータ型について説明します。その他のデータ型の使用方法については、このドキュメントの随所に示されているサンプル (enumhiddenbool など) をご覧ください。

list データ型の使用

list データ型のユーザー設定は、実行時にユーザーから動的に入力される値の配列です。ユーザーがユーザー設定編集ボックスに値を入力すると、それらの値がリストに追加されます。このリストは、他のユーザー設定と同じように、実行中のガジェットからプログラム的にアクセスできます。list データ型は、ユーザーが任意の値リストを動的に入力できるようにしたい場合に使用できます。たとえば天気予報のガジェットでは、ユーザーが郵便番号を入力できるようにする場合があります。

list データ型のユーザー設定は、datatype="list" を使用して宣言します。次に例を示します。

<UserPref name="mylist" display_name="Add Search Terms" datatype="list" required="true"/> 

ガジェットからリスト内の値にアクセスするには、Prefs 関数 getArray(), を使用します。次に例を示します。

var search_terms = prefs.getArray("mylist");

配列内の項目は、パイプ区切りのリストとして格納されます。Prefs 関数 getString() を使用すると、このリストを単一の文字列として返すことができます。その場合も、値はパイプ文字 (|) で区切られています。次に例を示します。

prefs.getString("mylist");

また、パイプ区切りの文字列を使用して、list タイプのデフォルト値を設定することも可能です。

<UserPref name="mylist" display_name="Add Search Terms" datatype="list" default_value="zdnet|pc|Apple Insider"/>

Prefs 関数 setArray(name, val) を使用すると、リストの値をプログラム的に追加できます。この関数を使用するには、ガジェットの <ModulePrefs><Require feature="setprefs"/> を追加する必要があります。たとえば次に示す抜粋コードでは、リストに値「Nokia」と「CNET」を追加しています。

...

<ModulePrefs title="Feed Searcher" scrolling="true">
   <Require feature="setprefs" />
</ModulePrefs> ... prefs.setArray("mylist", ["Nokia","CNET"]);

次に、ユーザーが編集ボックスに入力したリスト項目を出力する単純なサンプルを示します。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs 
    title="List Data Type Example" 
    scrolling="true"/> 
  <UserPref name="mylist" 
    display_name="Add Terms" 
    datatype="list" />
  <Content type="html">
  <![CDATA[ 
  <div id=content_div></div>

  <script type="text/javascript"> 
    // Get userprefs
    var prefs = new gadgets.Prefs();

    // Get the array of search terms entered by the user
    var terms = prefs.getArray("mylist");  
    var html = "";

    // If the user has not added any terms yet, display message.
    if (terms.length == 0)
    {
      html += "Edit the userprefs to add terms.";
    }
    else {
      html += "Your terms are:<br /><br />";
      for (var i = 0; i < terms.length ; i++) {
        var term = (terms[i]);
        html += term + "<br />";
      }
    }
    document.getElementById("content_div").innerHTML = html; 
  </script>

  ]]> 
  </Content>
</Module>

location データ型の使用

Google マップをベースとするガジェットでは、location データ型を使用できます。次のサンプル ガジェットでは、location データ型を使用する方法について説明します。ガジェットでは、location データ型の値として、米国、カナダ、英国の主要都市または郵便番号を指定する必要があります。郵便番号を指定する方が、良好な結果を得られるかもしれません。

location データ型を使用している場合は、getString() を使用して、ユーザーが指定した場所の緯度と経度を取得できます。

<Module>
<ModulePrefs title="Map of __UP_loc__" height="300" author="Jane Smith" author_email="xxx@google.com" />
<UserPref name="loc" display_name="Location" datatype="location" required="true" />
<Content type="html">
<![CDATA[
<script src="http://maps.google.com/maps?file=js" type="text/javascript"></script>
<div id="map" style="width: 100%; height: 100%;"></div>
<script type="text/javascript">
var prefs = new gadgets.Prefs();
var map = new GMap(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.centerAndZoom(new GPoint(prefs.getString("loc.long"), prefs.getString("loc.lat")), 6);
</script> ]]>
</Content> </Module>

location 設定 x の読み取りにおいて、

  • x が空文字列 (つまり空の場所) の場合、 x.latx.long は空文字列になります。
  • x をジオコード化できない (つまり無効な場所である) 場合、x.lat および x.long は 0.0 になります。

以前のバージョンの Gadgets API では、location タイプとして default_value を指定することはできませんでした。これは、今後は適用されません。

状態の保存

ユーザー設定の値は、編集ボックスでユーザー自身が設定できるようにするのが一般的です。しかし、ユーザーに入力させる代わりに、プログラム的に値を設定した方が便利な場合もあります。たとえば、ゲーム ガジェットでは、ユーザーの最高得点を永続的に保持したいかもしれません。その場合は、「high_score」ユーザー設定の値をプログラム的に設定できます。

setprefs 機能を使用するには、ガジェットに以下を追加する必要があります。

  • setprefs ライブラリを読み込むようガジェットに指示する <Require feature="setprefs"/> タグ (<ModulePrefs> の下にあります)。
  • 値をプログラム的に設定して永続的に保持したいユーザー設定。通常、このユーザー設定のデータ型は hidden にします。
  • 値を保存したいユーザー設定の JavaScript 関数 set() の呼び出し。

なお、現時点では、URL の制約により、ユーザー設定のサイズは 2 K に制限されています。

次に示すサンプル ガジェットには 2 つのボタンがあります。1 つはカウンタの値を増やすボタン、もう 1 つはカウンタの値を 0 にリセットするボタンです。このサンプルでは、「counter」がユーザー設定です。データ型は hidden なので、この値をユーザーが直接変更することはできません。

ガジェットの仕様は次のとおりです:

<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs 
    title="Setprefs New">
    <Require feature="opensocial-0.8"/>
    <Require feature="setprefs" /> 
    </ModulePrefs>
  <UserPref 
    name="counter" 
    default_value="0" 
    datatype="hidden"/>
  <Content type="html">
  <![CDATA[ 
    <div id="content_div" style="height: 100px;"></div>
    <script type="text/javascript">

    // Get user preferences
    var prefs = new gadgets.Prefs();
    var html = "";
    var div = document.getElementById('content_div');
    // Increment value of "counter" user preference
    function incrementCounter() {  
      var count = prefs.getInt("counter");
      div.innerHTML = "The count is " + count + ".";
      // Increment "counter" userpref          
      prefs.set("counter", count + 1);
    }

    // Reset value of "counter" userpref to 0
    function resetCounter(){
      prefs.set("counter", 0);
      div.innerHTML = "Count reset to " + prefs.getInt("counter") + ".";
    }

    </script>
    <input type=button value="Count" name="count" onClick="incrementCounter()">
    <input type=button value="Reset" name="reset" onClick="resetCounter()">
  ]]> 
  </Content>
</Module>

: 複数の値を保持したい場合は、値を JSON 文字列に保存することをおすすめします。

特殊文字のエスケープ

ガジェット仕様の XML 属性内では、一部の特殊文字をエスケープする必要があります。なお、ガジェット仕様内では、ASCII エンティティしか使用できません。たとえば、ISO 8859-1 の記号エンティティは使用できません。次の表に、サポートされる特殊文字を示します。

文字 エスケープ コード
& &amp;
< &lt;
> &gt;
" &quot;
' &apos;

次に例を示します。

  • 悪い例: href="http://www.foo.com/bar?x=a&y=b"
  • 良い例: href="http://www.foo.com/bar?x=a&amp;y=b"
  • 悪い例: description="this is a "sexy" gadget"
  • 良い例: description="this is a &quot;sexy&quot; gadget"

なお、CDATA ブロックでは、このタイプのエスケープは必要ありません。しかし、念のためエスケープしておくことをお勧めします。

JavaScript コード内では、_hesc(str) 関数を使用して、特殊文字をエスケープした str HTML 文字列を返すことができます。エスケープできる文字は次のとおりです。 <>'".

ログインまたは Cookie を要求するガジェットの作成

Microsoft Internet Explorer および Apple Safari のデフォルトのプライバシー ポリシーでは、サードパーティ サイトによる Cookie の設定は許可されていません。したがって、一部のガジェットはうまく機能しません。具体的には、ログインに Cookie を使用するサイトは、iGoogle ページからの iframe 内部では正常に機能しません。以下に、この問題の解決策を示します。

  • Cookie の代わりに URL パラメータを使用する。たとえば、Orkut 誕生日ガジェットでは、ログイン認証情報を URL で渡します。ただし、この方法を選択する場合は、これらの URL パラメータが、HTTP 参照フィールドで他のウェブサイトに漏れないよう注意する必要があります。
  • OAuth ガジェットを使用します。Gadgets API では OAuth プロキシと呼ばれる機能がサポートされます。この機能を使えば、ユーザー アカウントに関連する個人データを保管する別のウェブサイトにガジェットを安全に接続できます。OAuth は、個人データのアカウント所有者がウェブサイトに指示して、別のアプリケーションが個人データにアクセスできるようにするための標準規格です。OAuth プロキシは、ガジェットが OAuth 標準規格を簡単に使用できるよう設計されています。
  • P3P ヘッダーを記述する。サイトのプライバシー ポリシーによっては、P3P ヘッダーを記述することで、サイト上のサードパーティ Cookie を Internet Explorer に読み込めるようにすることができます (Safari には対応していません)。PHP を使用している場合にこのヘッダーを設定するには、PHP ページの最上部に次のコード スニペットを追加します。
<?php
  header("P3P: CP=\"CAO PSA OUR\"");
?> 

このスニペットは、ページに出力が表示される前に呼び出す必要があります。

サイトでどのヘッダーを使用できるかを判断するには、サイトのプライバシー ポリシーを慎重に確認する必要があります。弁護士と一緒に確認することをお勧めします。

  • ユーザーに指示メッセージを表示する。これは、JavaScript で実現できます。このサンプル ガジェット試してください。認証ロジックに指示メッセージを統合することも可能です。Cookie がブロックされたら、ユーザーにメッセージを表示して、プライバシー設定を低くするか、別のウェブ ブラウザを試すよう指示します。たとえば、次のようなメッセージを表示できます。

お使いのブラウザの設定では、このサイトを表示することができません。Microsoft Internet Explorer の場合は、セキュリティ設定を変更できます。その場合は、まず [ツール</strong>] > [<strong>インターネット オプション] を選択します。次に、[プライバシー] タブを開いて [詳細設定] をクリックし、[自動 Cookie 処理を上書きする] をオンにします。[サード パーティの Cookie] で [受け入れる] をオンにします。あるいは、Firefox など、他のウェブ ブラウザをお試しください。

 

トップへ戻る