iGoogle Google Developers Day Haifa Ran Tavory
Google Technologies <ul><li>Google uses a lot of web-related technologies in its products </li></ul><ul><li>We also suppor...
What are Gadgets? <ul><li>HTML inside an XML wrapper </li></ul><ul><li>Mini web pages: HTML, JavaScript, CSS, Flash, AJAX ...
Examples of Google Gadgets
Where do Google Gadgets live? <ul><li>iGoogle homepage </li></ul><ul><li>Third-party websites </li></ul><ul><li>Google Des...
iGoogle homepage…
Third-party websites… http://gadgetryout.blogspot.com http://www.puertovallarta.net
Google Desktop…
Mac OS X Dashboard…
Instant Dashboard capabilities <ul><li>Going from this: </li></ul>
Instant Dashboard capabilities <ul><li>to this: </li></ul>
Full application (gadget interaction) <ul><li>http://googlefinanceblog.blogspot.com/2007/10/api-gadgets-and-tabs-oh-my.htm...
Who writes gadgets? <ul><li>Individuals </li></ul><ul><ul><li>Independent contractors and contracting groups </li></ul></u...
Gadgets are open <ul><li>Gadgets are open-source XML </li></ul><ul><li>Developer community worldwide </li></ul><ul><li>Eas...
“ Hello world” gadget <ul><li><?xml version =&quot; 1.0 &quot;  encoding =&quot; UTF-8 &quot;  ?> </li></ul><ul><li><Modul...
The Google Gadgets Editor <ul><li>http://code. google . com/apis/gadgets/docs/gs .html#Scratchpad </li></ul>
API services <ul><li>ModulePrefs </li></ul><ul><ul><li>Title, height, author, description, thumbnail, … </li></ul></ul><ul...
<ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> </li></ul><ul><li><Module> </li></ul><ul><li><ModulePr...
Gadget UserPrefs <ul><li>Allows users to configure your gadget </li></ul><ul><li>Multiple types: </li></ul><ul><ul><li>Che...
Creating a Gadget: Using the API <ul><li>And more… </li></ul><ul><li>SetPrefs </li></ul><ul><li>Grid </li></ul><ul><li>Dra...
Creating a Gadget: Using the API <ul><li>Add <Require feature=“…”/> tags to use our libraries </li></ul><?xml version=&quo...
Tech Tip 1: Analytics & Numbers <ul><li>Weekly pageviews are displayed in the Google Gadgets for Your Page directory. </li...
Tech Tip 2: Fetching Remote Content <ul><li>Fetching remote content is powerful, convenient, and easy! </li></ul><ul><ul><...
Tech Tip 2: Fetching Remote Content <ul><li>Three methods available: </li></ul><ul><li>_IG_FetchFeedAsJSON(url, callback, ...
Tech Tip 2: Fetching Remote Content <div id=&quot;container&quot;></div> <script> function callback(response) { // Iterate...
Tech Tip 2: Fetching Remote Content <ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> </li></ul><ul><li><...
Tech Tip 3: Internationalize! <ul><li>Support multiple languages in a single gadget </li></ul><ul><li>Increase success in ...
Tech Tip 4: Storing State <ul><li>Example:  Simple Notes Gadget </li></ul><ul><li>User creates notes and saves them in iGo...
Tech Tip 4: Storing State <ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> </li></ul><ul><li><Module> <...
Tech Tip 5: Caching External Resources <ul><li>Facts: </li></ul><ul><ul><li>Google caches all gadget XML files </li></ul><...
Tech Tip 5: Caching External Resources <ul><li>Caching images </li></ul><ul><li>Caching Flash </li></ul><img id=&quot;goIm...
Advanced API <ul><li>Gadget-to-gadget communication: </li></ul><ul><ul><li>Read  http :// www . google . com / apis / gadg...
Feeds in tabs step-by-step <ul><li>Fetches and displays multiple RSS/Atom feeds </li></ul><ul><li>Uses multiple API featur...
Building a Gadget <ul><li>Start small with a simple gadget XML that contains bare essentials </li></ul><ul><li>Don’t worry...
Building a Gadget <ul><li>Add tabs to the gadget using the API Tabs library </li></ul><ul><li>Generate unique content  for...
Building a Gadget <ul><li>Create an input mechanism for Atom/RSS feed URLs </li></ul><ul><li>Add a UserPref to accept feed...
Building a Gadget <ul><li>Read the feed URL from the UserPref </li></ul><ul><li>Fetch the feed and get a JSON response bac...
Building a Gadget <ul><li>Use the JSON response object to generate the HTML </li></ul><ul><ul><li>feed.Title, feed.Link, f...
Building a Gadget <ul><li>Add CSS rules to stylize the output </li></ul><ul><li>Remember screen real estate is very limite...
Building a Gadget: Almost Done <ul><li>Are we done yet?  Almost… </li></ul><ul><li>What’s missing? </li></ul><ul><ul><li>d...
Building a Gadget: Almost Done <ul><li>Dynamic height is convenient and makes users happy </li></ul><ul><li>Analytics lets...
Building a Gadget: Final Touches <ul><li>Users love options.  It’s easy to extend your gadget to be more customizable by u...
Building a Gadget: Final Touches <ul><li>Let the gadget title be customizable </li></ul><ul><li>Customize each tab label <...
Building a Gadget: Final Touches <ul><li>Let user select how many feed entries to display </li></ul><UserPref name=&quot;e...
Building a Gadget: Final Touches <ul><li>Prepare your gadget for submission </li></ul><ul><li>Add important metadata to ma...
Now What? <ul><li>I’ve built my gadget, now what? </li></ul>
Submit your Gadget <ul><li>Users will discover your content through the public content directory.  </li></ul><ul><li>Submi...
It’s all in the first impression… <ul><li>Users will have thousands of gadgets to choose from in the gadget directory, so ...
Promote your Gadget <ul><li>Your gadget’s success is dependant upon user uptake. Some of the best ways to promote your gad...
Track your Gadget <ul><li>Tracking your gadget allows you to continually optimize it to provide the best experience for yo...
Hosting & Publishing <ul><li>Hosting </li></ul><ul><ul><li>Google Gadgets Editor </li></ul></ul><ul><ul><li>Google code </...
Want to know more? <ul><li>Google Gadgets API Docs h ttp://www.google.com/apis/gadgets </li></ul><ul><li>iGoogle  http://w...
Upcoming SlideShare
Loading in …5
×

iGoogle - Haifa Seminar

2,134 views

Published on

iGoogle presentation and the Google Haifa Seminar Apr 8th

Published in: Technology, Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,134
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
0
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • iGoogle - Haifa Seminar

    1. 1. iGoogle Google Developers Day Haifa Ran Tavory
    2. 2. Google Technologies <ul><li>Google uses a lot of web-related technologies in its products </li></ul><ul><li>We also support and encourage good web technologies for developers worldwide: </li></ul><ul><ul><li>Open source projects </li></ul></ul><ul><ul><ul><li>Hosting open source project on Google Code </li></ul></ul></ul><ul><ul><ul><li>Google Summer of Code </li></ul></ul></ul><ul><ul><ul><li>Google Gears (browser offline capabilities) </li></ul></ul></ul><ul><ul><ul><li>Googlers contributing to OSS: Linux, Subversion, GCC </li></ul></ul></ul><ul><ul><li>Google open technologies and APIs </li></ul></ul><ul><ul><ul><li>Google Maps API </li></ul></ul></ul><ul><ul><ul><li>Google Data API </li></ul></ul></ul><ul><ul><ul><li>Google Ajax API </li></ul></ul></ul><ul><ul><ul><li>Google Gadgets API </li></ul></ul></ul><ul><ul><ul><li>and many more … (over 35 APIs) </li></ul></ul></ul><ul><ul><ul><li>http://code. google .com/ </li></ul></ul></ul>
    3. 3. What are Gadgets? <ul><li>HTML inside an XML wrapper </li></ul><ul><li>Mini web pages: HTML, JavaScript, CSS, Flash, AJAX </li></ul><ul><li>Anything you can do on a web page, you can do inside a gadget </li></ul><ul><li>Write once, runs everywhere </li></ul><ul><li>Hundreds of thousands of page views each week </li></ul><ul><li>Free hosting and bandwidth </li></ul><ul><ul><li>Google Code Hosting </li></ul></ul><ul><ul><li>Google Pages </li></ul></ul><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> <Module> <ModulePrefs title=“Hello World&quot; /> <Content type=&quot;html”><![CDATA[ <b>Hello World!</b> ]]></Content> </Module>
    4. 4. Examples of Google Gadgets
    5. 5. Where do Google Gadgets live? <ul><li>iGoogle homepage </li></ul><ul><li>Third-party websites </li></ul><ul><li>Google Desktop (Windows, Mac OS X) </li></ul><ul><li>Mac OS X Dashboard </li></ul><ul><li>Windows Vista Sidebar </li></ul><ul><li>IBM WebSphere Portal </li></ul>
    6. 6. iGoogle homepage…
    7. 7. Third-party websites… http://gadgetryout.blogspot.com http://www.puertovallarta.net
    8. 8. Google Desktop…
    9. 9. Mac OS X Dashboard…
    10. 10. Instant Dashboard capabilities <ul><li>Going from this: </li></ul>
    11. 11. Instant Dashboard capabilities <ul><li>to this: </li></ul>
    12. 12. Full application (gadget interaction) <ul><li>http://googlefinanceblog.blogspot.com/2007/10/api-gadgets-and-tabs-oh-my.html </li></ul>
    13. 13. Who writes gadgets? <ul><li>Individuals </li></ul><ul><ul><li>Independent contractors and contracting groups </li></ul></ul><ul><ul><li>Professional developers who write gadgets for a living </li></ul></ul><ul><ul><li>Teenagers & hobbyists writing gadgets because they’re fun </li></ul></ul><ul><ul><li>You </li></ul></ul><ul><li>Businesses </li></ul><ul><ul><li>Provide useful content to users in gadgets </li></ul></ul><ul><ul><li>Extends branch reach </li></ul></ul><ul><ul><li>Drives traffic when users click on links for more information </li></ul></ul><ul><ul><li>Ex: news, sports, entertainment, pro blogs </li></ul></ul>
    14. 14. Gadgets are open <ul><li>Gadgets are open-source XML </li></ul><ul><li>Developer community worldwide </li></ul><ul><li>Easy API: google “gadgets api” or http://www . google . com / api s/ gadgets / </li></ul>
    15. 15. “ Hello world” gadget <ul><li><?xml version =&quot; 1.0 &quot; encoding =&quot; UTF-8 &quot; ?> </li></ul><ul><li><Module> <ModulePrefs title =&quot; hello world &quot; / > <Content type =&quot; html &quot; > < ![ CDATA [ </li></ul><ul><li>Hello, world ! </li></ul><ul><li>]] > </li></ul><ul><li>< / Content> </li></ul><ul><li>< / Module> </li></ul>
    16. 16. The Google Gadgets Editor <ul><li>http://code. google . com/apis/gadgets/docs/gs .html#Scratchpad </li></ul>
    17. 17. API services <ul><li>ModulePrefs </li></ul><ul><ul><li>Title, height, author, description, thumbnail, … </li></ul></ul><ul><li>UserPrefs </li></ul><ul><li>Saving state </li></ul><ul><li>Working with remote content: </li></ul><ul><ul><li>RSS, text, XML </li></ul></ul><ul><li>I18N </li></ul>
    18. 18. <ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> </li></ul><ul><li><Module> </li></ul><ul><li><ModulePrefs title=&quot;My First Gadget&quot; </li></ul><ul><li>description=&quot;This gadget prints hello world.&quot; </li></ul><ul><li>height=&quot;50&quot; </li></ul><ul><li>author=&quot;Daniel L.&quot; </li></ul><ul><li>author_email=&quot;my.email@gmail.com&quot; </li></ul><ul><li>author_location=&quot;Madrid, Spain&quot; </li></ul><ul><li>category=&quot;tools&quot; /> </li></ul><ul><li><UserPref name=&quot;Color&quot; datatype=&quot;string&quot; default_value=&quot;red&quot; /> </li></ul><ul><li><UserPref name=&quot;Toggle&quot; datatype=&quot;bool&quot; default_value=&quot;true&quot; /> </li></ul><ul><li><UserPref name=&quot;Locations&quot; datatype=&quot;list&quot; /> </li></ul><ul><li><Content type=&quot;html&quot;><![CDATA[ </li></ul><ul><li><b style=&quot;color: red&quot;>hello world!</b> </li></ul><ul><li>]]></Content> </li></ul><ul><li></Module> </li></ul>Anatomy of a Gadget User-configurable preferences Gadget content Gadget directory meta-data
    19. 19. Gadget UserPrefs <ul><li>Allows users to configure your gadget </li></ul><ul><li>Multiple types: </li></ul><ul><ul><li>Checkboxes </li></ul></ul><ul><ul><li>Dropdowns </li></ul></ul><ul><ul><li>Text input </li></ul></ul><ul><ul><li>Lists </li></ul></ul><ul><li>Use “hidden” UserPrefs to store data inside your gadget </li></ul><UserPref name=“saved” datatype=“hidden” default_value=“0” />
    20. 20. Creating a Gadget: Using the API <ul><li>And more… </li></ul><ul><li>SetPrefs </li></ul><ul><li>Grid </li></ul><ul><li>Drag </li></ul>Analytics Dynamic Height Tabs MiniMessages Flash
    21. 21. Creating a Gadget: Using the API <ul><li>Add <Require feature=“…”/> tags to use our libraries </li></ul><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> <Module> <ModulePrefs …> <Require feature=&quot;tabs&quot;/> <Require feature=&quot;flash&quot;/> <Require feature=&quot;dynamic-height&quot;/> <Require feature=&quot;minimessage&quot;/> <Require feature=&quot;analytics&quot;/> <Require feature=&quot;setprefs&quot;/> <Require feature=&quot;drag&quot;/> <Require feature=&quot;grid&quot;/> </ModulePrefs> <Content…/> </Module>
    22. 22. Tech Tip 1: Analytics & Numbers <ul><li>Weekly pageviews are displayed in the Google Gadgets for Your Page directory. </li></ul>http://www.google.com/ig/directory?synd=open&url= <gadget_url> <ul><li>For more precise and detailed numbers, it’s a few lines of JavaScript </li></ul><ModulePrefs …> <Require feature=&quot;analytics&quot;/> </ModulePrefs> … <script> _IG_Analytics(&quot;UA-00000&quot;, &quot;/mygadget&quot;); </script>
    23. 23. Tech Tip 2: Fetching Remote Content <ul><li>Fetching remote content is powerful, convenient, and easy! </li></ul><ul><ul><li>Text/HTML, XML, RSS/Atom feeds </li></ul></ul><ul><ul><li>Cached by default to prevent overloading servers </li></ul></ul><ul><ul><li>Built-in RSS/Atom parser outputs in JSON </li></ul></ul>
    24. 24. Tech Tip 2: Fetching Remote Content <ul><li>Three methods available: </li></ul><ul><li>_IG_FetchFeedAsJSON(url, callback, entries, summaries) Fetch RSS/Atom feeds. Returns simple JSON object: </li></ul><ul><ul><li>Useful when you need general data from the feed: </li></ul></ul><ul><ul><ul><li>per feed: URL, Title, Description, Link, Author </li></ul></ul></ul><ul><ul><ul><li>per entry: Title, Link, Summary, Date </li></ul></ul></ul><ul><li>_IG_FetchXmlContent(url, callback) Fetch XML content. Returns response as XML object. </li></ul><ul><ul><li>Useful when fetching XML feeds with no standard format. </li></ul></ul><ul><ul><li>Extract any data that you need. </li></ul></ul><ul><li>_IG_FetchContent(url, callback) Fetch content. Returns response as text. </li></ul><ul><ul><li>Useful when fetching and screen-scraping HTML from the response </li></ul></ul>
    25. 25. Tech Tip 2: Fetching Remote Content <div id=&quot;container&quot;></div> <script> function callback(response) { // Iterate through each entry and generate HTML to be inserted var html = new Array(); for (var n = 0; n < response.Entry.length; n++) { var entry = response.Entry[n]; html.push('<a href=&quot;' + entry.Link + '&quot;>' + entry.Title + '</a>' + '<div>' + entry.Summary + '</div>'); } _gel('container').innerHTML = html.join('<hr>'); } // Fetch 3 entries from Google News Atom feed and include summaries _IG_FetchFeedAsJSON(&quot;http://news.google.com/?output=atom&quot;, callback, 3, true); </script> <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <feed version=&quot;0.3&quot; xml:lang=&quot;en&quot; xmlns=&quot;http://purl.org/atom/ns#&quot;> <generator>NFE/1.0</generator> <title>Google News</title> … </feed> http://news.google.com?output=atom
    26. 26. Tech Tip 2: Fetching Remote Content <ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> </li></ul><ul><li><Module> </li></ul><ul><li><ModulePrefs title=&quot;Page Weight Example&quot; /> </li></ul><ul><li><UserPref name=&quot;url&quot; display_name=&quot;URL&quot; datatype=&quot;string&quot; required=&quot;true&quot; default_value=&quot;http://www.google.com/&quot;/> </li></ul><ul><li><Content type=&quot;html&quot;><![CDATA[ </li></ul><ul><li><script type=&quot;text/javascript&quot;> </li></ul><ul><li>function onLoadHandler() { </li></ul><ul><li>var url = _gel(&quot;url&quot;).value; </li></ul><ul><li>_gel(&quot;count&quot;).innerHTML = &quot;&quot;; </li></ul><ul><li>_IG_FetchContent(url, function (response) { </li></ul><ul><li>if (response == null) { </li></ul><ul><li>_gel(&quot;count&quot;).innerHTML = &quot;<i>Invalid data.</i>&quot;; </li></ul><ul><li>} else { </li></ul><ul><li>countCharsAndDisplay(response); </li></ul><ul><li>} </li></ul><ul><li>}); </li></ul><ul><li>} </li></ul><ul><li>function countCharsAndDisplay(response) { </li></ul><ul><li>_gel(&quot;count&quot;).innerHTML = response.length; </li></ul><ul><li>} </li></ul><ul><li>_IG_RegisterOnloadHandler(onLoadHandler); </li></ul><ul><li></script> </li></ul><ul><li><div style=&quot;font-size:0.8em&quot;> </li></ul><ul><li>Page <input type=&quot;text&quot; id=&quot;url&quot; value=&quot;__UP_url__&quot;/> </li></ul><ul><li><div>Weight: <span id=&quot;count&quot; style=&quot;color:green&quot;>&nbsp;</span></div> </li></ul><ul><li><input type=&quot;button&quot; value=&quot;Recalculate&quot; onclick=&quot;onLoadHandler()&quot;/> </li></ul><ul><li>]]></Content> </li></ul><ul><li></Module> </li></ul>
    27. 27. Tech Tip 3: Internationalize! <ul><li>Support multiple languages in a single gadget </li></ul><ul><li>Increase success in other countries </li></ul><ul><li>Specify supported languages in your gadget XML and iGoogle automatically loads the right one </li></ul>Hello World <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> <Module> <ModulePrefs title=“ __ MSG_title__ &quot;> <Locale lang=“en” messages=“en.xml” /> <Locale lang=“ja” messages=“ja.xml” /> </ModulePrefs> <Content type=&quot;html&quot;><![CDATA[ __MSG_hello__ ]]></Content> </Module> hello.xml <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> <messagebundle> <msg name=“title”> Title </msg> <msg name=“hello”> Hello, World! </msg> </messagebundle> en.xml <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> <messagebundle> <msg name=“title”> 題名 </msg> <msg name=“hello”> こんにちは世界 </msg> </messagebundle> ja.xml
    28. 28. Tech Tip 4: Storing State <ul><li>Example: Simple Notes Gadget </li></ul><ul><li>User creates notes and saves them in iGoogle </li></ul><ul><li>Remember user’s notes whenever coming back to the page. </li></ul><ul><li>Let the user set a different background color for the gadget </li></ul>
    29. 29. Tech Tip 4: Storing State <ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> </li></ul><ul><li><Module> </li></ul><ul><li><ModulePrefs title=&quot;Note&quot; height=&quot;80&quot;> </li></ul><ul><li><Require feature=&quot;setprefs&quot;/> </li></ul><ul><li></ModulePrefs> </li></ul><ul><li><UserPref name=&quot;text&quot; default_value=&quot;Type text here.” </li></ul><ul><li>datatype=&quot;hidden&quot;/> </li></ul><ul><li><UserPref name=&quot;color&quot; display_name=&quot;Color” default_value=&quot;#ffffcc&quot; datatype=&quot;enum&quot;>  <EnumValue display_value=&quot;Yellow&quot; value=&quot;#ffffcc&quot;/>  <EnumValue display_value=&quot;Blue&quot; value=&quot;#e5ecf9&quot;/>  <EnumValue display_value=&quot;Green&quot; value=&quot;#e0eee0&quot;/> </li></ul><ul><li></UserPref> </li></ul><ul><li><Content type=&quot;html&quot;><![CDATA[ </li></ul><ul><li><script> </li></ul><ul><li>function save() { </li></ul><ul><li>var prefs = new _IG_Prefs(); </li></ul><ul><li>prefs.set(&quot;text&quot;, _gel(‘note’).value); </li></ul><ul><li>} </li></ul><ul><li></script> </li></ul><ul><li><style> </li></ul><ul><li>#container { </li></ul><ul><li>background-color: __UP_color__; </li></ul><ul><li>text-align: center;   padding:6px; </li></ul><ul><li>} </li></ul><ul><li></style> </li></ul><ul><li><div id=container> </li></ul><ul><li><div><textarea id=&quot;note&quot;/>__UP_text__</textarea></div> </li></ul><ul><li><input type=&quot;button&quot; value=&quot;Save Note&quot; onclick=&quot;save()&quot; /> </li></ul><ul><li></div> </li></ul><ul><li>]]></Content> </li></ul><ul><li></Module> </li></ul>
    30. 30. Tech Tip 5: Caching External Resources <ul><li>Facts: </li></ul><ul><ul><li>Google caches all gadget XML files </li></ul></ul><ul><ul><li>Google caches all requests going through_IG_Fetch…() methods. </li></ul></ul><ul><ul><li>Gadgets receive tons of traffic (Date & Time gadget currently at 156M pvs/week) </li></ul></ul><ul><li>Remaining Problem: </li></ul><ul><ul><li>Gadgets often embed external resources hosted on third-party servers, e.g. images, Flash </li></ul></ul><ul><ul><li>Hosting servers melt down because they cannot handle all the requests </li></ul></ul><ul><li>Solution: </li></ul><ul><ul><li>Use API methods to cache all embedded resources on iGoogle </li></ul></ul><ul><ul><ul><li>_IG_GetImage(url) - Returns HTML image fetched from the cache </li></ul></ul></ul><ul><ul><ul><li>_IG_GetImageUrl(url) - Returns URL used to fetch the image via cache </li></ul></ul></ul><ul><ul><ul><li>_IG_GetCachedUrl(url) - Returns URL used to fetch the resource via cache </li></ul></ul></ul>
    31. 31. Tech Tip 5: Caching External Resources <ul><li>Caching images </li></ul><ul><li>Caching Flash </li></ul><img id=&quot;goImg&quot; src=&quot;&quot; width=100 height=150 /> <script> _gel(&quot;goImg&quot;).src = _IG_GetImageUrl(&quot;http://domainA.com/go.gif&quot;); </script> <div id=&quot;container&quot;></div> <script> var cacheUrl = _IG_GetCachedUrl(‘http://mydomain.com/flashvideo.swf’); _IG_EmbedFlash(cacheUrl, ‘container’, { width: 300, height: 250 }); </script>
    32. 32. Advanced API <ul><li>Gadget-to-gadget communication: </li></ul><ul><ul><li>Read http :// www . google . com / apis / gadgets / pubsub . html </li></ul></ul><ul><li>It’s new and cool </li></ul>
    33. 33. Feeds in tabs step-by-step <ul><li>Fetches and displays multiple RSS/Atom feeds </li></ul><ul><li>Uses multiple API features: </li></ul><ul><ul><li>tabs, dynamic-height, analytics, setprefs </li></ul></ul><ul><li>Highly configurable </li></ul><ul><ul><li>Feed URLs </li></ul></ul><ul><ul><li>Font size </li></ul></ul><ul><ul><li>Number of feed entries to display </li></ul></ul><ul><ul><li>Mor e </li></ul></ul>
    34. 34. Building a Gadget <ul><li>Start small with a simple gadget XML that contains bare essentials </li></ul><ul><li>Don’t worry about gadget metadata or UserPrefs yet. </li></ul><ul><li>Focus on the content. Customize the gadget later. </li></ul><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> <Module> <ModulePrefs title=&quot;Feeds in Tabs&quot; height=&quot;250&quot;/> <Content type=&quot;html&quot;><![CDATA[ Here's my gadget content! ]]></Content> </Module>
    35. 35. Building a Gadget <ul><li>Add tabs to the gadget using the API Tabs library </li></ul><ul><li>Generate unique content for each tab via callback </li></ul><ul><li>Use tab.getIndex() to determine which tab is selected </li></ul><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?> <Module> <ModulePrefs title=&quot;Feeds in Tabs&quot; height=&quot;250&quot;> <Require feature=&quot;tabs&quot;/> </ModulePrefs> <Content type=&quot;html&quot;><![CDATA[ <script> var tabs = new _IG_Tabs(); tabs.addDynamicTab('Feed 1', _IG_Callback(tabCallback)); tabs.addDynamicTab('Feed 2', _IG_Callback(tabCallback)); tabs.addDynamicTab('Feed 3', _IG_Callback(tabCallback)); tabs.addDynamicTab('Feed 4', _IG_Callback(tabCallback)); function tabCallback(domId) { var tab = tabs.getSelectedTab(); _gel(domId).innerHTML = 'my content for tab # ' + (tab.getIndex() + 1); } </script> ]]> </Content> </Module>
    36. 36. Building a Gadget <ul><li>Create an input mechanism for Atom/RSS feed URLs </li></ul><ul><li>Add a UserPref to accept feed URLs for each tab </li></ul><ul><li>Populate ‘default_value’ attribute with initial feed URL to be loaded </li></ul><UserPref name=&quot;feed1&quot; display_name=&quot;Feed 1: URL&quot; datatype=&quot;string&quot; default_value=&quot;http://groups.google.com/group/Google-Gadgets-API/feed/atom_v1_0_topics.xml&quot;/> <UserPref name=&quot;feed2&quot; display_name=&quot;Feed 2: URL&quot; datatype=&quot;string&quot; default_value=&quot;http://code.google.com/feeds/updates.xml&quot;/> <UserPref name=&quot;feed3&quot; display_name=&quot;Feed 3: URL&quot; datatype=&quot;string&quot; default_value=&quot;http://www.google.com/calendar/feeds/developer-calendar@google.com/public/basic&quot;/> <UserPref name=&quot;feed4&quot; display_name=&quot;Feed 4: URL&quot; datatype=&quot;string&quot; default_value=&quot;http://googleblog.blogspot.com/atom.xml&quot;/>
    37. 37. Building a Gadget <ul><li>Read the feed URL from the UserPref </li></ul><ul><li>Fetch the feed and get a JSON response back in a callback </li></ul><ul><li>Hardcode the number of feed entries to display and always show entry summaries </li></ul><script> var tabs = new _IG_Tabs(); tabs.addDynamicTab('Feed 1', _IG_Callback(tabCallback)); tabs.addDynamicTab('Feed 2', _IG_Callback(tabCallback)); tabs.addDynamicTab('Feed 3', _IG_Callback(tabCallback)); tabs.addDynamicTab('Feed 4', _IG_Callback(tabCallback)); function tabCallback(domId) { var tab = tabs.getSelectedTab(); var prefs = new _IG_Prefs(); var feedUrl = prefs.getString('feed' + (tab.getIndex() + 1)); _IG_FetchFeedAsJSON( feedUrl, function(feed) { // JSON response received. }, 3, // # of entries true // show summaries } } </script>
    38. 38. Building a Gadget <ul><li>Use the JSON response object to generate the HTML </li></ul><ul><ul><li>feed.Title, feed.Link, feed.Author, feed.Description, feed.Entry[] </li></ul></ul><ul><ul><li>entry.Title, entry.Link, entry.Summary </li></ul></ul>function(feed) { // JSON response received. var container = _gel(domId); if (typeof feed == &quot;undefined&quot; || typeof feed.Entry == &quot;undefined&quot;) { container.innerHTML = '<div class=&quot;statusLabel&quot;>Invalid feed URL:<br>' + feedUrl + '</div>'; } else { // Fetch feed successful. Generate HTML content from returned JSON object. // Create feed header containing title and description. var html = new Array(); html.push('<div class=&quot;feedHeader&quot;>'); html.push('<div class=&quot;feedTitle&quot;>'); html.push((feed.Link != &quot;&quot;) ? '<a target=&quot;_blank&quot; href=&quot;' + _hesc(feed.Link) + '&quot;>' + _hesc(feed.Title) + '</a>' : _hesc(feed.Title)); html.push((feed.Author != &quot;&quot;) ? '<span class=&quot;feedAuthor&quot;> by ' + _hesc(feed.Author) + '</span>' : &quot;&quot;); html.push('</div>'); html.push('<div class=&quot;feedDesc&quot;>' + _hesc(feed.Description) + '</div>'); html.push('</div>'); // Iterate through each feed entry and generate list of content. html.push('<ul class=&quot;feedList&quot;>'); for (var n = 0; n < feed.Entry.length; n++) { var entry = feed.Entry[n]; html.push('<li>'); html.push('<a target=&quot;_blank&quot; href=&quot;' + entry.Link + '&quot;><b>' + _hesc(entry.Title) + '</b></a>'); if (typeof entry.Summary != &quot;undefined&quot; && entry.Summary != &quot;&quot;) { var summary = document.createElement(&quot;div&quot;); summary.innerHTML = entry.Summary; html.push('<div class=&quot;entrySummary&quot;>'); html.push(summary.innerHTML); html.push('</div>'); } html.push('<div class=&quot;entryTimestamp&quot;>[' + new Date(entry.Date * 1000).toLocaleString() + ']</div>'); html.push('</li>'); } html.push('</ul>'); container.innerHTML = html.join(&quot;&quot;); } }
    39. 39. Building a Gadget <ul><li>Add CSS rules to stylize the output </li></ul><ul><li>Remember screen real estate is very limited: </li></ul><ul><ul><li>Decrease the size of your font-sizes </li></ul></ul><ul><ul><li>Use minimal amount of padding/margin </li></ul></ul><ul><ul><li>Single border lines are good at separating sections with minimal space </li></ul></ul><ul><li>Apply formatting to tabs, e.g. font-size, width, etc. </li></ul><style type=&quot;text/css&quot;> .tablib_table { font-size: 0.7em; } .tablib_selected, .tablib_unselected { width: 23%; } .statusLabel { font-size: 0.75em; font-style: italic; padding-top: 10px; text-align: center; } .feedHeader { padding-top: 5px; font-size: 0.7em; } .feedHeader .feedTitle { font-weight: bold; font-size: 1.1em; } .feedHeader .feedAuthor { font-weight: normal; font-size: 0.8em; color: #676767; } .feedList { font-size: 0.7em; margin: 0px; padding: 0px 0px 5px 0px; border-bottom: 1px solid #aaaaaa; } .feedList li { margin-top: 5px; padding: 3px 3px 0px 3px; border-top: 1px solid #aaaaaa; } .feedList li div.entryTitle a { font-weight: bold; } .feedList li div.entryTimestamp { font-size: 0.95em; font-style: italic; color: #676767; } </style>
    40. 40. Building a Gadget: Almost Done <ul><li>Are we done yet? Almost… </li></ul><ul><li>What’s missing? </li></ul><ul><ul><li>dynamic-height, to auto-resize the height </li></ul></ul><ul><ul><li>analytics, to track performance </li></ul></ul>… _IG_FetchFeedAsJSON( feedUrl, function(feed) { // Generate HTML and insert into DOM … // Resize iframe height to fit content. _IG_AdjustIFrameHeight(); }, 3, // # of entries true // show summaries ); … _IG_RegisterOnloadHandler(function() { _IG_Analytics(&quot;UA-676947-9&quot;, &quot;/feeds_tabs&quot;); }); <ModulePrefs title=&quot;Feeds in Tabs&quot; height=&quot;250&quot;> <Require feature=&quot;tabs&quot;/> <Require feature=&quot;dynamic-height&quot;/> </ModulePrefs>
    41. 41. Building a Gadget: Almost Done <ul><li>Dynamic height is convenient and makes users happy </li></ul><ul><li>Analytics lets you track progress on your gadget </li></ul>
    42. 42. Building a Gadget: Final Touches <ul><li>Users love options. It’s easy to extend your gadget to be more customizable by using UserPrefs. </li></ul><ul><li>Think about the gadget from a user’s perpective and imagine what parts you’d like to customize. </li></ul><ul><li>Here’s a few customizations that can easily be added: </li></ul><ul><ul><li>gadget title </li></ul></ul><ul><ul><li>custom tab labels </li></ul></ul><ul><ul><li>number of feed entries to display </li></ul></ul>
    43. 43. Building a Gadget: Final Touches <ul><li>Let the gadget title be customizable </li></ul><ul><li>Customize each tab label </li></ul><ModulePrefs title=&quot; __UP_title__ &quot; height=&quot;250&quot;> … </ModulePrefs> <UserPref name=&quot;title&quot; display_name=&quot;Gadget Title&quot; default_value=&quot;Feeds in Tabs&quot;/> <UserPref name=&quot;feedTitle1&quot; display_name=&quot;Feed 1: Title&quot; datatype=&quot;string&quot; default_value=&quot;Gadgets API&quot;/> <UserPref name=&quot;feedTitle2&quot; display_name=&quot;Feed 2: Title&quot; datatype=&quot;string&quot; default_value=&quot;Google Code&quot;/> <UserPref name=&quot;feedTitle3&quot; display_name=&quot;Feed 3: Title&quot; datatype=&quot;string&quot; default_value=&quot;Dev Events&quot;/> <UserPref name=&quot;feedTitle4&quot; display_name=&quot;Feed 4: Title&quot; datatype=&quot;string&quot; default_value=&quot;Google Blog&quot;/> var prefs = new _IG_Prefs(); tabs.addDynamicTab( prefs.getString('feedTitle1') , _IG_Callback(tabCallback)); tabs.addDynamicTab( prefs.getString('feedTitle2') , _IG_Callback(tabCallback)); tabs.addDynamicTab( prefs.getString('feedTitle3') , _IG_Callback(tabCallback)); tabs.addDynamicTab( prefs.getString('feedTitle4') , _IG_Callback(tabCallback)); JavaScript code:
    44. 44. Building a Gadget: Final Touches <ul><li>Let user select how many feed entries to display </li></ul><UserPref name=&quot;entries&quot; display_name=&quot;# of Entries&quot; datatype=&quot;enum&quot; default_value=&quot;3&quot;> <EnumValue value=”1&quot;/> <EnumValue value=”2&quot;/> <EnumValue value=&quot;3&quot;/> <EnumValue value=&quot;4&quot;/> <EnumValue value=&quot;5&quot;/> <EnumValue value=&quot;6&quot;/> <EnumValue value=&quot;7&quot;/> <EnumValue value=&quot;8&quot;/> <EnumValue value=&quot;9&quot;/> </UserPref> _IG_FetchFeedAsJSON( feedUrl, function(feed) { … }, prefs.getInt('entries'), // # of entries true // show summaries ); JavaScript code:
    45. 45. Building a Gadget: Final Touches <ul><li>Prepare your gadget for submission </li></ul><ul><li>Add important metadata to make your gadget more discoverable in the directory. </li></ul><ModulePrefs title=&quot;__UP_title__&quot; directory_title=&quot;Feeds in Tabs&quot; description=&quot;Read up to four Atom or RSS feeds from within a single gadget using tabs. Customize the feed URLs, titles, control how many entries to receive and more.&quot; author=&quot;Daniel L.&quot; author_email=&quot;daniel.feedback+feedstabs@gmail.com&quot; author_affiliation=&quot;Google Inc.&quot; author_location=&quot;Mountain View, CA&quot; screenshot=&quot;/ig/modules/feeds_tabs.png&quot; thumbnail=&quot;/ig/modules/feeds_tabs-thm.png&quot; height=&quot;250&quot; scrolling=&quot;false&quot; singleton=&quot;false&quot;>
    46. 46. Now What? <ul><li>I’ve built my gadget, now what? </li></ul>
    47. 47. Submit your Gadget <ul><li>Users will discover your content through the public content directory. </li></ul><ul><li>Submit gadget to the content directory ( http://www. google . com/ig/directory ). </li></ul><ul><li>Your gadget appears in the directory & is ranked according to popularity. </li></ul><ul><li>Users find your gadget via keywords/categories that describe your gadget. </li></ul><ul><li>Users can add your gadget to their website directly from the directory. </li></ul>
    48. 48. It’s all in the first impression… <ul><li>Users will have thousands of gadgets to choose from in the gadget directory, so you must attract the user to choose your gadget when they are browsing through the directory: </li></ul><ul><li>Find a catchy title – make it short and descriptive – there should be no doubt as to the general function of the gadget from the title </li></ul><ul><li>Design an attractive thumbnail – images are important as this may be the only thing that attracts the user to your gadget from the choice of the gadget directory. Make the thumbnail stand out to encourage that first click. </li></ul><ul><li>Don’t forget to use the button on your website to promote your gadget </li></ul>
    49. 49. Promote your Gadget <ul><li>Your gadget’s success is dependant upon user uptake. Some of the best ways to promote your gadget are: </li></ul><ul><li>Promote it on your own site via the button. </li></ul><ul><li>Include a link to your gadget in your mailing lists, blogs and feeds. </li></ul><ul><li>Educate users on the &quot;send to a friend&quot; link so your users can virally spread the word. </li></ul>
    50. 50. Track your Gadget <ul><li>Tracking your gadget allows you to continually optimize it to provide the best experience for your users. </li></ul><ul><li>To get basic data, the content directory offers an overview of your gadget's usage and performance, and allows users to send you direct feedback. </li></ul><ul><li>Get more detailed data with Google Analytics ( http://www. google .com/analytics/ ) such as: </li></ul><ul><ul><li>no. of pageviews </li></ul></ul><ul><ul><li>unique visits </li></ul></ul><ul><ul><li>traffic sources </li></ul></ul><ul><ul><li>traffic to your website </li></ul></ul><ul><ul><li>% returning users </li></ul></ul>
    51. 51. Hosting & Publishing <ul><li>Hosting </li></ul><ul><ul><li>Google Gadgets Editor </li></ul></ul><ul><ul><li>Google code </li></ul></ul><ul><ul><li>Googlepages </li></ul></ul><ul><ul><li>Your own site </li></ul></ul><ul><li>Publishing </li></ul><ul><ul><li>Submitting to the directory </li></ul></ul><ul><ul><li>Getting people to use it </li></ul></ul>
    52. 52. Want to know more? <ul><li>Google Gadgets API Docs h ttp://www.google.com/apis/gadgets </li></ul><ul><li>iGoogle http://www.google.com/ig </li></ul><ul><li>Google Gadgets For Your Webpage http://www.google.com/ig/directory?synd=open </li></ul><ul><li>Top Gadget Authors http://www.google.com/ig/authors </li></ul><ul><li>Discussion Group http://groups.google.com/group/Google-Gadgets-API </li></ul><ul><li>FAQ / Knowledge Base http://code.google.com/support/bin/topic.py?topic=10027 </li></ul><ul><li>Google Distribution Guidelines http://www. google .com/webmasters/gadgets/guidelines.html </li></ul><ul><li>Getting Started ( http://code. google . com/apis/gadgets/docs/gs .html ) </li></ul><ul><li>Developer Guide ( http://code. google . com/apis/gadgets/docs/dev_guide .html ) </li></ul><ul><li>Design Guidelines ( http://www. google .com/webmasters/gadgets/guidelines.html ) </li></ul><ul><li>Submit ( http://www. google . com/ig/submit ) </li></ul><ul><li>Promote ( http://www. google .com/webmasters/add.html ) </li></ul><ul><li>Google Analytics instructions ( http://code. google . com/apis/gadgets/tools .html#Analytics ) </li></ul><ul><li>Discussion Group ( htt p://groups.google.com/group/Google-Gadgets-API </li></ul><ul><li>FAQ / Knowledge Base ( http://code.google.com/support/bin/topic.py?topic=10027) </li></ul>

    ×