11 Oct 09

This is a simple to follow tutorial on how to create an extension that other Google Wave users can install and use in their waves. We will create a simple gadget extension that will list some blog names and when the user clicks on a name, the latest posts from the blog selected will be displayed in the wave. Yes, we will create a feed reader to use in Google’s waves :)

Step 1: Create the interface

The first thing we need to do is to wireframe our application. Our gadget should be easy to use and most of the time it will be loaded in less than 500px in width. This is how our application will look like this:

wireframe

The HTML code needed to create the layout above is (File: gadget.php):

<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="scripts.js"></script>
</head>
<body>
<div id="container">
<div id="buttons">
 <a href="javascript:void(0);" onclick="loadFeed('jeez')"><span class='button'>Jeez.eu</span></a>
 <a href="javascript:void(0);" onclick="loadFeed('drupal')"><span class='button'>Drupal</span></a>
 <a href="javascript:void(0);" onclick="loadFeed('wp')"><span class='button'>Wordpress</span></a>
 <a href="javascript:void(0);" onclick="loadFeed('noupe')"><span class='button'>Noupe</span></a>
 <a href="javascript:void(0);" onclick="reloadFeed()"><span class='button'>Reload</span></a>
</div>
<div id="sitelogo"></div>
<div id="feed"></div>
</div>
</body>
</html>

and the CSS (File: styles.css):

body{
 width:500px;
 margin:0 auto;
 position:relative;
}

#container{
 background-color:magenta;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;
 border: 1px solid #000; padding: 10px;
}

#buttons{
 text-align:center;
 height:30px;
 padding:5px;
}

.button{
 padding:8px;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;
 border: 1px solid #000; padding: 10px;
 background-color:white;
 font-family:verdana;
 font-weight:bold;
}

iframe{
 border:0px;
}

#feed,#sitelogo{
 background-color:white;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;
 border: 1px solid #000; padding: 10px;
}

#sitelogo{
 text-align:center;
}

#feed img{
 max-width:120px;
 max-height:120px;
}

a SPAN.button:hover{
 background-color:#000fff;
 color:white;
}

.counter,.title{
 font-weight:bold;
}

.date{
 color:gray;
 font-size:60%;
}
a{
 text-decoration:none;
}

Don’t worry about CSS3 code above. Remember that Google Wave works only with browsers that support (100% or less) CSS3 and HTML5.

Step 2: The behavior

We would like to use AJAX to load each feed in our application but xmlhttprequests don’t work cross domain. So, we will use an iframe to deliver the content . The JavaScript needed to do this is (File: scripts.js):


//This function will return the instance of the element passed
function getVariable(element){
 var element;
 if(document.all){
 var fetchedVar = document.all(element);
 }else{
 var fetchedVar = document.getElementById(element);
 }

 return fetchedVar;
}
//We load our feed here
function loadFeed(feed){
 switch(feed){
 case "jeez":
 getVariable('sitelogo').innerHTML = "<img src='http://jeez.eu/wp-content/themes/palmixio/images/logo.png' />";
 break;
 case "wp":
 getVariable('sitelogo').innerHTML = "<img src='http://s.wordpress.org/style/images/wordpress-logo.png' />";
 break;
 case "drupal":
 getVariable('sitelogo').innerHTML = "<img src='http://drupal.org/sites/all/themes/bluebeach/logos/drupal.org.png' />";
 break;
 case "noupe":
 getVariable('sitelogo').innerHTML = "<img src='http://www.noupe.com/wp-content/themes/default/images/logo.png' />";
 break;
 }
//Here we load the iframe
 getVariable('feed').innerHTML = "<iframe id='feedf' width='455' height='180' src='http://seotests.writer.gr/gwave/index.php?action="+feed+"'></iframe>";
}

function reloadFeed(){
 loadFeed(getVariable('ftable').className);
}

Now, each time any of the links is clicked, our JavaScript will ask the server for the feed and display it in the “feed” div layer.

Step 3: Server Side

We need some server side coding to get the feed, parse it and send the data back to the gadget. We will use PHP and SimplePie to do this. The code is very simple (File: index.php):

function readData($blog){
 include "simplepie.inc";
 switch($blog){
 case "jeez":
 $load = "http://jeez.eu/feed/";
 break;
 case "wp":
 $load = "http://wordpress.org/development/feed/";
 break;
 case "drupal":
 $load = "http://drupal.org/node/feed";
 break;
 case "noupe":
 $load = "http://feeds.feedburner.com/Noupe";
 break;
 }
 $feed = new SimplePie($load);
 $i = 0;
 foreach ($feed->get_items() as $item):
 $data[$i]['permalink'] = $item->get_permalink();
 $data[$i]['title'] = $item->get_title();
 $data[$i]['description'] = $item->get_description();
 $data[$i]['post_date'] = $item->get_date('j F Y | g:i a');
 $i++;
 endforeach;
 return $data;
}

if($_GET['action']){
 $data = readData($_GET['action']);
//we load the style again in order to style the iframe too.
 $html = "<link rel='stylesheet' type='text/css' href='http://seotests.writer.gr/gwave/styles.css' /><table id='ftable' class='$_GET[action]'>";
 $i=1;
 foreach($data as $key=>$value){
 if($i<=5){
 $html .= "<tr><td class='counter'>$i)</td><td class='title'><a href='$value[permalink]' title='$value[title]'>$value[title]</a></td><td class='date'>at $value[post_date]</td></tr><tr><td colspan='4' class='description'>\"$value[description]\"</td></tr>";
 $i++;
 }
 }
 $html .="</table>";
 echo $html;
}

What some of you might have noticed, is that we assign a class name to the html table element from the action generated by the gadget. This is used only by the reloadFeed() JavaScript method and is nothing special.The gadget now looks like this:

screen

Step 4: Gadgetize it

To create a Google gadget, all you need to do is to create an XML file with this structure:

<Module>
<ModulePrefs title="YOUR TITLE HERE" title_url="The URL where your Gadget will link to" width="WIDTH OF GADGET" thumbnail="A THUMBNAIL" screenshot="A SCREENSHOT OF YOUR GADGET" height="HEIGHT OF GADGET" author="YOUR NAME" author_email="YOUR EMAIL"/>
<Content type="html"><![CDATA[
PLAIN SIMPLE HTML HERE
]]></Content>
</Module>

This structure allows you to add nearly anything between the Content tags. So, what we need to do in order to make a gadget from our code, is to add the xml headers and enclose our code between the Content tags. Now, the gadget.php file becomes:

<?php header('Content-type: text/xml');?><?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<Module>
<ModulePrefs title="Feed Reader for Google Wave"
title_url="http://jeez.eu"
width="500"
thumbnail="thumb.png"
screenshot="screen.jpg"
height="375"
author="Kerasiotis Vasileios - http://jeez.eu"
author_email="basdog22@gmail.com" />
<Content type="html"><![CDATA[
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="scripts.js"></script>
</head>
<body>
<div id="container">
<div id="buttons">
 <a href="javascript:void(0);" onclick="loadFeed('jeez')"><span class='button'>Jeez.eu</span></a>
 <a href="javascript:void(0);" onclick="loadFeed('drupal')"><span class='button'>Drupal</span></a>
 <a href="javascript:void(0);" onclick="loadFeed('wp')"><span class='button'>Wordpress</span></a>
 <a href="javascript:void(0);" onclick="loadFeed('noupe')"><span class='button'>Noupe</span></a>
 <a href="javascript:void(0);" onclick="reloadFeed()"><span class='button'>Reload</span></a>
</div>
<div id="sitelogo"></div>
<div id="feed"></div>
</div>
</body>
</html>
]]></Content>
</Module>

Beware that the file should be served as an XML file. This is easy to bypass by serving it as one using PHP’s header function. We also echo the first line in order to avoid PHP getting confused by the “<?” at the start of the file.  Now, we need to add it to Google Wave :)

Step 5: Wave it

Google wave allows us to create extensions and make them available for other users with the “Extension Installer” extension provided by Google itself. We first need to install this extension. Go to Google Wave and click on the “Extensions Gallery” wave. Scroll down a little and you should find the “Extensions Installer” extension:

installer

Click on the Install button and reload Google Wave. Now you are ready to create your extension’s manifest file that the “Extensions Installer” will use to import your extension to Wave.

Manifest.xml

The manifest.xml file is the file that will describe your extension to Wave. The structure of this file is:

<extension
 name="Your Extension name"
 description="a description here"
 thumbnailUrl="The URL to the thumbnail">
 <author name="Your name"/>
 <menuHook location="WHERE TO LOAD IT" text="WHAT NAME TO SHOW?" iconUrl="AN ICON FOR YOUR EXTENSION">
 <insertGadget url="THE URL TO THE GADGET"/>
 </menuHook>
</extension>

Here is the full manifest file description. Read this to find out about other options in the file. In our case, the above file will look like this:

<extension
 name="Simple Feed Reader"
 description="A feed reader for some blogs"
 thumbnailUrl="http://seotests.writer.gr/gwave/screen.jpg">
 <author name="Jeez Tech"/>
 <menuHook location="TOOLBAR" text="Jeez.eu Feed Reader" iconUrl="http://seotests.writer.gr/gwave/icon.png">
 <insertGadget url="http://seotests.writer.gr/gwave/gadget.php"/>
 </menuHook>
</extension>

Our extension is ready to be imported to Wave. Load Google Wave and when it is loaded, you will notice an arrow next to the “New Wave” button. Click on the arrow and select “New Extension Installer”:

adding

This will open a dialog like this one:

dialog

This is where you will give the full URL to the manifest.xml file. When you click on the insert button, a new wave will load that will look like this:

installed

Now all you have to do is to click the Install button. From now on, when you compose a message or edit one, a new icon will appear on your toolbar, it is our extension’s button:

waveicon

and when you click it, our feed reader will be placed into the wave:

final

That’s it. Our feed reader is ready for use from within the Wave.

There is a way to use AJAX to deliver content using JSON encoded data. We will try to do this and we will update the post.

VN:F [1.9.1_1087]
Rating: 9.3/10 (14 votes cast)
VN:F [1.9.1_1087]
Rating: +5 (from 5 votes)
Creating A Google Wave Extension In 5 Steps, 9.3 out of 10 based on 14 ratings

Popularity: 8%

  • Share/Bookmark

Related posts:

  1. Our Favorite Google Wave Extensions And Add-ons Google Wave is gaining more and more attention from developers...
  2. A Google Wave Guide For Dummies Today i got my invitation for Google’s new service called...
  3. Google Visualizations From A To Z Google has released an API that you can use to...
  4. Creating an Unobtrusive Javascript Image Callery Using YUI The Yahoo User Interface (YUI) is a set of utilities...
  5. Bing Maps. A Google Maps Alternative, or Better? Microsoft has released their own maps service and to be...

About the Author:

Filed under: Tutorials - Trackback Uri


14 Comments.

  • Basilakis says:

    Dude, let wave start come out of beta and then start developing!

    That article is pro! The widget is nice! I think it is time to start working on em! :D

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
  • Hay says:

    The Javascript could be a little less complex. Afaik the getVariable() function isn’t really need, just use document.getElementById. Also, the method could be a little tricky, it’s probably easier to use JSONP or something and use a library like jQuery to load in your cross-domain javascript.

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: +1 (from 1 vote)
  • You are 100% right about the method with the iframe.. I will update the post in the future with jQuery. Thanks

    VN:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VN:F [1.9.1_1087]
    Rating: +1 (from 1 vote)
  • mPm says:

    Hey nice post.

    I wish to explore wave, but unfortunately not getting invitation, no sandbox account. :(

    Sending an invitation will be highly appreciated.

    Thanks.

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 2 votes)
  • Nice article.
    I’d like to get the invitation of Google Wave too.

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
  • Great article, easy to follow.

    I really look forward to playing around with Wave. Like others this post is mostly made to request an invite lol :) My email is jonjonsson at the great gmail.com (email.replace(‘at the great’, ‘@’))

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
  • Awesome Post…If you still have wave invites my email is alex a t inceptdesign d o t c o m

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
  • Elizabeth says:

    Great Article! I am looking forward to creating my own wave extention and this is a great framework for conceptualizing my ideas.

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
  • gab says:

    I going to try,
    thank you very much.
    gab

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
  • Michal says:

    If interested in Wave Gadget programming in Java, take a look at my post http://dendrytsoft.blogspot.com/2009/10/building-google-wave-gadget-with-gwt.html

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)

Trackbacks/Pingbacks

  1. [...] En Jeez.eu, han hecho un mini tutorial para hacer una extensión para Google Wave en tan solo 5 pasos. [...]

  2. [...] Creando una extension para Google Wave en 5 pasos (via Anieto2k) [...]

  3. [...] Creating a google wave extension in 5 steps |Jeez [...]