開発の基礎

このドキュメントでは、ガジェット開発プロセスの基本的なコンセプトとタスクについて説明します。ガジェット API の使用方法については、スタートガイドをご覧ください。

コンテンツ タイプの選択

ガジェットを開発する際に最初に行う意思決定の 1 つは、どのコンテンツ タイプを使用するかです。次に例を示します。

<Content type="html">

コンテンツ タイプによって、次の情報が決まります。

  • ガジェット作成者が使用できる API 機能
  • ガジェットのレンダリング方法。
  • ガジェットをデプロイする場所。

次の表に、使用可能なコンテンツ タイプと、それらを使用すべき状況を示します。

コンテンツ タイプ 説明 使用する場面
html html コンテンツ タイプでは、すべてのコンテンツは通常、ガジェット仕様に含まれます。type="html" ガジェットには HTML が含まれており、JavaScript、Flash、ActiveX などのブラウザ オブジェクトが埋め込まれている可能性があります。これがデフォルトのタイプです。 柔軟性が高く汎用性の高いコンテンツ タイプは html です。判断に迷う場合は、html コンテンツ タイプを選択します。
url コンテンツ タイプが url の場合、ガジェット コンテンツは、ガジェット仕様の URL で参照されるリモート ウェブページに存在します。リモート ウェブページには、HTML マークアップと JavaScript がすべて存在します。ガジェット仕様自体に HTML マークアップや JavaScript コードを含めることはできません。 現在のところ、type="url" コンテンツ タイプは gadgets.* API または OpenSocial API で完全にはサポートされていません。

HTML

html コンテンツ タイプの場合、通常、すべてのコードはガジェットの仕様に存在します。これには、ガジェットの XML、HTML マークアップ、JavaScript などが含まれます。このデベロッパー ガイドのほぼすべての例では、html コンテンツ タイプを使用しています。最も柔軟性が高く、さまざまな用途に使用できます。また、特定の要件のあるガジェットを作成していない限り、通常はこのタイプを選択する必要があります。

次の例は、ROT13 のガジェット実装です。ROT13 では、各文字をアルファベットのアルファベットの右 13 文字に置き換えてテキストを暗号化します。ROT13 を再適用すると、各文字が再度回転し、元のテキストが復元されます。

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

<?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 セクションで認識される区切り文字は、&DATA ;]]>" 文字列だけです。

  • <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" ガジェットには適用されません。
  • オンロード イベントには、gadgets.util.registerOnLoadHandler() を使用します。
  • ガジェットでログインが必要な場合は、URL コンテンツ タイプを使用します。発生する可能性がある問題については、ログインや Cookie を必要とするガジェットの作成をご覧ください。HTTPS ガジェットでは、Internet Explorer に対して「混合コンテンツ」の警告が発行され、ユーザーに不快感を与える可能性があります。
  • ページまたはアプリケーションを小さなガジェット空間に適合させるために必要なユーザー インターフェースの変更を行います。 愛好家やプロのプロトタイプを構築する場合は、makeRequest() を使用してプロキシを使用できます。商用開発されたガジェットの場合は、新しい小さなページを作成し、その URL を参照するように type="url" を使用することをおすすめします。

Userpref データ型の操作

ガジェット仕様では、すべてのユーザー設定にデータ型があります。datatype は、属性のデータ型を指定する文字列です(省略可)。 datatype の値には、stringboolenumhidden(ユーザーが編集できない非表示の文字列)および list があります。デフォルトのデータ型は string です。

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

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

リストデータ型の使用

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

userpref がリストデータ型を持つことを、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");

パイプ区切り文字列を使用して、リスト型のデフォルト値を設定することもできます。

<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>

地域の指定

ユーザーが地理的位置を指定できるようにガジェットを作成するには、Google Maps API ジオコーダを使用します。

注: 以前は、ガジェット デベロッパーは location userpref データ型を使用して、ユーザーが地理的位置を指定できるようにしていました。このデータ型はサポートが終了しました。

たとえば、次のガジェットは、ユーザーが指定した住所の地図を表示します。これには、デフォルトのデータ型 "string." というユーザー設定 loc が含まれています。ガジェットを実行する場合、ユーザーは loc のアドレスを入力し、文字列として GClientGeocoder getLatLng メソッドに渡されます。getLatLng メソッドは、指定された住所をジオコーディングするリクエストを Google のサーバーに送信し、指定されたコールバック関数(この例では showMap)を GLatLng ポイントで呼び出します。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Map of __UP_loc__" height="300"
    author="Jane Smith"
    author_email="xxx@google.com" />
  <UserPref name="loc"
    display_name="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());
    var geocoder = new GClientGeocoder();
    geocoder.getLatLng(prefs.getString('loc'), showMap)

    function showMap(point) {
      if (point!=null) {
        map.centerAndZoom(point, 6);
      }
    };
    </script>
  ]]>
  </Content>
</Module>

状態の保存

一般的には、ユーザーが編集ボックスを使用してユーザー設定を明示的に設定できるようにします。しかし、ユーザーが直接参加することなく、プログラムでユーザー設定の値を設定しておくと便利な場合があります。たとえば、ゲーム ガジェットでは、ユーザーの最高スコアを永続的に保存するようにします。これを行うには、プログラムで「high_score"」の設定値を設定します。

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

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

現在のところ、設定サイズは URL 制限(2K)によって制限されています。

次のサンプル ガジェットは 2 つのボタンで構成されています。1 つはカウンタの値をインクリメントするボタン、もう 1 つはカウンタの値を 0 にリセットするボタンです。この例では、「ショップ カウンタ」がユーザーの好みです。データ型は 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 ブロックでは必要ありません。CDATA ブロックでエスケープすると、誤った出力が生成されます。

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

ログインまたは Cookie が必要なガジェットの作成

Microsoft Internet Explorer と Apple Safari のデフォルトのプライバシー ポリシーでは、サードパーティのサイトで Cookie を設定することはできません。一部の ガジェットが正しく動作しないことがあります。特に、ログインに Cookie を使用するサイトは、iframe ページの iframe 内では正しく機能しない可能性があります。考えられるソリューションは次のとおりです。

  • Cookie ではなく URL に認証情報などのパラメータを渡します。1 つの警告: この方法を選択する場合は、これらの URL パラメータを HTTP 参照フィールド内の他のウェブサイトに漏洩しないように注意してください。
  • OAuth を使用します。ガジェット API は、OAuth プロキシと呼ばれる機能をサポートしています。これにより、ガジェットは、ユーザーのアカウントに関連付けられているプライベート データを保存している別のウェブサイトに安全に接続できます。OAuth は、限定公開データのアカウント所有者が、別のアプリケーションにデータへのアクセスを許可するようウェブサイトに伝えるための標準手法です。OAuth プロキシは、ガジェットが OAuth 標準をより簡単に使用できるように設計されています。
  • P3P ヘッダーを記述する。サイトのプライバシー ポリシーによっては、Internet Explorer(ただし Safari は不可)がサイトからのサードパーティ Cookie を読み取ることを許可する P3P ヘッダーを作成できます。PHP を使用していて、ヘッダーを設定する場合は、PHP ページの上部にあるコード スニペットを使用できます。
<?php
  header("P3P: CP=\"CAO PSA OUR\"");
?> 

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

サイトで見出しを使用できる場合、プライバシー ポリシーをよく確認する必要があります。弁護士に確認することをおすすめします。

  • JavaScript でユーザーに指示する。手順と認証ロジックを統合することもできます。Cookie がブロックされていることがわかった場合は、プライバシー設定を下げてみるか、別のウェブブラウザをお試しいただくようお客様に伝えます。たとえば、次のようなメッセージを表示できます。

お使いのブラウザは、構成されているこのサイトと互換性がありません。Microsoft Internet Explorer を使用している場合は、[ツールとオプション] を選択してセキュリティ設定を変更できます。[プライバシー] タブを開き、[詳細設定] をクリックして、[自動 Cookie 処理をオーバーライドする] をオンにします。[サードパーティの Cookie] で [同意する] をクリックします。 Firefox など別のウェブブラウザをお試しいただくこともできます。

  • ガジェットが機密性の高いプライベート ユーザーデータにアクセスする場合は、ロックされたドメイン機能を使用することをおすすめします。

トップへ戻る