Sunday, December 13, 2009

Converting Google Picasa's embedded slideshow code to valid XHTML/HTML

Defining the Problem:

You have created a picture album in Google Picasa and want to embed a slideshow of that album in your website or blog. Fortunately, Google Picasa makes it easy to generate the code to do so. All you have to do is copy and paste the generated code into the HTML of your site.

Here's an example of that generated code, using my Chinese Zodiac desktop wallpaper album:

<embed type="application/x-shockwave-flash" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" width="144" height="96" flashvars="host=picasaweb.google.com&hl=en_US
&feat=flashalbum&RGB=0x000000&feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2FJonah.Chanticleer%2Falbumid%2F5220445689687444257%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer">

</embed>

Unfortunately, Picasa's generated code uses the <embed> tag, which is not part of the HTML/XHTML standards (see http://validator.w3.org/docs/help.html#faq-flash for more information). Furthermore, the value assigned to the flashvars attribute of the <embed> tag has multiple ampersands in it, and those ampersands are not properly URL-encoded (see http://www.htmlhelp.com/tools/validator/problems.html#amp for details). This means the code will break validation for any page into which you paste it. Many people don't care if their pages fail to validate, but since you've made the effort to find this article and read this far, I'm assuming you are a web development professional who does care if your page throws a web-browser into "quirks mode."(http://en.wikipedia.org/wiki/Quirks_mode)

Creating a Solution:

To regain proper validation, we need to address the two following issues:

1. Switch from <embed> to <object>, which is part of the HTML/XHTML standards

2. Properly encode the ampersands by changing them from "&" to "&amp;"

Switching from embed to object:

Let's take a closer look at the attributes of the <embed> tag example from above. I've separated them by linebreaks to make them easier for us to read:

<embed

type="application/x-shockwave-flash"

src="http://picasaweb.google.com/s/c/bin/slideshow.swf"

width="144"

height="96"

flashvars="host=picasaweb.google.com&hl=en_US&feat=flashalbum&RGB=0x000000&feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2FJonah.Chanticleer%2Falbumid%2F5220445689687444257%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US"

pluginspage="http://www.macromedia.com/go/getflashplayer">

</embed>

The good news is that three of the six attributes (width, height and type) translate directly into attributes with the same names for the new object tag. We are off to a good start.

<object type="application/x-shockwave-flash" width="144" height="96">
<!-- TBD -->
</object>

By reading the HTML reference page for the object tag (http://www.w3schools.com/TAGS/tag_object.asp), we can figure out that the src attribute doesn't exist-- the closest equivalent to it is the data attribute. The two remaining attributes, pluginspage and flashvars, do not have any counterparts in the attributes of the object tag. We will need to pass them directly as run-time parameters with the param tag (http://www.w3schools.com/TAGS/tag_param.asp).

It is worth noting this one important note from the object tag reference: "The object support in browsers depend on the object type. Unfortunately, the major browsers use different codes to load the same object type." In other words, all standards-compliant web browsers will recognize the object tag, but they may do so in different ways. Netscape-family browsers might respond to the data attribute, while Internet Explorer will not see that same information unless it is passed along in a param value.

Fortunately for us, Drew McLellan's article in the Nov. 9 2002 issue of A List Apart, "Flash Satay: Embedding Flash While Supporting Standards," gives us just the perfect trick to make the object/param sandwich that works with both sets of browsers. Check it out below:

<object type="application/x-shockwave-flash" width="144" height="96" data="http://picasaweb.google.com/s/c/bin/slideshow.swf">
<param name="movie" value="http://picasaweb.google.com/s/c/bin/slideshow.swf" />
</object>

(Mr. McLellan, if you should find yourself in the DC Metro area, drop me a line-- because your first beverage is on me. This bit of brilliance saved me time and a headache!)

Let's stay on track-- because we haven't finished just yet! We still need to create param tags for the pluginspage and flashvars, and nest them between the object tags.

<object type="application/x-shockwave-flash" width="144" height="96" data="http://picasaweb.google.com/s/c/bin/slideshow.swf">
<param name="movie" value="http://picasaweb.google.com/s/c/bin/slideshow.swf" />
<param name="FlashVars" value="host=picasaweb.google.com&hl=en_US&feat=flashalbum&RGB=0x000000&feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2FJonah.Chanticleer%2Falbumid%2F5220445689687444257%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" />
<param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" />
</object>

Encoding the ampersands:

Almost done. There's only one thing left to fix-- those pesky ampersands assigned to the "value" attribute of the param tag named "FlashVars." This is literally a case of substituting "&amp;" for "&", as I've done below (bold removed for emphasis):

<param name="FlashVars" value="host=picasaweb.google.com&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2FJonah.Chanticleer%2Falbumid%2F5220445689687444257%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" />

Final Result:

So, our end result should look like this when we view it as an entire page (assuming XHTML 1.0 Transitional):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>. . .</title>
</head>
<body>

<!-- any content in your page that appears before the slideshow -->

<object type="application/x-shockwave-flash" width="144" height="96" data="http://picasaweb.google.com/s/c/bin/slideshow.swf">
<param name="movie" value="http://picasaweb.google.com/s/c/bin/slideshow.swf" />
<param name="FlashVars" value="host=picasaweb.google.com&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2FJonah.Chanticleer%2Falbumid%2F5220445689687444257%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" />
<param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" />
</object>

<!-- any content in your page that appears after the slideshow -->

</body>
</html>

Extra Credit:

Now that your page validates, you can congratulate yourself on a job well done-- until the next time you need to create a new slideshow code snippet in Picasa. Or someone else tries to use the invalid slideshow code on their webpage, and asks you to help them fix it. Or doesn't ask you to help them fix it.

The truth is what I've shown you here is only a band-aid, not a cure for the real problem. There are many tools out there which generate invalid HTML code snippets; Google's Picasa is only one of them. If you care about web standards and want to see them realized on the World Wide Web, you need to contact the developers responsible for popular tools like Picasa (http://www.google.com/support/forum/p/Picasa/thread?tid=3ca39d2989c708ac&hl=en) and persuade them to make changes that will result in the output of valid HTML code. Be patient and polite when you advocate for these changes, not pushy and critical. You never know the circumstances behind the development of an application or product. It may be the developer created the code before a specific standard had been fully ratified, or the developer may have been forced to use third party libraries/components that generate invalid code. By advocating and educating in a positive manner, you can give a developer the motivation, desire and information they need to do the right thing.

Acknowledgments/Further Reading:

Thanks to E.G. for bringing this whole Google Picasa puzzle to my attention in the first place.

Drew McLellan, "Flash Satay: Embedding Flash While Supporting Standards", A List Apart, Nov. 9, 2002, http://www.alistapart.com/articles/flashsatay

Picasa Web Albums Help Forum (http://www.google.com/support/forum/p/Picasa/label?lid=051816230f0ec560&hl=en)