This document explains how to use the publish-subscribe ("pubsub") framework to pass messages from one gadget to another. This feature is deprecated and is unsupported.
Contents
Overview
The publish-subscribe framework allows publisher gadgets on iGoogle to communicate changes to subscriber gadgets that have declared interest in those changes.
Note: You can use the publish-subscribe framework for type="html"
gadgets.
This feature does not support
type="url"
gadgets. To use pubsub, your
gadgets must be running on iGoogle. The pubsub feature won't work
for syndicated
gadgets.
Here are the major concepts involved in gadget-to-gadget communication:
- Publisher. Publishers are gadgets that inform one or more subscribers that a particular userpref value has changed. A publisher gadget can have many subscriber gadgets. It does not need to know the number or identities of its subscriber gadgets.
- Subscriber. Subscribers are gadgets that declare their interest in knowing when the value of a particular userpref has changed.
- Message. A message is a string containing new userpref values that the publisher sends to subscribers.
- Channel. A channel is a known, named
place for publishing messages of a certain type.The pubsub
framework enforces a set of predefined data policies to
ensure that all messages published on a particular channel
share the same type and have the same data structure.
For example, the channel
finance_symbol
could be used for publishing Google Finance symbols, while the channelslat
andlong
could be used for publishing geographic positioning information.
This table lists the channel names that are currently supported. As new channel names are added, they will be announced on the Developer Forum. If you want to propose new channel names, you can do so on the Developer Forum.
Channel Name | Description |
---|---|
test000 - test100 |
Test channels to be used for development. You can
use the test channel names test000
through test100 . |
rawquery |
Either the literal text of the user's query, or keywords used to match a context. |
finance_portfolio |
Stock watchlist/portfolio. |
finance_symbol |
Stock symbol. |
finance_symbol_quote |
Stock market data for a symbol. |
lat |
Latitude (in microdegrees) for geographical targeting. |
long |
Longitude (in microdegrees) for geographical targeting. |
How It Works
You implement gadget-to-gadget communication through "userprefs binding". With userprefs binding, the userprefs in the subscriber gadget map to the userprefs in the publisher gadget. You define this mapping in the XML portion of your gadget specs. For example:
// Publisher gadget userpref definition <UserPref name="test000" display_name="Message" default_value="Bonjour Monde" publish="true" /> // Subscriber gadget userpref definition
<UserPref name="test000" display_name="Message" default_value="Hello World" listen="true" on_change="updateMessage" />
The above snippet illustrates how to define userprefs for the pubsub feature:
- The publisher gadget and the subscriber gadget must
have at least one userpref with the same name. In this example,
it is
test000
. This name is also used as the name of the channel that passes messages from the publisher to the subscriber. - The publisher gadget includes
publish="true"
in the userpref definition. This states that the userpref is published on a channel of the same name. - The subscriber gadget includes
listen="true"
in the userpref definition. This states that the subscriber gadget wishes to be notified when the userpref value changes in the publisher gadget. - The subscriber gadget includes
on_change="updateMessage"
in the userpref definition. This optional attribute specifies the name of a callback function that is invoked when the subscriber gadget receives notification that the userpref value has changed in the publisher gadget. Note that the callback function cannot take parameters.
The following example shows the publisher and subscriber gadgets that include these userpref definitions. This is the sequence of events in the running gadgets:
Step 1. The publisher and subscriber gadgets run in the container page for the first time.
Initially, each gadget displays its own default value
for the userpref test000
.
For the publisher gadget, the value is "Bonjour Monde".
For the subscriber gadget, the value is "Hello World".

Step 2. The user enters a new value in the publisher gadget's Message text field, and clicks Update Message.
This invokes the publisher function updateValue()
,
which includes a call to prefs.set()
.
The prefs.set()
call has the effect of publishing
the new value to the channel.
As described in Saving
State, the _IG_Prefs
function set()
causes
userpref values to be saved persistently. If you navigate
away from your browser window and return, the gadgets
still have the last value you set. Another thing
that might not be obvious is that if you change the value
of the publisher's test000
userpref locally,
in the userprefs edit
box, the change does not
get published to the channel, and the subscriber's test000
userpref
is not updated. In other words, you must use the _IG_Prefs
set()
function
to explicitly publish the change to the channel.
Step 3. The publisher tells subscribers that the value has changed.
Step 4. The subscriber responds by invoking its callback
function updateMessage()
,
which causes the subscriber gadget to refresh its display
to reflect test000
's
new value.
The callback
function updateMessage()
is specified
by the
on_change
attribute in the subscriber's test000
userpref
definition. Using the on_change
attribute to
specify a callback function is optional. However, if you want
the subscriber to immediately respond (typically by refreshing
its display) when a value changes, using on_change
to
specify a callback function is the way to do it.
After the user enters a new value in the publisher's Message field and clicks Update Message, the publisher and subscriber gadgets display the same message:

Basic Example
This section shows the gadget specs for the publisher and subscriber
gadgets described above. You may notice that the gadget specs
don't include the statements <Require feature="pubsub" />
or <Require
feature="setprefs" />
to load the pubsub
and
setprefs
libraries, even though the gadgets use
them. This is because for the pubsub feature, iGoogle automatically
includes these libraries in the gadget context.
Here is the publisher gadget spec:
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Publisher Gadget 01" height="150" /> <UserPref name="test000" display_name="Message" default_value="Bonjour Monde" publish="true" /> <Content type="html"> <![CDATA[ <br/> My Message <br/><br/> <table> <tr> <td> Message: </td> <td> <input type="text" id="msg" name="msg" value=""> </td> <td> <input type="button" name="butUpdateMsg" name="butUpdateMsg" value="Update Message" onclick="updateValue()"> </td> </tr> </table> <script type="text/javascript"> // This publisher gadget updates the value for the test000 userpref when users click the "Update Message" // button. function updateValue() { var newMsg = _gel("msg").value; prefs.set("test000", newMsg); } // Gets and displays the publisher gadget's local test000 userpref. New userpref value is not published // unless user invokes updateMsg() by clicking button. var prefs = new _IG_Prefs(__MODULE_ID__); var str = prefs.getString("test000"); _gel("msg").value = str; </script> ]]> </Content> </Module>
Here is the subscriber gadget spec:
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Subscriber Gadget 01" height="150" scrolling="true"/> <UserPref name="test000" display_name="Message" default_value="Hello World" listen="true" on_change="updateMessage" /> <Content type="html"> <![CDATA[ <div id="mydiv"></div> <script type="text/javascript"> // When the message value is updated in the publishing gadget, // the test000 userpref is updated. Refresh the message in the // div to display the new value. function updateMessage() { div.innerHTML = "<h1>" + prefs.getString("test000") + "</h1>"; } // Gets and displays the subscriber gadget's local test000 userpref value. var prefs = new _IG_Prefs(__MODULE_ID__); var div = _gel("mydiv"); div.innerHTML = "<h1>" + prefs.getString("test000") + "</h1>"; </script> ]]> </Content> </Module>
Bundling Updates
"Bundling" allows you to group a set of changes into a single transaction. It allows the publisher gadget to pass updated values as a unit to subscribers.
The following sections describe the publisher and subscriber requirements for bundling updates.
Publisher Requirements
In the most common case, you publish bundled userprefs by specifying
the group
attribute
for all userprefs in the same bundle, and giving the attribute the
same value for all userprefs. You then call the _IG_Prefs
set()
function.
The publisher gadget call to the set()
function typically
includes all userprefs of the bundle, but it does not have to. If a
subset of userprefs in a group are specified in the call to the set()
function,
all userprefs with the same group get published as a bundle. Any userprefs
that are not specified in the set()
call
are published with old values, whereas the userprefs specified in the
set()
call are published with new values.
For example:
<UserPref name="lat" display_name="Latitude:" publish="true" group="geoinfo" />
<UserPref name="long" display_name="Longitude:" publish="true" group="geoinfo" /> ... var prefs = new _IG_Prefs(__MODULE_ID__); prefs.set("lat", "45.8");
In this example, both the lat
and long
userprefs
get published as a bundle, with lat
having the new
value ("45.8.") and long
having the old value.
There is a second way of publishing bundled userprefs. Userpref
updates are published as a bundle if the userprefs are marked with publish="true"
and
they get updated in a single call to _IG_Prefs
set()
function.
For example:
<UserPref name="lat" display_name="Latitude:" publish="true" /> <UserPref name="long" display_name="Longitude:" publish="true" /> ... var prefs = new _IG_Prefs(__MODULE_ID__); prefs.set("lat", 45.8, "long", 16);
Mixing the two techniques of publishing bundled userprefs is not
recommended. However, for the purpose of explanation, suppose you have
an _IG_Prefs set()
call that includes userprefs with group
attributes and userprefs without group attributes. In that "mixed" scenario,
the set of userprefs that would get published as a bundle would include:
- Any userprefs without group attributes that are included in the
set()
call. - Any userprefs that belong to a group in which at least one group
member is included in the
set()
call.
For example:
<UserPref name="lat" display_name="Latitude:" publish="true" group="geoinfo" /> <UserPref name="long" display_name="Longitude:" publish="true" group="geoinfo" /> <UserPref name="test003" display_name="Locaccuracy:" publish="true" /> ... var prefs = new _IG_Prefs(__MODULE_ID__); prefs.set("lat", "45.8", "test003", "0.89");
In this example, all the userprefs get published as a bundle:
test003
is published even though it does not have a group attribute, because it is specified in theset()
call.-
lat
is published with a new value since it is specified in theset()
call. -
long
is published (with the old value) since it's in the same group aslat
.
Subscriber Requirements
In the subscriber gadget, all
userprefs that have a group attributed specified must also have the
on_change
attribute specified. Also, all userprefs that
have the same group attribute specified must have the same on_change
attribute
value (that is, the same callback function must be invoked for each
userpref). For example:
<UserPref name="lat" display_name="Latitude:" listen="true" on_change="locationChange" group="geoinfo" /> <UserPref name="long" display_name="Longitude:" listen="true" on_change="locationChange" group="geoinfo" />
The locationChange()
function specified by the on_change
attribute
gets invoked only when one or more of the bundled userprefs get updated.
Example: Bundled Updates
In this example, the publisher gadget has text fields where users can specify a latitude and longitude. When users specify a new value and click Update, the subscriber gadget updates its display to show a map that matches the specified longitude and latitude.
Publisher gadget:
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Map Controller" height="150" /> <UserPref name="lat" default_value="37441900" publish="true" group="geoinfo" /> <UserPref name="long" default_value="-122141900" publish="true" group="geoinfo" /> <Content type="html"> <![CDATA[ <br/><br/> <table> <tr> <td> Latitude: </td> <td> <input type="text" id="txtLat" name="txtLat" value=""> </td> </tr> <tr> <td> Longitude: </td> <td> <input type="text" id="txtLong" name="txtLong" value=""> </td> <td> <input type="button" name="butUpdateLoc" name="butUpdateLoc" value="Update" onclick="updateLoc()"> </td> </tr> </table> <script type="text/javascript"> function updateLoc() { var newLat = parseFloat(_gel("txtLat").value) * 1000000; var newLong = parseFloat(_gel("txtLong").value) * 1000000; prefs.set("lat", newLat.toString(), "long", newLong.toString()); } var prefs = new _IG_Prefs(__MODULE_ID__); var lat = prefs.getInt("lat") / 1000000; var long = prefs.getInt("long") / 1000000; _gel("txtLat").value = lat; _gel("txtLong").value = long; </script> ]]> </Content> </Module>
Subscriber gadget:
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Listening Map" height="500" /> <UserPref name="lat" default_value="37441900" listen="true" on_change="updateLocation" group="geoinfo" /> <UserPref name="long" default_value="-122141900" listen="true" on_change="updateLocation" group="geoinfo" /> <Content type="html"> <![CDATA[ <script src="http://maps.google.com/maps?file=api&v=2.x" type="text/javascript"></script> <div id="map" style="width:100%;height:100%"></div> <script type="text/javascript"> function updateLocation() { var newLat = prefs.getInt("lat") / 1000000; var newLong = prefs.getInt("long") / 1000000; map.panTo(new GLatLng(newLat, newLong), 13); } var prefs = new _IG_Prefs(__MODULE_ID__); var lat = prefs.getInt("lat") / 1000000; var long = prefs.getInt("long") / 1000000; var map = new GMap2(_gel("map")); map.setCenter(new GLatLng(lat, long), 13); </script> ]]> </Content> </Module>