http://www.spicebird.com/content/chat-screen
开发基础
本文档介绍了小工具开发过程中的基本概念和任务。有关使用小工具 API 的简介,请参阅使用入门 。
目录
选择内容类型
当您开发新的小工具时,最初的决策之一是使用哪种内容类型。例如:
<Content type="html">
内容类型确定:
- 作为小工具作者,哪些 API 功能对您可用。
- 如何渲染小工具。
- 部署小工具的位置。
下表介绍了可用内容类型以及何时应使用这些内容类型:
内容类型 | 说明 | 何时使用 |
---|---|---|
html | 使用 html 内容类型时,通常所有内容都驻留在小工具规范中。type="html" 小工具包含 HTML,可能带有嵌入的 JavaScript、Flash、ActiveX 或其他浏览器对象。此为默认类型。 | 最灵活、通用的内容类型为 html 。当有疑惑时,请选择 html 内容类型。 |
url | 使用 url 内容类型时,存在于远程网页上的小工具内容将以小工具规范中的网址引用。远程网页是所有 HTML 标记和 JavaScript 驻留的地方。您不能将任何 HTML 标记或 JavaScript 代码置于小工具规范中。 | type="url" 内容类型当前不完全受 gadgets.* 或 OpenSocial API 的支持。如果您想使用带有小工具 JavaScript 库的 type="url" 内容类型,请使用传统小工具 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 部分中唯一识别的分隔符为结束 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
内容类型时,假设与此小工具的用户界面和编程逻辑相关的所有信息均驻留在此网址引用的文件中。您不能将任何 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()
可以用于代理内容。对于商业开发的小工具,我们建议只创建一个新的小页面,然后使用type="url"
指向它。
使用 Userpref 数据类型
在小工具规范中,每个用户使用偏好 都有一个数据类型。datatype
是一个可选字符串,其指定属性的数据类型。datatype
的可能值为 string
、bool
、enum
、hidden
(用户不可编辑的非可见字符串)、list
,以及 location
(对于基于 Google 地图的小工具)。默认数据类型为 string
。
请参阅参考以获得有关用户参考数据类型 的详情。
本部分介绍了两个更专用的数据类型:list
和 location
。您可以找到有关如何在整个文档中使用其他数据类型(例如 enum
、hidden
和 bool
)的实例。
使用 list 数据类型
具 有 list 数据类型的用户使用偏好是一组在运行时由用户动态提供的值。当用户向用户使用偏好编辑框中键入值时,这些值将被添加到列表中。在运行时此列表可以通过编程 方式由小工具进行访问,就像任何其他用户使用偏好一样。可以在想要允许用户动态提供值的任意列表时随时使用 list 数据类型。例如,天气小工具可以允许用户输入邮政编码列表。
您可以通过使用 datatype="list"
声明 userpref 具有 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" defaultvalue="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 Maps 的小工具可以使用 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.lat
和x.long
是空字符串。 - 如果 x 无法进行地理编码(表示无效位置),
x.lat
和x.long
为 0.0。
早期版本的小工具 API 不允许指定 location 类型的 default_value
。现在情况已经改变。
保存状态
用户普遍都可以使用编辑框明确地设置其用户使用偏好。但有时通过编程方式设置用户使用偏好的值(用户不直接参与)很有用。例如,对于游戏小工具,您可能想要永久地存储用户的最高分数。您可以通过以编程方式设置“high_score”用户使用偏好来实现这一目标。
要使用 setprefs
功能,您的小工具应包括以下内容:
<Require feature="setprefs"/>
标签(位于<ModulePrefs>
下),用于通知小工具加载setprefs
库。- 您想要通过编程方式设置并永久存储的 userpref 的值。通常,您将 userpref 的数据类型设置为
hidden
。 - 对于您要保存其值的 userpref 调用 JavaScript 函数
set()
。
请注意,使用偏好大小目前受 URL 限制,大小为 2K。
以下示例小工具由两个按钮组成:一个按钮可以增加计数器的值,另一个按钮可以将计数器的值重设为 0。在此实例中,“计数器”是用户使用偏好。其数据类型为 hidden
,这意味着不允许用户直接修改其值。
以下是小工具规范:
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Setprefs New"> <Require feature="opensocial-0.7"/> <Require feature="setprefs" /> </ModulePrefs> <UserPref name="counter" defaultvalue="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 符号实体。此处是受支持的特殊字符列表:
字符 | 转义代码 |
---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
例如:
- 错误:
href="http://www.foo.com/bar?x=a&y=b"
- 正确:
href="http://www.foo.com/bar?x=a
&y=b"
- 错误:
description="this is a "sexy" gadget"
- 正确:
description="this is a "sexy" gadget"
请注意,CDATA 块中无需此类转义。但是,在 CDATA 块中进行转义仍然是一种好做法。
在 JavaScript 代码中,您可以使用 _hesc(str)
函数返回 HTML 字符串 str
以及下列已转义的字符: <>'".
编写需要登录或 Cookie 的小工具
Microsoft Internet Explorer 和 Apple Safari 的默认隐私政策不允许第三方站点设置 Cookie。因此,某些小工具可能运行不正常。特别地,使用 Cookie 登录的站点在 iGoogle 页面中的 iframe 中可能运行不正常。此处是可能的解决方案:
- 使用 URL 参数(而不是 Cookie)。例如,Orkut 生日小工具 通过 URL 传递验证凭证。警告:如果您选择该方式,请注意不要将这些 URL 参数泄露到 HTTP 下线域中的其他网站。
- 编写 P3P 标题。根据您站点的隐私政策,您可能能够编写 P3P 标题,使 Internet Explorer(但非 Safari)能够从您的站点中读取第三方 Cookie。如果您使用 PHP 且想要设置标题,则可以使用位于 PHP 页面顶部的该代码段:
<?php header("P3P: CP=\"CAO PSA OUR\""); ?>