Monday, December 14, 2009

Getting Started with Friend Connect

This blog post will cover two simple capabilities of Google Friend Connect: creating a social network and rating items in a table.  First, however, let's provide some motivation for science portals.

We've developed the QuakeSim portal for several years to support earthquake modeling research and education. A typical scenario, common in many other gateways, is for a user to set up and launch an application through a Web interface.  Web services are needed to both run the modeling code and preserve metadata about the run: the input parameters, the time the code was executed, the URLs of all the input, output, and error files, and so on.  We organize these metadata fields as projects owned by a particular user.  The metadata is modeled with JavaBeans and stored in object databases, although these are irrelevant technical details here.  It is also possible, and appropriate, to model the metadata as Atom/RSS, for example.

Let's look first at creating a little GFC social network of people who may be interested in looking at the metadata feeds.  You will need to create a Google account if you don't have one and register a URL with GFC.  Just use your development machine's URL, as you would with Google Maps.  Note the Site ID that you are assigned (it will be in the GFC URL of the projects you register).  You'll need to use this in your GFC applications.

To get started, you can generate code for lots of GFC applications.  Just save this generated HTML/JavaScript in files that can be loaded from your Web server.   If you want to use these as standalone pages, be sure to add <html> and <body> tags to the beginning and end of the document.  You can also embed the generated code into existing HTML pages.  To wrap the code as a gadget, just paste it in the CDATA section of an "html" gadget.

First, now, we need a GFC code snippet to manage logins and mini-social networks.  The GFC way for doing this is shown below:

<html>
<body>
  <!-- Include the Google Friend Connect javascript library. -->
  <script type="text/javascript" src="http://www.google.com/friendconnect/script/friendconnect.js"></script>
  <!-- Define the div tag where the gadget will be inserted. -->
  <div id="div-4719709228063302739" style="width:276px;border:1px solid #cccccc;"></div>
  <!-- Render the gadget into a div. -->
<script type="text/javascript">
var skin = {};
skin['BORDER_COLOR'] = '#cccccc';
skin['ENDCAP_BG_COLOR'] = '#e0ecff';
skin['ENDCAP_TEXT_COLOR'] = '#333333';
skin['ENDCAP_LINK_COLOR'] = '#0000cc';
skin['ALTERNATE_BG_COLOR'] = '#ffffff';
skin['CONTENT_BG_COLOR'] = '#ffffff';
skin['CONTENT_LINK_COLOR'] = '#0000cc';
skin['CONTENT_TEXT_COLOR'] = '#333333';
skin['CONTENT_SECONDARY_LINK_COLOR'] = '#7777cc';
skin['CONTENT_SECONDARY_TEXT_COLOR'] = '#666666';
skin['CONTENT_HEADLINE_COLOR'] = '#333333';
skin['NUMBER_ROWS'] = '4';
google.friendconnect.container.setParentUrl('/gadgets-repo/' /* location of rpc_relay.html and canvas.html */);
google.friendconnect.container.renderMembersGadget(
 { id: 'div-4719709228063302739',
   site: '16707400350554686557' },
  skin);
</script>
</body>
</html>

The site ID in the above example is one of my site IDs.  You would need to replace this with your site ID.

This is just generated code from the GFC site.  I only added the (necessary) HTML and BODY tags so that it would work as a standalone  page. Load this new HTML page in your browser and use it to sign in and add people to your network.  If you are already signed in to a Google site (say to iGoogle) on the same browser, then the GFC widget above should detect this through cookies. Note that this network should apply only to a specific site ID, so you can create multiple social networks.  One difficulty here of course is that all of this is external to your legacy portal's authentication system.

Our next example is a rating widget that can be embedded into an existing page.  Recall our motivating problem was an archive list of project metadata associated with a particular user's previous code submissions.   In QuakeSim, we render this information using JSF datatables populated with JavaBeans pulled from an object database, but this detail is irrelevant here.  In the browser, the generated page would look something like the HTML below:

<html>
<body>
<!-- Include the Google Friend Connect javascript library. -->
<script type="text/javascript" src="http://www.google.com/friendconnect/script/friendconnect.js"></script>
<!-- Define the div tag where the gadget will be inserted. -->
<table border="1">
  <tr>
     <th>Project</th><th>ID</th><th>Date</th><th>Input File</th><th>Output File</th><th>Recommend</th>
  </tr>
  <tr>
     <td>
        Northridge
     </td>
     <td>
        123456789
     </td>
     <td>
        08:43 GMT, Dec 14, 2009
     </td>
     <td>
        <a href="http://www.quakesim.org/mpierce/northridge/input">Input</a>
     </td>
     <td>
        <a href="http://www.quakeims.org/mpierce/northridge/output">Output</a>
     </td>
     <td>
        <div id="div-1095870898733665271" style="width:100%;"></div>
     </td>
  </tr>
  <tr>
     <td>
        Plieto
     </td>
     <td>
        987654321
     </td>
     <td>
        10:12 GMT, Dec 12, 2009
     </td>
     <td>
        <a href="http://www.quakesim.org/mpierce/plieto/input">Input</a>
     </td>
     <td>
        <a href="http://www.quakeims.org/mpierce/plieto/output">Output</a>
     </td>
     <td>
        <div id="div-123456789" style="width:100%;"></div>
     </td>
  </tr>
</table>

<script type="text/javascript">
var skin = {};
skin['HEIGHT'] = '21';
skin['BUTTON_STYLE'] = 'compact';
skin['BUTTON_TEXT'] = 'Recommend it!';
skin['BUTTON_ICON'] = 'default';
google.friendconnect.container.setParentUrl('/gadgets-repo/' /* location of rpc_relay.html and canvas.html */);
google.friendconnect.container.renderOpenSocialGadget(
 { id: 'div-1095870898733665271',
   url:'http://www.google.com/friendconnect/gadgets/recommended_pages.xml',
   height: 21,
   site: '16707400350554686557',
   'view-params':{"pageUrl":"http://www.quakesim.org/users/mpierce/northridge","pageTitle":"Northridge","docId":"recommendedPages"}
 },
  skin);

google.friendconnect.container.renderOpenSocialGadget(
 { id: 'div-123456789',
   url:'http://www.google.com/friendconnect/gadgets/recommended_pages.xml',
   height: 21,
   site: '16707400350554686557',
   'view-params':{"pageUrl":"http://www.quakesim.org/users/mpierce/plieto","pageTitle":"Plieto","docId":"recommendedPages"}
 },
  skin);
</script>
</body>
</html>


The main thing to notice is that each project has been given a URL.  I use http://www.quakesim.org/users/mpierce as the base--see the pageUrl parameter in the code above. This assumes a REST style programming model for the metadata services, which unfortunately isn't implemented yet (but now I have some motivation to do it...).  The javascript at the end is a slightly modified version of generated GFC code.  The values for the view-params (pageURL, pageTitle) are generated and should be taken from entries in your project database.


Each entry in the table will have a button with "Recommend It" in the final column.  You can get a list of recommended projects in a page like the one below (again, this is generated by an online GFC tool):

<html>
<body>
<!-- Include the Google Friend Connect javascript library. -->
<script type="text/javascript" src="http://www.google.com/friendconnect/script/friendconnect.js"></script>
<!-- Define the div tag where the gadget will be inserted. -->
<div id="div-6585877907190446397" style="width:300px;border:1px solid #cccccc;"></div>
<!-- Render the gadget into a div. -->
<script type="text/javascript">
var skin = {};
skin['BORDER_COLOR'] = '#cccccc';
skin['ENDCAP_BG_COLOR'] = '#e0ecff';
skin['ENDCAP_TEXT_COLOR'] = '#333333';
skin['ENDCAP_LINK_COLOR'] = '#0000cc';
skin['ALTERNATE_BG_COLOR'] = '#ffffff';
skin['CONTENT_BG_COLOR'] = '#ffffff';
skin['CONTENT_LINK_COLOR'] = '#0000cc';
skin['CONTENT_TEXT_COLOR'] = '#333333';
skin['CONTENT_SECONDARY_LINK_COLOR'] = '#7777cc';
skin['CONTENT_SECONDARY_TEXT_COLOR'] = '#666666';
skin['CONTENT_HEADLINE_COLOR'] = '#333333';
skin['HEADER_TEXT'] = 'Recommended stories';
skin['RECOMMENDATIONS_PER_PAGE'] = '5';
google.friendconnect.container.setParentUrl('/gadgets-repo/' /* location of rpc_relay.html and canvas.html */);
google.friendconnect.container.renderOpenSocialGadget(
 { id: 'div-6585877907190446397',
   url:'http://www.google.com/friendconnect/gadgets/recommended_pages.xml',
   site: '16707400350554686557',
   'view-params':{"docId":"recommendedPages"}
 },
  skin);
</script>
</body>
</html>

Integration Thoughts: the main issue I see in the above example is integrating the GFC authentication and authorization system with your portal. We'll look at this next.  Also, one of the strengths of GFC is the simplicity of the JavaScript code exposed to the end developer.  Gateways have long had a problem integrating in programming-literate computational scientists who just didn't care to learn Enterprise Java and similar things. To retain this advantage of GFC, we would probably need to consider building our own higher level gadget that queries our project database and is rendered with google.friendconnect.container.renderOpenSocialGadget() GFC call.

No comments: