本文档介绍了小工具开发过程中的基本概念和任务。有关使用小工具 API 的简介,请参阅“使用入门”。
当您开发新的小工具时,最初的决策之一是使用哪种 Content 类型。例如:
<Content type="html">
Content 类型决定:
下表介绍了可用 Content 类型以及何时应使用这些 Content 类型:
| Content 类型 | 说明 | 何时使用 |
|---|---|---|
html |
使用 html Content 类型时,小工具的主要内容都会放在 Content 标记中。type="html" 小工具包含 HTML,可能带有嵌入的 JavaScript、Flash、ActiveX 或其他浏览器对象。此为默认类型。 |
最灵活、通用的 Content 类型为 html。当有疑惑时,请选择 html Content 类型。 |
url |
使用 url Content 类型时,小工具将会在其 Content 标记中引用指定的网页的 url。该远程网页是所有 HTML 标记和 JavaScript 所放的地方。您不能将任何 HTML 标记或 JavaScript 代码置于小工具规范本身中。 |
type="url" Content 类型当前不完全受 gadgets.* 或 OpenSocial API 的支持。如果您想使用带有小工具 JavaScript 库的 type="url" Content 类型,请使用传统的小工具 API。 |
使用 html Content 类型时,小工具的主要代码都会放在 Content 标记中。这包括小工具 XML,以及任何 HTML 标记和 JavaScript。本开发人员指南中几乎所有的示例都使用 html Content 类型。该类型是最灵活通用的类型,除非您在编写有特殊要求的小工具,否则通常应当选择该类型。
以下示例是 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 Content 类型的小工具还可以引用外部 JavaScript 文件:
<Module>
<ModulePrefs ... />
<Content type="html"><![CDATA[
<script src="http://www.example.com/gadgets/clock/clock.js" type="text/javascript"></script>
]]></Content>
</Module>
当小工具具有 type="url" Content 类型时,href= 属性会提供网址,并且小工具规范中的其他任何内容都会被忽略。具有 url Content 类型时,假设与此小工具的用户界面和编程逻辑相关的所有信息均放在此网址引用的文件中。不能将任何 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()。makeRequest() 可以用于代理内容。对于商业开发的小工具,建议只创建一个新的小页面,然后使用 type="url" 指向它。在小工具规范中,每个用户使用偏好都有一个数据类型。datatype 是一个可选字符串,可指定属性的数据类型。datatype 的值可以为 string、bool、enum、hidden(用户不可编辑的非可见字符串)、list,以及 location(用于基于 Google 地图的小工具)。默认数据类型为 string。
请参阅参考以获得有关用户使用偏好数据类型的详细信息。
本部分介绍了两个更专用的数据类型:list 和 location。您可以找到有关如何在整个文档中使用其他数据类型(例如 enum、hidden 和 bool)的示例。
具有 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" 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 地图的小工具可以使用 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.lat 和 x.long 是空字符串。x.lat 和 x.long 为 0.0。早期版本的小工具 API 不允许为 location 类型指定 default_value。现在情况已经改变。
用户普遍都可以使用编辑框明确地设置其用户使用偏好。但有时通过编程方式设置用户使用偏好的值(用户不直接参与)很有用。例如,对于游戏小工具,您可能想要永久地存储用户的最高分数。您可以通过以编程方式设置“high_score”用户使用偏好来实现这一目的。
要使用 setprefs 功能,您的小工具应包括以下内容:
<Require feature="setprefs"/> 标签(位于 <ModulePrefs> 下),用于通知小工具加载 setprefs 库。hidden。 set() 的调用,针对您要保存其值的 userpref。请注意,使用偏好大小目前受网址限制,大小为 2K。
以下示例小工具由两个按钮组成:一个按钮可以增加计数器的值,另一个按钮可以将计数器的值重设为 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 符号实体。以下是受支持的特殊字符列表:
| 字符 | 转义代码 |
|---|---|
& |
& |
< |
< |
> |
> |
" |
" |
' |
' |
例如:
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,其中以下字符已转义: <>'".
Microsoft Internet Explorer 和 Apple Safari 的默认隐私政策不允许第三方站点设置 Cookie。因此,某些小工具可能运行不正常。特别是使用 Cookie 登录的站点在 iGoogle 页面中的 iframe 中可能运行不正常。此处是可能的解决方案:
<?php header("P3P: CP=\"CAO PSA OUR\""); ?>这必须在页面上显示任何输出之前调用。
您需要仔细检查您的隐私政策,以了解您的站点可以使用哪些标题。我们建议您与代理人一起检查。
根据配置,您的浏览器与该站点不兼容。如果您使用的是 Microsoft Internet Explorer,则可以通过选择“工具”>“Internet 选项”更改您的安全设置。打开“隐私”标签,点击“高级”,然后选中“替代自动 cookie 处理”。在“第三方 Cookie”下,点击“接受”。 此外,您可以尝试其他网络浏览器,例如 Firefox。