Writing Google Gadgets – A Tutorial – Part 01
- By Samisa Abeysinghe
- |
- 19 Nov, 2011
Curated on 08th March 2012
Writing Google Gadgets – A Tutorial – Part 01
We will start small and simple and then gradually move onto
more useful and advanced features in these tutorials. Along the way, we will
evolve a gadget from ground up to a user configurable, comprehensive gadget. We
will use WSO2 Gadget Server as the hosting environment to test the gadget,
along the way. WSO2 Gadget
Server adheres to the Google Gadget Specification [1], thus, allows hosting
gadgets written for Google gadget container.
Writing Google Gadgets - A tutorial - Part 01
Basic Gadget Example - Hello Gadget
Pulling Information from the Web into a Gadget
Writing Google Gadgets – A tutorial – Part 02
Processing Fetched HTML with JavaScript
Using TEXT vs DOM Content Type when Working with HTML
Using External JavaScript Libraries
Writing Google Gadgets - A tutorial - Part 03
Using enum Data Type as an Options List
Integer Settings with String Data Type
Setting Preferences from Within the Gadget
Writing Google Gadgets – A tutorial – Part 04
Versatility of Google Gadgets as a Presentation Instrument
Google Gadgets Basics
Anatomy of a Gadget
The source code of a gadget is written in XML. In other words, a gadget is an XML document. The root element of a gadget is <Module>.
And a gadget consists of three main sections:
- Gadget Preferences: Specifies characteristics of the gadget. Wrapped with <ModulePrefs> XML element. Mandatory.
- User Preferences: Defines controls that allow users to specify settings for the gadget. Wrapped with <UserPrefs> XML element. Optional.
- Content Section: Specifies the content of the gadget, often using HTML and JavaScript programming logic. Wrapped with <Content> XML element. Mandatory.
The following diagram portrays the overall gadget structure, which consists of the three main sections described above.
You can find more information on the anatomy of a gadget on Google gadget basics documentation page [2].
Basic Gadget Example – Hello Gadget
Here is a sample gadget that demonstrates the three elements of a gadget.
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Hello Example" /> <UserPref name="Name" display_name="Your Name" default_value="World" /> <Content type="html"> <![CDATA[ Hello, <span id="nameSpan"> Name goes here </span> <script type="text/javascript"> var prefs = new gadgets.Prefs(); document.getElementById('nameSpan').innerHTML = prefs.getString("Name"); </script> ! ]]> </Content> </Module>
In this gadget, we set the gadget title in the gadget preference section on line 3. The title is "Hello Example".
On line 4, we set a user preference with the preference name being "Name", display name being "Your Name" and default value being "World".
In the content section, we print a greeting message, based on the value set by the user for Name preference field.
We have a span with the ID "nameSpan", preceded by "Hello," on line 7.
From lines 8 to 11 we have some JavaScript logic to pick the name
preference value, and set the "nameSpan" with the preference value.
As the default value for "Name" is "World", the gadget would greet with "Hello, World!" when it loads initially, and if the user sets the name preference, would greet accordingly.
The following figure shows how the gadget behaves in action. This simple gadget is capable of picking the user settings and greets the user accordingly. Later in this tutorial series, we will explore in more detail, how to make use of user preferences and make gadgets configurable.
To try this gadget with WSO2 Gadget Server, you can upload the gadget to the gadget repository, on Gadget Server management console, by going to
Home > Manage Gadget Server > Gadget Repository > Add / Modify Gadget
You can find documentation on uploading a gadget to gadget repository [3], adding the gadget to the portal [4] and if you are a newbie to WSO2 gadget server – how to install [5] on WSO2 developer portal.
Pulling Information from the Web into a Gadget
Now that we know the basic structure of a gadget, let’s move on to a more useful use case.
One of the common use cases is to pull information from the Web and display information within a gadget.
Often we might want to extract some useful information from the Web URL, and display on the gadget, rather than showing the Web data as they are.
However, before diving into the complex case, let’s look at the simple case of pulling a page and displaying as it is.
The simplest way to fetch content from a URL and display is to set the <Content> elements "type" attribute to "url" and provide
the URL location with the "href" attribute. Following is a sample where WSO2 mailing list information is fetched from MarkMail [6] and displayed on a gadget.
<?xml version="1.0" encoding="UTF-8"?> <Module> <ModulePrefs title="MarkMail WSO2 Lists"> </ModulePrefs> <Content type="url" href="https://wso2.markmail.org/search/?q="/> </Module>
This gadget, once deployed with WSO2 Gadget Server will render like following.
The gadget renders successfully, but there is a problem. The content is clipped, and there is no way to see the full content.
We can try setting "height" attribute and "scrolling" attribute on the content element:
<ModulePrefs title="MarkMail WSO2 Lists" height="350" scrolling="true" />
Now the height setting has worked, and we can see the graph on the top left hand side of the original page within the gadget. However, we do not still see scrolling. This is due to an issue [7] in the Apache Shinding engine that is used as the core engine of WSO2 Gadget Server. Hopefully this would be fixed in the near future.
A workaround would be to use larger height, and view the gadget in the maximized mode. Yet, since the main objective is not to load the page as it is, let’s move on and look at more useful forms of this gadget.
Google gadget API documentation on URL content type [8] might provide more details on URL content type, if you are interested in.
The "Hello" gadget given earlier in this tutorial, used <Content> element's "type" attribute as "html".
<Content type="html">
This content type is what we have to use when we want to pull information from the Web, process it, and extract information that we need and display within the gadget, using various visualization forms that we need.
One point that must be kept in mind when using "html" content type gadget, is that, it must include a CDATA section, within
<Content type="html"> <![CDATA[ Hello, <span id="nameSpan"/> <script type="text/javascript"> var prefs = new gadgets.Prefs(); document.getElementById('nameSpan').innerHTML = prefs.getString("Name"); </script> ! ]]> </Content>
Another important aspect to note is that with URL content type gadgets, the gadget engine triggers the pulling of content from the URL given. However, when we use HTML content type gadgets, we have to write our own logic, to pull the Web URL into the gadget. Though this might sound complex, there are built-in mechanisms and APIs that we can use to pull a URL content and this also yields flexibility to make our lives easy, when processing the pulled content.
Google gadget API documentation on HTML content type [9] might provide more details on HTML content type, if you are interested in.
Pulling Information into a Gadget with makeRequest
Google gadget API provides a call named "makeRequest" [10] to fetch content from a URL. Let’s look at a sample, where we fetch WSO2 Carbon and Stratos SVN commits data from MarkMail and display them content in the gadget.
This gadget, has a
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="WSO2 Carbon and Stratos SVN Data from MarkMail" /> <Content type="html"> <![CDATA[ <div id="contentDiv"></div> <script type="text/javascript"> function getHtml() { var parameters = {}; parameters[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT; var url = "https://markmail.org/browse/org.wso2.carbon-commits"; gadgets.io.makeRequest(url, processResponse, parameters); }; function processResponse(response) { document.getElementById('contentDiv').innerHTML = response.text; }; gadgets.util.registerOnLoadHandler(getHtml); </script> ]]> </Content> </Module>
The data fetching and filling in the div is done using JavaScript logic. There are two functions, one that gets the HTML form the URL and one that process the response.
On line 21 we register the "getHtml" function, to be triggered on the loading of the gadget.
Within "getHtml", on line 12, we set the request parameter saying that content type is TEXT, meaning that we would expect to deal with the fetched content in text format.
On line 14, we make the request to fetch, with the mailing list URL, the name of the callback function into which "makeRequest" will feed the content, and request parameters.
When "makeRequest" receives the fetched content, "processResponse" will be called with the response object, and the text field will have the received HTML as text.
So we can use that text and set the
Here is the output from this gadget.
So it works. But yet, the content is clipped. We have hit the scrolling problem again? Not really, with a preference setting and an API call we can fix this.
Dynamic Height with Google Gadgets
The fix to clipping of the content can is to adjust the height of the gadget, dynamically, when content gets updated. For this, we can use the combination of "dynamic-height" feature and a call to "adjustHeight" API when the content changes.
So there are two changes to be made to the gadget.
<ModulePrefs title="WSO2 Carbon and Stratos SVN Data from MarkMail"> <Require feature="dynamic-height" /> </ModulePrefs>
Update the <ModulePrefs> to require "dynamic-height" feature.
function processResponse(response) { document.getElementById('contentDiv').innerHTML = response.text; gadgets.window.adjustHeight(); };
Update "precessReponse" JavaScript function to call "adjustHeight", right after setting the <div> element’s content.
And we can see the content in full within the gadget.
More information on dynamic height settings can be found in Google gadget documentation [11].
This gadget still display the content from the URL as it is. But we might want to process this data and present this data in a more appealing format,
like using a graph. MarkMail of course display data using a graph on its home page, but the intention here is to learn how to write better gadgets and
not re-do what MarkMail is already doing.
In the next part of this tutorial, we will explore how to use a third party JavaScript library and content from mark mail, to come up with more colorful gadgets.
And in the process, will dig more into the Google gadget API usage, tips and tricks.
References
[1] href="https://code.google.com/apis/gadgets/docs/spec.html">Google Gadget Specification
[2]
href="https://code.google.com/apis/gadgets/docs/basic.html#Anatomy">Anatomy of a
Google gadget
[3]
href="https://wso2.org/project/gadget-server/documentation/gadget_repo.html">Adding
Gadgets to Gadget Repository
[4]
href="https://wso2.org/project/gadget-server/1.4.2/docs/add_gadgets.html#repo_add">Adding
Gadgets to the Portal
[5]
href="https://wso2.org/project/gadget-server/1.4.2/docs/installation_guide.html">Installation
Guide
[6] MarkMail
WSO2 mailing lists
[7]
href="https://issues.apache.org/jira/browse/SHINDIG-180">Apache Shinding gadget
scrolling issue
[8]
href="https://code.google.com/apis/gadgets/docs/fundamentals.html#URL">Google
gadget API documentation on URL content type
[9]
href="https://code.google.com/apis/gadgets/docs/fundamentals.html#HTML">Google
gadget API documentation on HTML content type
[10]
href="https://code.google.com/apis/gadgets/docs/reference/#gadgets.io.makeRequest">gadgets.io.makeRequest
API
[11]
href="https://code.google.com/apis/gadgets/docs/ui.html#Dyn_Height">Google
gadget API documentation on dynamic height
This brings us to the end of this four part tutorial. Please feel free to provide us the feedback, and help us improve the content.
Please refer to the table of contents section to find out about the other parts of this tutorial.