OpenSocial Specification: What's Next?

Chewy Trewhella Developer Advocate - Google July 09

• What is OpenSocial? • Spec process o getting from 0.7 to 0.8 and beyond • Deeper dives on what's coming next o A) Javascript/XML enhancements o B) RESTful APIs o C) Templating language and tags • Q&A

What is OpenSocial?

OpenSocial OpenSocial is a set of APIs for building social applications on the web. Many sites, one API Common APIs mean you only have to learn once in order to build for multiple websites. Server optional OpenSocial is built upon Google Gadget technology, so you can build a great, viral social app without owning a single server.

Why OpenSocial?

Why OpenSocial?

Arnie says: OpenSocial Rules!

Spec Definition Process
– OpenSocial 0.7 Spec
o o o o o

– Spec Process Proposal – Tracking Changes – Final Review

– OpenSocial 0.8 Spec

1) OpenSocial 0.7 Spec

2) Spec Process Proposal

3) Tracking Changes

4) Final Review

5) OpenSocial 0.8 Spec

Compatibility and Migration
• Most containers will continue to support 0.7 apps with no changes. • Most 0.8 changes are backwards compatible. • To use new 0.8 features, you might have to update small amounts of existing 0.7 app code.

A) Javascript/XML enhancements B) RESTful APIs C) Templating language and tags

OpenSocial 0.8 - What's New
• Cleanup, convenience, capability • Dozens of changes o More data about People o Richer querying capabilities o Integration features for containers o Mechanisms to improve security o OAuth support o More expressiveness for gadget developers o Performance optimization capabilities o Much more!

Javascript/XML Enhancements in 0.8

- Gadgets XML - gadgets.* - opensocial.*

Gadgets XML Changes
Message Substitution in all User Facing Fields
<ModulePrefs author="__MSG_author__"              screenshot="__MSG_sshot__" ...> <UserPref name="code" display_name="__MSG_cnm__"/> ...

• Everything user-facing can be localized • All ModulePrefs fields, UserPref@display_name, etc.

Gadgets XML Changes
Inlined Message Bundles
<ModulePrefs author="Google"> <Locale lang="fr">     <messagebundle>       <msg name="hello">Bonjour</msg>     </messagebundle> </Locale> ...

• Optional alternate syntax • No need for bundle file hosting

Gadgets XML Changes
<ModulePrefs author="Google">   <Preload href=""            authz="signed"/> ...

• Data loaded by rendering server, available at render time • Avoids the need for async makeRequest call • Supports signed or oauth

Gadgets XML Changes
Preferred Size attached to Views
<Content view="home"   preferredHeight="300"          preferredWidth="300">... <Content view="canvas"  preferredHeight="600"          preferredWidth="800">...

• Helps containers size gadgets appropriately for each view

Javascript/XML Enhancements in 0.8

- Gadgets XML - gadgets.* - opensocial.*

gadgets.* JavaScript Changes
Refresh interval for Proxy URL "", { REFRESH_INTERVAL: 360 });

• Asks container to refresh content every N seconds

gadgets.* JavaScript Changes
var unsafe = "<script>alert(document.cookie);</script >hello!"; var safe = gadgets.util.sanitizeHtml(unsafe);

• Makes an arbitrary string safe for inclusion on-page

gadgets.* JavaScript Changes
requestNavigateTo with Owner ID
gadgets.views.requestNavigateTo( gadgets.views.ViewType.HOME, { }, "12345678"); // ownerID

• Allows navigation to the specified view on a given Owner's page. • Default is the "current" owner.

gadgets.* JavaScript Changes
PubSub Communication Mechanism
gadgets.pubsub.subscribe(   "stock-ticker", handleStock); gadgets.pubsub.unsubscribe(   "stock-ticker", handleStock); gadgets.pubsub.publish(   "search-query", currentQuery);

• Gadget-to-gadget communication mechanism • Enables inter-gadget integration

gadgets.* JavaScript Changes
gadgets.views.ViewType standardization
gadgets.views.ViewType.CANVAS gadgets.views.ViewType.HOME gadgets.views.ViewType.PREVIEW gadgets.views.ViewType.PROFILE

• Standardizes best-known view identifiers

Javascript/XML Enhancements in 0.8

- Gadgets XML - gadgets.* - opensocial.*

opensocial.* JavaScript Changes
Person Fields
opensocial.Person.Field.HAS_APP opensocial.Person.Field.NETWORK_PRESENCE opensocial.Person.Field.LOOKING_FOR opensocial.Enum.LookingFor.ACTIVITY_PARTNERS opensocial.Enum.LookingFor.DATING opensocial.Enum.LookingFor.FRIENDS opensocial.Enum.LookingFor.NETWORKING opensocial.Enum.LookingFor.RANDOM opensocial.Enum.LookingFor.RELATIONSHIP

• Answers: Is your app installed on the Person's page? • Answers: Is the Person currently online at the site? • Better structured values for LOOKING_FOR

opensocial.* JavaScript Changes
Improved ability to request People • New filters o TOP_FRIENDS o IS_FRIENDS_WITH • Retrieve people in a group by GROUP_ID • Retrieve Friends-of-Friends and FoFoF o USER_ID + NETWORK_DISTANCE

opensocial.* JavaScript Changes
Persistence data enhancements • All data now treated as JSON o Easier storage of complex objects o Enables smart data escaping • ESCAPE_TYPE parameter allows developers to specify appropriate escaping of data o Applies to getField and newFetchPersonAppData • newRemovePersonAppDataRequest o Allows deletion of stored data.

A) Javascript/XML enhancements B) RESTful APIs C) Templating language and tags

OpenSocial 0.8 RESTful API

(images under Createive Commons by-nc license.)

OpenSocial -> New Environments

Authentication + Authorization: OAuth

Data: People, Activities, AppData, Groups

Formats: JSON, Atom XML

Person (JSON)
{ "id" :"", "name" : {"unstructured" : "Jane Doe"}, "gender" : {"displayvalue" : " 女性 ", "key" : "FEMALE" } }

Person (Atom)
<entry xmlns=""> <content type="application/xml"> <person xmlns=...> <name> <unstructured>Jane Doe</unstructured> </name> <gender key="FEMALE"> 女性 </gender> </person> </content>   <title/>   <updated>2003-12-13T18:30:02Z</updated>   <author/>   <id></id> </entry>

Messaging, Concurrency, Batching

RESTful In the Wild:

{"startIndex":0,"totalResults":100,"entry":[{"id":"175560942","prof ileUrl":" =175560942","isViewer":false,"name":{"unstructured":"Ali","give nName":"Ali"}, ....

A) Javascript/XML enhancements B) RESTful APIs C) Templating language and tags

OpenSocial Templates
Even if you love JavaScript... you don't really want to use it to build HTML
var div = document.getElementById('main');                var url = person.getField(Opensocial.Person.PROFILE_URL); if (url) {                                                  html += '<a href="' + url + '/>';                       }                                                         html += person.getDisplayName();                          if (url) {                                                  html += '</a>';                                         }                                                         div.innerHTML = html;                                    

OpenSocial Templates - Goals
• Easy to develop with - can define templates by copying and pasting HTML and making minor modifications • Secure - XSS free unless developers explicitly work around XSS protections • Fast - supports server-side optimizations • OpenSocial-style - can render templates on the client in JavaScript • Can build an entire application - binds to data returned from OpenSocial APIs as well as to custom developer data; supports conditional and repeated elements

OS Templates - Proposal Stage

OS Template Features - Quick Tour
in two simple examples...

Quick Tour Stop 1 - Using Templates and Expressions
<?xml version="1.0" encoding="UTF-8"?> <Module> <ModulePrefs title="Hello World" height="100"> <Require feature="opensocial-0.7"/> <Require feature="opensocial-templates"/> </ModulePrefs> <Content type="html"> <![CDATA[ <script type="text/os-template"> <div style="font-size: 20px">Hello ${Viewer.Name}!</div> </script> <script type="text/javascript">         var data = {           Viewer: {             Name:  'Opensocial  Bob'           }}; opensocial.template.processAll(data); </script> ]]> </Content> </Module>

Quick Tour Stop 1 - Using Templates and Expressions
• <script type="text/os-template"> defines an inline template section. o Inside the <script> tag, the template content is a valid XML fragment. • Data is passed in to opensocial.template.processAll(data). o This data can be raw JSON data or data returned from OpenSocial APIs. o Expressions of form ${expr} are evaluated against this data o ${Viewer.Name} in the example translates to the JavaScript expression "data['Viewer']['Name'].

Quick Tour Stop 2 - OpenSocial Tags and Flow Control
<?xml version="1.0" encoding="UTF-8"?> <Module> <Content type="html"> <![CDATA[ <script type="text/os-template"> <div repeat="${Top.ViewerFriends}"> <os:ShowPerson person="${Cur}" if="${!Cur.IsOwner}"/> </div> </script> <script type="text/javascript"> loadSocialData(function(socialData) { opensocial.template.processAll(socialData); }); </script> ]]> </Content> </Module>

Quick Tour Stop 2 - OpenSocial Tags and Flow Control
• Tags starting with "os:" are standard OpenSocial tags o i.e. <os:ShowPerson person="${Viewer}"/> o Can extend with additional tag libraries, OpenSocial tag library is just one of many • @if annotation only shows element if expression evaluates to true o <div if="${expr}"> • @repeat annotation renders element once per value in evaluating expression o <div repeat="${expr}"> o ${Cur} variable holds current iteration variable • Can apply @if and @repeat to custom tags o <os:ShowPerson if="${!Cur.IsOwner}"/> • Will have <if> and <repeat> elements as well

OpenSocial Templates Extreme Makeover (before)
html = new Array(); html.push('<select id="person">'); viewerFriends.each(function(person) { html.push('<option value="' + person.getId() + '">' + p person.getDisplayName() + "</option>"); friends[person.getId()] = person.getDisplayName(); }); html.push('</select>'); document.getElementById('friends').innerHTML = html.join('');

OpenSocial Templates Extreme Makeover (after)
<select id="person"> <option repeat="${ViewerFriends}" value="${Id}">${DisplayName}</option> </select>

html.push('You have given:'); html.push('<ul>'); <Content type="html"> for (i in givenGifts) { <![CDATA[ if (+(i) > 0) { <script html.push('<li>' + friends[i] src=" + ' received ' + dgets/file/108987057342301521365/Gifts options[givenGifts[i]] + '</li>'); Old.js"></script> } <script> } gadgets.util.registerOnLoadHandler( html.push('</ul>'); init);

OpenSocial Templates Extreme Makeover 2 (before)

function onLoadFriends(data) { var viewer = data.get('viewer').getData(); var viewerFriends = data.get('viewerFriends').getData(); var giftData = data.get('data').getData(); var friends = new Array(); html = new Array(); html.push('<select id="person">'); viewerFriends.each(function(person) { html.push('<option value="' + person.getId() + '">' + person.getDisplayName() + "</option>"); friends[person.getId()] = person.getDisplayName(); }); html.push('</select>'); document.getElementById('friends').inn erHTML = html.join(''); updateGiftList(viewer, giftData, friends); } function init() { loadFriends(); makeOptionsMenu(); }

</script> document.getElementById('given').inn <div id='main'> erHTML = html.join(''); <div id='give'> } <form id='gift_form'> function makeOptionsMenu() { Give <span var options = ['a cashew nut', 'a id='gifts'></span> to <span peanut', 'a hazelnut', 'a red id='friends'></span>. <a pistachio nut']; href="javascript:void(0);" onclick='giveGift();'>Give!</a> var html = new Array(); </form> html.push('<select id="nut">'); </div> for (var i = 0; i < <div id='given'></div> options.length; i++) { </div> html.push('<option value="' + i ]]> + '">' + options[i] + '</option>'); </Content> } var givenGifts = {}; function updateGiftList(viewer, data, html.push('</select>'); friends) { document.getElementById('gifts').inn givenGifts = {}; erHTML = html.join(''); var options = ['a cashew nut', 'a } peanut', 'a hazelnut', 'a red pistachio nut']; var html = new Array();

OpenSocial Templates Extreme Makeover 2 (after)
<Content type="html"> <![CDATA[ <script type="text/os-template"> <form id='gift_form'> Give <select id="nut"> <option repeat="${Options}" value="${Cur.Index}">${Cur}</option> </select> to <select id="person"> <option repeat="${ViewerFriends}" value="${Id}"> ${DisplayName}</option> </select> <a href="javascript:void(0);" onclick='giveGift();'>Give!</a> </form> You have given: <ul> <li repeat="${GiftList}"> <os:ShowPerson person="${Friend}"/> received ${Gift}</li> </ul> </script> ]]> </Content>

OpenSocial Templates - What Next?
Interested in finding out more and/or getting involved in the spec process?

You can review the proposal at: and post any and all feedback to the discussion group.

To Get Involved:
The 0.8 Spec


Shaping the Spec