Hi all,
I've been working through converting an existing GWT based app into a
Google Gadget that can be hosted in an iGoogle page or on a Google
desktop. Unless I was looking in all the wrong places, I was surprised
to find there wasn't that much information about the end to end
process for doing this. There have been some posts on this newsgroup
and there is a presentation by Didier Gerard at
http://www.slideshare.net/dgirard/javapolis-gwt-gadget-opensocial but
nothing "end to end".
So, having gotten this working, I thought I'd post the steps below in
case they are useful for anyone else and to see if I've headed off in
the wrong direction...
The starting point is the Gadgets documentation at
http://code.google.com/apis/gadgets/docs/dev_guide.html
Then make your existing GWT app look good in a much smaller UI
space :-)
Given that you've already developed your application in GWT, you'll
almost certainly want to define your gadget as type=url i.e. pointing
to your server rather than embedding in the widget html directly. So
your gadget definition will include something like
<Content type="url" href="
http://example.com/gwtgadget/music-
gadget.jsp"/>
Your gadget definition will also include stanzas relating to any
Google Gadgets functionality you want to use. In this example, I want
to use the mini message functionality from iGoogle so the
<ModulePrefs> include
<Require feature="minimessage"/>
The "pointed to" JSP looks pretty much like the landing page of a
normal GWT app i.e. it will define links to style sheets, 3rd party js
libraries etc but it also needs to include code to extract some data.
When the iGoogle page is displayed in the browser, this results in a
call to your server similar to
GET /gwtgadget/music-gadget.jsp?
lang=en&country=us&.lang=en&.country=us&synd=ig&mid=87&ifpctok=4116213266150043456&parent=http://
www.google.com&libs=GoCC2u__rgs/lib/libcore.js,_dWJeD4-864/lib/libminimessage.js&extern_js=/extern_js/f/CgJlbhICdXMrMAU4ACwrMAo4ACwrMBA4ACwrMBI4ACwrMBM4ACw/ZuzVyrMxcg0.js
As per the Gadget documentation at
http://code.google.com/apis/gadgets/docs/fundamentals.html#Libs
you need to extract the libraries and output as <script ...>
statements in you page. So code similar to the following is required
because I don't speak regex if I don't have to :-)
<%
if (request.getParameter("libs") != null) {
String [] libs = request.getParameter("libs").split(",");
for (String script : libs) {
if (script.endsWith("js")) {
%>
<script src="
http://www.google.com/ig/f/<%=script
%>"></script>
<% }
}
}
%>
What the docs don't mention, is that you'll also probably want to
extract the mid (module id) parameter with something like
<%
if (request.getParameter("mid") != null) {
String moduleId = request.getParameter("mid");
%>
<script type="text/javascript">
var __MODULE_ID__ = <%=moduleId%>;
</script>
<%
}
%>
so your output html ends up with something like
...
<script src="
http://www.google.com/ig/f/GoCC2u__rgs/lib/libcore.js"></
script>
<script src="
http://www.google.com/ig/f/_dWJeD4-864/lib/
libminimessage.js"></script>
<script type="text/javascript">
var __MODULE_ID__ = 87;
</script>
...
At which point you should now have your GWT app working as a Google
Gadget in iGoogle / on your Google desktop.
For your GTW compiled JavaScript served from your server to interact
with the Gadget JS served from iGoogle (in this example to set some
text into the mini messages), its seems to me as though JSNI is
needed. So an example might be,
public native static void attachDismissableMessage(String msgText,
String divId) /*-{
var msg = new _IG_MiniMessage(__MODULE_ID__, _gel(divId));
var statusMsg = msg.createDismissibleMessage(msgText);
statusMsg.style.backgroundColor = "white";
statusMsg.style.color = "black";
}-*/;
which allows the GWT code to pass message text and a <div> id to
iGoogle JS. You can also see that the iGoogle API requires the module
id and hence why it needed to be extracted from the initial browser
call. One small implementation note, the IG_MiniMessage(__MODULE_ID__,
_gel(divId)); call is going to look for a <div> id in the DOM so it
needs to be there before the mini message call is made so you probably
don't want to call the above attachDismissableMessage until after your
GWT app has added its widgets to the RootPanel.
One final thing - why bother using the iGoogle JS APIs? For me, with
the little experience I have of this so far, there is not much
currently there in the Gadget JS APIs that couldn't also be done via
GWT code e.g. the mini messages in the above example (perhaps also
using the great gwt-ext library). The preferences stuff is useful to
keep a consistent user experience but I think the real benefit will
come when functionality is added to Shindig based containers. So in
Didier's presentation example there is
<Require feature="opensocial-0.5"/>
and in the future there might be others such as
<Require feature="oauth-x.x"/>
I hope the above is useful to someone else. I'd also be grateful if
others who have done this before have alternate / better suggestions
on how to do the above.
Cheers
Aidan