At the Forge - OpenSocial and Google Gadgets
Google has tried to make gadget development as easy as possible. One way it eases the learning curve has been through the creation of many on-line tools that remove the editing and storage needs for many developers. Thus, although many Web developers (like me, and possibly you) are happy to write programs in Emacs and put them on their own private Web servers, Google realized that not everyone has access to (or familiarity with) such tools. So, Google provides a Web-based editor (GGE, the Google Gadget Editor), which not only lets people edit their own gadgets via a Web browser, but also provides free storage for gadgets.
I'm going to take a more traditional route to storage in this column, although you're welcome to ignore my example. I'll be putting my gadgets on my Web server (atf.lerner.co.il). To incorporate these gadgets into my iGoogle page, I must go to the My Gadgets gadget and enter the complete URL of the gadget. For example, I stored the above “Hello, world” gadget on my server as rmlgadget1.xml. Thus, I entered the following URL into My Gadgets: http://atf.lerner.co.il/rmlgadget1.xml.
Sure enough, after a moment of loading, I saw “Hello, world!” on my iGoogle screen. Each gadget is displayed inside an iframe, an HTML entity that allows the developer to create content that's independent of its surroundings. Or, thinking about it in a different way, the iframes ensure that gadgets cannot interfere with one another but stay “locked” inside their frames.
It goes without saying that most developers would not be content to produce “Hello, world” programs. Rather, we typically want to do something a bit more substantive.
In order to do that, we need to create a bit more HTML inside the <Content> section. We probably should create some JavaScript that manipulates that HTML as well, given that we have a completely open canvas.
Note that I'm going to modify the original gadget I created, which I named rmlgadget1. Google caches gadgets, which means that once you have loaded one on to your iGoogle page, modifications made to the gadget won't show up. This is when you must fire up your trusty My Gadgets gadget, and uncheck the cached check box for the gadget (in my example, rmlgadget1). Reloading the iGoogle page will reload the gadget from the Web server, allowing you to have a more interactive and productive development experience.
Here's one update that demonstrates how to use JavaScript inside the gadget:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Hello world" />
<Content type="html">
<![CDATA[
<div id="content">Hello, world!</div>
<script type="text/javascript">
var element = document.getElementById('content');
element.innerHTML = "Foo";
</script>
]]>
</Content>
</Module>
Once again, there's not much content to this widget. We simply use JavaScript and the DOM to modify the contents of a div. So, let's make things a bit more interesting and retrieve the latest headlines from Linux Journal's RSS feed. Then, we can display the first few headlines, even making them linkable:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Reuven's Gadget" />
<Content type="html">
<![CDATA[
<div id="content">Loading feeds...</div>
<script type="text/javascript">
var html = '';
var url = "http://feeds.feedburner.com/linuxjournalcom";
var callback = function(feed) {
html += "<ul>\n";
for (var counter = 0; counter < feed.Entry.length;
counter++) {
html += "<li>" + '<a href="' +
feed.Entry[counter].Link + '" ta\
rget="_blank">' + feed.Entry[counter].Title + "</a>" + "</li>\n";
}
html += "</ul>\n";
_gel('content').innerHTML = html;
};
var num_entries = 5;
var get_summaries = false;
_IG_FetchFeedAsJSON(url, callback, num_entries, get_summaries);
</script>
]]>
</Content>
</Module>
The above gadget code begins with the same sort of static code as our previous gadget, although I did change it from saying “Hello, world” to something a bit more useful (“Loading feeds...”), because this text will appear while the feeds are loaded.
The JavaScript in this gadget is somewhat interesting, mostly because it depends on the _IG_FetchFeedAsJSON function, which Google provides to gadget developers. This function takes four arguments, and the first two are mandatory—the URL from which to fetch the arguments and the callback function that should be invoked when the feed is retrieved. For our example, I'm using the RSS/Atom feed URL for Linux Journal as provided by FeedBurner.com. Thus, we will get the list of recent www.linuxjournal.com headlines, as defined by the site administrators.
The callback function, which I've named callback here, is invoked with a single argument, the JSON (JavaScript Object Notation), representing the feed that was retrieved from our URL. That JSON contains an array named Entry, whose elements contain the feed information. Each element contains Title and Link properties, which we will use to construct the output HTML.
When callback is invoked, we first go to FeedBurner.com and retrieve the five most-recent headlines:
_IG_FetchFeedAsJSON(url, callback, num_entries, get_summaries);
Then, we iterate over the elements of Entry, appending them to a variable we've conveniently named html and putting each Title inside an HTML link, which opens the target URL in a new tab or window (thanks to target="_blank"):
for (var counter = 0; counter < feed.Entry.length;
counter++) {
html += "<li>" + '<a href="' +
feed.Entry[counter].Link + '" ta\
rget="_blank">' + feed.Entry[counter].Title + "</a>" + "</li>\n";
}
Finally, we assign our div (the one that starts by saying “Loading feeds...”):
_gel('content').innerHTML = html;
Sure enough, our gadget works very nicely, providing us with a dynamically updated list of headlines from Linux Journal. What could be better?
One of the most interesting characteristics of Google Gadgets is the way in which they are completely self-contained, insulated from the surrounding page and application. As I mentioned previously, this is because each gadget sits inside an iframe, and it undoubtedly was one of the reasons gadgets were used as the basis for OpenSocial.
However, we already can see how this will lead to a situation in which the application, rather than the hosting OpenSocial “container” site, determines the look and feel. This means if you include six OpenSocial applications, each one will have its own look and feel. This is a big difference from Facebook, in which applications are forced, to a large degree, to adhere to Facebook's look and feel, creating a rather pleasant user experience. Time will tell whether this causes problems or whether developers and users will reach a happy medium on this issue.
A separate issue is the fact that each gadget contains only a single page of HTML. Any updates that take place within the gadget, as we saw, happen thanks to JavaScript manipulation of the DOM. This is not a bad thing, and it is becoming increasingly common as Ajax becomes more pervasive among Web developers. However, it may be slightly foreign for developers who are still using the one-page-per-click paradigm.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
| Introduction to MapReduce with Hadoop on Linux | Jun 05, 2013 |
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Linux Systems Administrator
- Validate an E-Mail Address with PHP, the Right Way
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- RSS Feeds
- Introduction to MapReduce with Hadoop on Linux
- Bought photoshop CS5 for developing a website :(
1 hour 4 min ago - What the author describes
2 hours 30 min ago - Reply to comment | Linux Journal
6 hours 41 min ago - Reply to comment | Linux Journal
7 hours 26 min ago - Didn't read
7 hours 36 min ago - Reply to comment | Linux Journal
7 hours 41 min ago - Poul-Henning Kamp: welcome to
9 hours 52 min ago - This has already been done
9 hours 53 min ago - Reply to comment | Linux Journal
10 hours 38 min ago - Welcome to 1998
11 hours 26 min ago
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
Hi
Thanks the article was really insightful