Putting It All Together

Now that we’ve examined data pipelining and templating, one thing should be blatantly obvious: these two features of the OpenSocial specification can significantly reduce the amount of code that you need to write, create a highly modularized environment to promote multiuser development, and generally simplify debugging and data retrieval to allow you to focus on more important aspects of your gadget, such as monetization and social features.

Up until now, we’ve explored the individual specifications for accessing and working with data. Now we will put together a few of the lessons that we have learned into a fully functional example that showcases some of the major uses for templating and data pipelining.

In this example, we’ll look at:

  • Capturing data sources through data pipelining HTTP Requests

  • Integrating data pipes into templates

  • Using expressions

  • Using loop structures

  • Using special variables

Our sample code will use the data pipelining specification to pull in two RSS feeds, one from www.reddit.com and the other from the San Francisco local news section of www.craigslist.org. Following that, we’ll create two separate pages that can be switched back and forth by tabs. These pages will use the templating specification to display the title, link, and date from these two feeds as styled, unordered lists. The general visual form that we will use for this application will mimic Figure 7-1.

Architecture of this chapter’s example, showcasing HTTP requests through an OpenSocial gadget

Figure 7-1. Architecture of this chapter’s example, showcasing HTTP requests through an OpenSocial gadget

First, we have to look at the foundation of our gadget XML file and the requirements that we need to include:

<?xml version="1.0" encoding="utf-8s"?>
<Module>
   <ModulePrefs title="Chapter rollup example"
                title_url="http://www.jcleblanc.com"
                description="Displays templating and data pipelining
                             specifications"
                author="Jonathan LeBlanc">
      <Require feature="opensocial-0.9"/>
      <Require feature="opensocial-data" />
      <Require feature="opensocial-templates" />
   </ModulePrefs>

Since the sample gadget that we are building will integrate functionality from data pipelining as well as templating, we need to require these features in our gadget:

  • At the very minimum, we should include version 0.9 of the OpenSocial specification as opensocial-0.9. (This is the minimum version that is needed to run both the features from data pipelining and templating.)

  • The data pipelining specification as opensocial-data.

  • The templating specification as opensocial-templates.

Now that our JavaScript feature requirements are in place in our core gadget, we can focus on the Content section that will house our gadget functionality:

<Content type="html">
   <![CDATA[
   <style type="text/css">
      #nav{ margin:5px 0 5px 15px;
            padding-top:10px; }
      #nav a{ background-color:#e8f0f4;
              border:1px solid #0c7099;
              border-bottom:0;
              color:#000;
              padding:6px 8px;
              margin-top:5px; }
      #nav a{ cursor:pointer;
              font-weight:bold; }
      #nav a.navOff{ background-color:#0c7099;
                     color:#fff; }
      #nav, .page{ font:12px arial,helvetica,sans-serif; }
      .page{ margin:5px 0;
             padding:5px;
             margin:0 10px 15px;
             background-color:#e8f0f4;
             border:1px solid #0c7099; }
      .page li{ list-style-type:none;
                padding:3px 10px 3px 0; }
      .textSmall{ font-size:10px; }
      .hide{ display:none; }
   </style>

We first need to specify the styles that will be used in the gadget. These styles will define the look of the anchor tags that are used for the page tabs, the layout for the pages, and the formatting of the data pipes as unordered lists.

Following the styles, we define the navigation of the gadget, which will allow us to switch between the two feed pages:

<div id="nav">
   <a id="linkCraigslist"
      onclick="switchNode('pageCraigslist', 'pageReddit', this)">
      Craigslist Local</a>
   <a id="linkReddit"
      onclick="switchNode('pageReddit', 'pageCraigslist', this)"
      class="navOff">Reddit</a>
</div>

Our navigation system consists of a div wrapping two anchor tags that are styled to look like tabs. To visualize the tab’s off state, we can set a class of navOff. Other than that, our anchor tags contain an onclick event that, when triggered, will call the switchNode(...) function to swap between the current page and the other page.

Our next task is to define the data pipe that will pull in the RSS feeds from www.reddit.com and www.craigslist.org:

<script type="text/os-data" xmlns:os="http://ns.opensocial.org/2008/markup">
   <os:HttpRequest key="feeds" href="http://query.yahooapis.com/v1/public/yql?
      q=select%20*%20from%20yql.query.multi%20where%20queries%3D%22select%20
      *%20from%20rss%20where%20url%3D'http%3A%2F%2Fwww.reddit.com%2F.rss'%3B
      select%20*%20from%20rss%20where%20url%3D'http%3A%2F%2Fsfbay.craigslist.
      org%2Fvnn%2Findex.rss'%22&format=json&debug=true"/>
</script>

As with some of our previous examples, we use the os:HttpRequest element to pull in our data feeds, using the Yahoo! Query Language to aggregate the sources. The YQL URL makes the request to the service, which in turn makes two separate RESTful requests to the two RSS sources and then binds the results into a single data pipe in JSON format. Our pipe is set to a key of feeds.

Next we will cover the visualization of these data sources through the templating specification:

<script type="text/os-template" require="feeds">
   <div id="pageReddit" class="page hide">
      <ul>
         <li repeat="${feeds.content.query.results.results[0].item}">
            <b>${Cur.title[0]}</b><br />
            <a href="${Cur.link}">${Cur.link}</a><br />
            <span class="textSmall">${Cur.pubDate}</a>
         </li>
      </ul>
   </div>
   <div id="pageCraigslist" class="page">
      <ul>
         <li repeat="${feeds.content.query.results.results[1].item}">
            <b>${Cur.title[0]}</b><br />
            <a href="${Cur.link}">${Cur.link}</a><br />
            <span class="textSmall">${Cur.date}</a>
         </li>
      </ul>
   </div>
</script>

Our template script block contains the require attribute stating that if the feeds data pipe is not available, the template should not be rendered with the data.

If feeds is available, the template will set up two div nodes, one set as visible and the other as hidden. Within these div nodes, or pages, we set up an unordered list. Then we use the repeat attribute of the templating specification to create an <li> node in the unordered list for each object in the associated RSS feed. Within each list item, we create markup to display the title, link, and current date for the appropriate RSS feed item.

Our last task is to define our JavaScript functionality to enable us to swap between the two different pages that we have defined:

      <script type="text/javascript">
         //swap the visibility of one page
         function switchNode(activate, deactivate, linkObj){
            //get page nodes to swap
            var showNode = document.getElementById(activate);
            var hideNode = document.getElementById(deactivate);

            //switch the display properties of the two pages
            hideNode.className = "page hide";
            showNode.className = "page";

            //swap link tab classes
            var linkAlt = (linkObj.id == "linkCraigslist") ?
                          document.getElementById("linkReddit") :
                          document.getElementById("linkCraigslist");
            linkObj.className = "";
            linkAlt.className = "navOff";
         };
      </script>
      ]]>
   </Content>
</Module>

Our JavaScript functionality layer consists of a single function, switchNode(...), which accepts three parameters:

activate

The ID of the page to be switched to a display status.

deactivate

The ID of the page to be hidden.

linkObj

The DOM node object representing the tab that was clicked. This determines the tab visualization states.

This is a simple function that has two responsibilities: swap the state of the pages, and swap the state of the tabs. We start out by swapping the pages, removing the hide class from the page to be displayed and adding the class to the page to be hidden. We then determine the tab that was clicked and the one that wasn’t, and swap the classes for those tabs as well.

When we render, we should be presented with a tabbed interface like Figure 7-2, which contains a basic application that allows you to read up on current news and topics.

This chapter’s example, showcasing HTTP requests in OpenSocial gadgets

Figure 7-2. This chapter’s example, showcasing HTTP requests in OpenSocial gadgets

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.205.235