Google Gadget Scaffolding

Last modified by Thomas Mortagne on 2021/03/18 11:28

cogShow how to build a Google gadget that can be installed in any iGoogle gadget container
TypeSnippet
Category
Developed by

Jerome

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1

Description

Note that it supports the token-based authentication mechanism.

Code

The gadget (GadgetCode.Gadget)

This document will provide the gadget to your gadget container. It does not necessarily needs to be hosted on your wiki instance, but well... it's easy this way emoticon_wink If hosted on your wiki instance, the final URL of the gadget (that you will provide to the gadget container) will look like this : http://yourserver/xwiki/bin/view/GadgetCode/Gadget?xpage=plain. Remember to give the view right to XWikiGuest for this page, or your container will complain not being allowed to access it (401). You may also want to include this code from another page (using the includeInContext macro), in order to have a nicer URL (like http://yourserver/xwiki/bin/view/Gadget/) and a separation between the code and the page exposed (including its rights). This is up to you, really !

{pre }
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="My XWiki Gadget">
  <Require feature="dynamic-height"/>
</ModulePrefs>
<UserPref name="server"
   display_name="XWiki Server URL"
   datatype="string" />
<UserPref name="username"
   display_name="Username"
   datatype="string" />
<UserPref name="token"
   display_name="Authorization Token"
   datatype="string" />
<Content type="html">
 <![CDATA[
  <div id="content">
  </div>
  <script type="text/javascript">
 var prefs = new gadgets.Prefs();
 function doRequest() {    
  var params = {};  
  params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
  var args = "xpage=plain&token=" + prefs.getString("token") + "&username=" + prefs.getString("username");
  var url = prefs.getString("server") + $xwiki.getURL("GadgetCode.Service","view") + "? + args;
  gadgets.io.makeRequest(url, responseHandler, params);
 };
 function responseHandler(obj) {  
  document.getElementById('content').innerHTML = obj.text;
  gadgets.window.adjustHeight();
 };
 gadgets.util.registerOnLoadHandler(doRequest);
  </script>
  ]]>

</Content>
</Module>
{/pre }

The back-end service (GadgetCode.Service)

The code in this service page will handle the asynchronous requests made by the gadget itself. It will return HTML to display inside the gadget upon response. In this example, we will return a list of pages the gadget user has created and that has been recently modified. Replace the code between the placeholders to fit your specific gadget purpose.

#**
* Service for handling a google gadget asynchronous requests.
* Authentication is token-based. The token is a hashcode of the concatenated
* username and password of one use.)
*
* @programming
* @internalapi to retrieve the user doc, because we are called as XWikiGuest.
* @ajaxservice called by a google gadget container.
*#
{pre }
#set($token = $request.token)
#set($username = $request.username)
#if($token && $username)
 #set($userdoc=$xwiki.xWiki.getDocument("XWiki.${username}",$context.context))
 #set($password=$userdoc.getObject('XWiki.XWikiUsers').getStringValue('password'))
 #set($validToken="${userdoc.fullName}${password}")
 #set($validToken=$validToken.hashCode())
 #if($validToken == $token)
$context.context.setUser("XWiki.${username}") ## set to valid user
  ## BEGIN Placeholder for the service logic code starts here. Replace the code below, until END, by yours
   #set($hql = "where doc.creator='$context.user' order by doc.date desc")
  <h2>Latests modifications on the pages I've created :</h2>
  <ul>
   #foreach($docName in $xwiki.searchDocuments($hql, 10, 0))
    #set($tDoc=$xwiki.getDocument($docName))
   <li><a href=$tDoc.getExternalURL() target="_new">$tDoc.fullName</a></li>
   #end
  </ul>
  ## END Placeholder for the service logic code starts here
 #else ## invalid token
Invalid combination of username and token.
 #end
#else
Request parameters are wrong.
#end
{/pre }

The token provider (GadgetCode.TokenProvider)

Finally, this page will be useful to provide the wiki users their authentication token. As for the gadget page, you might consider including this code from an other page, to have a nice separation between the logic and the UI.

#set($userdoc = $xwiki.getDocument($context.user))
#set($token = "${userdoc.fullName}${userdoc.getObject('XWiki.XWikiUsers').getProperty('password').value}")
#set($token = $token.hashCode())
#info("Token for $context.user : $token")

Google Gadget development

See http://code.google.com/apis/igoogle/ for more information. In development mode, you might want to use the gadget developer sandbox. Remember to uncheck the "Cached" checkbox to see your changes when you refresh your iGoogle page.

Result

Hereunder is the result as you can observe it in the iGoogle gadget container:

Settings view

XWikiGoogleGadgetSettings.png

Result view

TBD. (iGoogle gadget sandbox does not work properly today, see this thread)

Get Connected