The full code for this sample is available at https://github.com/jcleblanc/programming-social-applications/blob/master/chapter_7/pipeline_with_templating.xml.
We’ve explored the vast potential and power in both data pipelining and templates, which integrate rich data sets and visualization templates, respectively, into a gadget. Alone, each feature is a wonderful addition to any gadget, but their power really lies in being married into one cohesive unit.
Let’s take a look at an example of how we can merge these two technologies together to build out a data set based on the result set of an external data source. In this example, we want to scrape the main page of http://www.reddit.com to capture its top headlines. Using this data source, we want to display all links within our gadget.
Our first task is to build out the ModulePrefs
section of
our OpenSocial gadget, integrating all data pipelining and templating
requirements:
<?xml version="1.0" encoding="utf-8"?> <Module> <ModulePrefs title="Reddit Headline Fetch" title_url="http://www.jcleblanc.com" description="Obtains reddit.com headlines via YQL using data pipelining and visualizes using OS templates" author="Jonathan LeBlanc"> <Require feature="opensocial-0.9"/> <Require feature="opensocial-data" /> <Require feature="opensocial-templates" /> </ModulePrefs>
Within the ModulePrefs
node, we
need to set up the Require
elements for
the features that we will need in our gadget. For this use case, we need
to implement at least OpenSocial version 0.9 (opensocial-0.9
) as well as the OpenSocial data
(opensocial-data
) and OpenSocial
templates (opensocial-templates
)
features.
The next section, where we actually use these features, is our
Content
section. This is where we
make an external data request to scrape http://www.reddit.com and loop through all headlines to
display them in the gadget:
<Content type="html"> <![CDATA[ <script type="text/os-data" xmlns:os="http://ns.opensocial.org/2008/markup"> <os:HttpRequest key="reddit" href="http://query.yahooapis.com/v1/public/ yql?q=select%20*%20from%20html%20where%20url%3D%22http%3A%2F%2F www.reddit.com%22%20and%0A%20%20%20%20%20%20xpath%3D'%2F%2Fa%5B %40class%3D%22title%22%5D'&format=json"/> </script> <script type="text/os-template" require="reddit"> <ul> <li repeat="${reddit.content.query.results.a}"> <a href="${Cur.href}">${Cur.content}</a> </li> </ul> </script> ]]> </Content> </Module>
The first script
block in our
Content
section is the data
pipelining feature. Within the data pipe, we make an os:HttpRequest
to get an external data source and set the key for the return
data to reddit
. The href
source of our data is an HTML page-scrape
query using the Yahoo! Query Language (YQL). This query obtains the HTML from http://www.reddit.com, drills down to the headlines using
an XPath string, and returns all headline results as a JSON
object.
Once the data returns, the reddit
variable should comprise an array of
anchor objects. This data source will look something like the
following:
"a": [ { "class": "title", "href": "http://www.youtube.com/watch?v=Lk3ibIGKTYA", "rel": "nofollow", "content": ""Your car has a broken headlight and, oh no, pack of wolves coming down the road"" }, { "class": "title", "href": "http://imgur.com/6DfnY.png", "content": "I'm not sure which system this is referring to [PIC]" }, ...
We then define a second script
block for our template, requiring our reddit
variable in order to render the
template. Our markup sets up an unordered list and then repeats the
<li>
tags for each anchor tag
returned in our result set. Each <li>
will then contain an anchor tag
pointing to the headline URL and display the text of the headline for
the link.
With just a minimal amount of effort, we have laid the foundation for a gadget that is based on a dynamic list of data, providing users with new results each time they visit the gadget. In doing so, we are building our gadget to update its content without us ever having to lift a finger after the initial construction is complete.
18.223.170.223