GTUG CampoutI recently attended the Google Technology User Group Campout at the Googleplex in Mountain View. This was a three day sprint to build something interesting with the latest Google product: Google Wave.

Google Wave, as it turns out is a very interesting experiment in social interaction. Google is trying to reinvent collaborative communication with a piece of software that is one part chat, one part Wiki, and one part WebEx.

I’d seen this product at the Google I/O conference a few months back and was impressed with the demos. Basically you get these shared documents (called Waves) that all of the collaborators can update at the same time. You can watch the hour and a half demo at http://www.youtube.com/watch?v=v_UyVmITiYQ

The demo included things like interaction with blogs, Twitter and other web technologies, as well as interesting programming doing things like on the fly grammar checking. I signed up for a sandbox account the day of the presentation (using my iPhone of course), and got set up a week or so after that.

Wave was written by the brothers Lars and Jans Rasmussen, who are the architects of the Google Maps API. In some sense, this is an experiment in building software caused by the lessons they learned with the immensely popular Maps API. By giving the developers access early in the build process, they hope to build a more solid platform that will serve the developers needs.

So Friday came and I drove over to Google with Bennett Fonacier (a friend I met through Job Connections some time back). After the 50+ people got through with their 5 minute pitches, we networked for another hour forming teams. There were many ideas that were very similar, and for the most part these groups joined up into a combined team. Bennett and Steffen Frost (CEO of Carticipate) both came up with the idea of matching people for ride shares using the Wave.

I’d originally thought I would join a team doing something health related, but since my goal was to get a working piece of code, and I was sitting with the car pool team, I joined that effort. We became one of the roughly 50 projects teams, and quickly talked through what we’d be building over the next 48 hours or so.

The other members of the Wave Rides team were:

  1. Steffen Frost was a great concept guy, and had an existing product we were going to try and emulate.
  2. Bennett Fonacier has some development background, but he was short a computer, and would be doing QA.
  3. Andreas Koll who had some experience with the Google Maps API volunteered to build the Gadget for our interface.
  4. Hannie Fan offered to provide some design expertise and CSS coding.
  5. Robert Herriott was a quiet supporter, offering constructive criticism

I took on the task of writing the Robot, which is the part of the Wave that would take the input from the Gadget and match the participants with ride partners. Andreas had a working Gadget in short order, and was able to embed it in a Wave.

While he was doing that, I was working on getting a Robot built using the guidelines in developing Wave extensions slides. I got a working “Hello World”, built the extension.xml file, and with help from the Google crew, got it so we could create a new Wave with my Robot added.
Carticipate Logo

I got the icon from the Carticipate site, added a bit of code, and the Robot was adding the Gadget to the Wave. So far I had gotten a working Robot, and Andreas had a working Gadget. Now all we needed to do was clean them up a bit and get them talking.

This turned out to be a bit tougher than expected. The current state of the world is that the Robot can add a Gadget, and send data to it when it is added to the Wave, but can only read the state from the Gadget, and not actually set anything after the Gadget is running.

Anyway, I eventually got some debug code going in my Robot that would dump out the properties of the Gadget, which helped Andreas to debug some issues he was seeing with the state of the users accessing the Gadget.

A Gadget is basically a snippet of HTML and JavaScript that gets embedded in an XML file for inclusion in the Wave. Because the working code is inside an XML document, it gets wrapped in a CDATA element, which makes editing and debugging the Gadget a bit challenging. Andreas approach was to cut the HTML code out of the Gadget and edit it as an HTML document, then paste it back into the Gadget. Not ideal, but it works.

Our original plans for the WaveRides robot was that it would behave roughly the same way as the Carticipate application does: ask the user a few questions about where they are going, if they are driving, and then show a list of everybody who is travelling in the same area and time. So as we worked, I kept prototyping closer and closer to that goal.

By the late Saturday night, we had a working prototype that launched the map gadget, and displayed back the data from the users interacting with the gadget. The gadget was displaying the location of all of the users on the map, and we were feeling pretty good about the progress (especially considering none of us had ever built anything with the Wave API before). Bennett and I headed home, expecting to finish up the next morning, leaving Andreas coding away on his gadget.

The next day we arrived at the Googleplex and found that Andreas had solved some of his remaining problems, and the gadget was looking good. I went to work on the Robot, trying to get it to match up the user data. Of course, since there was little time left, the Wave kept misbehaving (probably due to all of us pounding on the sandbox with untested code), and we kept running into walls.

My original design had been to add a blip with the map gadget and gather my data from there. I soon realized that it was difficult to keep track of the gadget that way, so I changed my code to add the gadget to the root blip, and started removing debug code. At some point, we decided to put the code up on code.google.com for safekeeping, so I spent a few minutes figuring out how to do that (you can see the code at http://waverider.googlecode.com).

It was still fairly early on Sunday morning, and Andreas had been up until the wee hours of the night, so he wasn’t around for us to ask him to make changes to his gadget. We had separated the development of the gadget and the robot, so they were actually being served by two separate app server applications. The gadget only provided input for one point, and to complete the robot to the point we could demo something interesting, we needed it to have a “from” and “to” for each participant.

So rather than reinventing what Andreas had done, I decided to change the robot to create a “from” and a “to” gadget in the Wave, and use that. Interestingly this turned out to be fairly painless. I was able to add the second instance of the gadget, and give them each a name. The Wave kept track of them separately, so I got the data from both separately.

I spent the last few moments before we were supposed to present, trying to get a simple match working. The nice thing about this was that I could version the app on the Google App engine, and keep a known working version deployed while continuing to test. As other teams presented, it became obvious that this had been a good decision, and I eventually dropped back to one of the earlier working versions for the demo.

We got to demo the concept, and explain what we would have liked to have done. I accomplished my goal of learning how to code a basic robot, and learned a lot about the API. We were by no means the slickest or coolest app there, but we had fun building it.

We’ve got the start to an open source project that could eventually be used to match people locationally, and used for all sorts of purposes, and we got to see some of the challenges in building apps for a piece of software as new as Google Wave.

Team picture

From left to right above: Steffan Frost, Fannie Han, Rob Weaver, Andreas Koll, Bennett Fonacier.

Steffen created a really cool video over that weekend as well that you can watch at http://www.youtube.com/watch?v=DkmuBmBZkBo

Recently I’ve been doing some web page work again, and trying to push the envelope on my CSS knowledge.

I was at a talk at 360|iDev where Brian Fling was talking about UI design, and he pointed out that your site should work without your CSS. Now while I know this as a design principle, it seems like something that we probably overlook more often than not.

So, out of curiosity, I thought I’d take a look and see what some of my pages look like without their stylesheets applied.

The first trick is Firefox with Firebug.

Firebug is a plugin that lets you debug and examine the contents of a page and do very interesting things, like modify your page on the fly. By loading up Firebug on one of my sites, it was an easy thing to browse to where the stylesheets are loaded. To start up Firebug, I normally just right click on the page and choose “Inspect Element” from the popup dialog box, or use the Open Firebug option from the Tools menu:

right click menutools_open_firebug

Once you have Firebug open, you can browse your HTML to where the stylesheets are loaded (normally in the HEAD section of your page):

Firebug looking at header

The next trick is that with Firebug, you can change everything

In the above example, I have two stylesheets loading: a basic one (basic.css) and one for print layout (print.css). So to look at my site without the stylesheet, all I have to do is right click on the link that loads the sheet, and choose Delete Element:

delete element

Third trick: debugging missing link includes with Firebug is cool

One interesting thing to note, if you expand the link node, you’ll see the complete style sheet as it was downloaded from the server. I’ve found this very handy in finding issues like a typo in a stylesheet name, or a misconfigured server (which is very easy to happen with frameworks like Cake), since what displays is the actual return from the server (so for instance if you mispell the name, you’ll see the actual 404 file missing):

404 error

Once you’ve removed the link (or even change the name to a bad one as I did above), you’ll see your bare bones HTML, just like it would appear to a browser without styles. If your page was designed correctly, it should have basic navigation links at the top of the page instead of the menu bars, which make the site usable for a browser that isn’t using your stylesheets.

Jc no style

Next: starting a new page so that it works with and without style …

I spent some time yesterday figuring out CSS problems for Job Connections.

The Job Connections site was built using a CSS for printing that wasn’t including all of the parts of the page that should be printed. They use a stylesheet called print.css, and when somebody would try to print a page, they weren’t getting anything but the text in the middle of the page.

I took a look and found that the stylesheet was setting all of the region styles to “display: none”, which tells CSS not to display them. Editing the stylesheet to remove these bits was all that was needed, so I set it up to print everything but the menu bar at the top and down the side.

In the same file, there was a reference that looked like an attempt to make the links display as bolded when the page was printed. The code that was trying to do this looked like:

 

That wasn’t working, mostly because the style was being applied to all anchors. I updated it to look like:

This change applied the style to both links and visited links. I then went one step further and added some magic to get the actual link to print (works in CSS2 compliant browsers):

The magic is in the “:after” bit, which basically says “after you display the link, display something else”. With this applied, the links all get bolded, underlined, and are followed by the actual URL in parentheses afterward.

I got access to the web site (thanks to Walt Feigenson), so this is partially fixed now. It looks pretty good except the content still has quite a large area of whitespace to the left due to the way the style sheets are interacting. I’m playing with updating this now to make the print CSS work the way it should and not inherit the styles that cause this from the “screen” CSS.

Enhanced by Zemanta