Whaddyathink? & the Yahoo! Application Platform

Several months ago, inspired by an idea from hacker/summer intern Mattt Thompson, we developed an app on MySpace called Whaddyathink?. Whaddyathink? enables users to create simple opinion polls for their friends, and although we think it's a good product, part of the motivation for building it was also to get our feet wet with OpenSocial and to build up a code base so we could get experience porting it to the Yahoo! Application Platform (YAP).

Last December, we started adapting the code for YAP, and last week, we released the app on YAP. Although the YAP development team is constantly rolling out features and fixes, there are a few aspects of the platform we think deserve special attention at this time:

Coding for the Small View
To ensure your app loads quickly in My Yahoo!, only a subset of YML, YML Lite, is available, and JavaScript and Flash are disallowed. To implement asynchronous behavior in the small view, we made extensive use of yml:a's "insert" and "replace" attributes.


Note: your app must be in the "live" state to see it in context on My Yahoo!. If it isn't, go to the dev dashboard and click the edit button for your app. In the top right corner of the editing screen, there is a button with the text "push live." Click this, and in a couple seconds, a small notification will pop up stating the push is complete. Click the live segment indicated by the notification to see the app's canvas as it will look to users who install the app. On the canvas, look in the yellow bar above the app for a link to install the app on your My Yahoo! page. Click the link and accept the installation on My Yahoo!. You will now see the small view as it appear to your users. By accepting the install, you are now, literally, a user. The content of the small view is the default content defined in the developer dashboard.

Default code for the small view
In the developer dashboard, clicking on the edit button for an app will open a perspective that includes an area for defining the default small view. The code that goes here is, as the name suggests, the default content for the small view. In other words, it's the content shown on My Yahoo! before new content is cached. The simplest way we found for pushing new content is to use the setSmallView method in the PHP SDK. A discussion on doing this can be found in the documentation. The "Preview Open Application Small View" tutorial covers a method of previewing the small view from the canvas view.

Refreshing the small view content from the small view
In the settings for My Yahoo!, there is an option for auto-refreshing the modules installed on the page. At this time, however, there is no way to auto-refresh app content. The most reliable method we found for ensuring fresh content requires clicking a button so that new dynamic content is displayed. By doing this, we are able to incorporate a call for the most up-to-date data into the content request.

Large and Small views
OpenSocial defines canvas, home, and profile views, yet the YAP platform references "Full" and "Small" views, so what gives? For the purpose of discussion, "Full View" and canvas are interchangeable, as are "Small View" and home. However, there are a couple technical details to be aware of:

  • the "YahooFullView" keyword in a url represents the url defined in the app dashboard.
  • if the url defined in the developer dashboard ends with a file name, this file will be loaded by default. For example, if the url is "domain/path/file.php" then browsing to "apps.yahoo.com/-yourAppId/YahooFullView/" will load "file.php" Browsing to "apps.yahoo.com/-yourAppId/YahooFullView/anotherfile.php" will load "domain/path/anotherfile.php." This same logic holds true in the params attribute of the yml:a, yml:form, and yml:message tags.
  • Setting the view to "YahooSmallView" in either yml:a, yml:form, or yml:message and defining either "insert" or "replace" will load the content of the small or home view into the element with the designated id. If you want to actually navigate to the home view, use a regular a tag and set the href to: http://my.yahoo.com.


Caja enforces the W3C standards for JavaScript, HTML, and CSS, regardless of browser (!).
Yes, you read correctly, if your code cajoles, it will run in Firefox and IE. This is amazing and its value cannot be overestimated.

Keep your client-side code base simple.
Caja is a great resource, but it does rewrite your code to be more secure. If your code is complicated to begin with, debugging the Caja-processed cajoled code will be difficult. Please check out the Caja page of the YAP docs for help debugging Caja's error messages

Start using YML quickly to reduce your code base
If you're resistant to learning another language, be aware that a similar markup language is incorporated in OpenSocial 0.9 as OSML, so you've got nothing to lose. In the YAP version of our app, we use YML extensively as an easy way to put friends' pics and names on a page and link to their profile. Also, because JavaScript and Flash are disallowed in the small view, yml:a is the only way to achieve asynchronous behavior.

Navigation using yml:a
Hallelujah for the ability to navigate between files on your server using traditional, synchronous interactions: the yml:a tag allows you to do this whether your app is in preview or live mode. For our app on MySpace, we used asynchronous calls to swap out content. You can do this in YAP as well using yml:a's "insert" and "replace" attributes or io.makeRequest, but it's much simpler to just link between your files. Note that Caja's client-side component strips YML from io.makeRequest responses, and CSS blocks and JavaScript from yml:a responses. For more information, please refer to Jon's forum post.

Adding event listeners
Use addEventListener instead of the onclick assignment shorthand. It's a bit wordier, but in Caja, it works in IE and Firefox, which is great! Additionally, the event object is consistently passed as an argument to the event handler regardless of browser. For example, instead of this:

<a href="#">before</a>
var a = document.getElementsByTagName('a')[0],
    handler = function(e){
        var target = e.target || window.event.srcElement;
        target.firstChild.data = 'after';//set link text to 'after'
a.onclick = handler;

You would use:

<a href="#">before</a>
var a = document.getElementsByTagName('a')[0],
    handler = function(e){
        e.target.firstChild.data = 'after';//set link text to 'after'
a.addEventListener('click', handler, false);

POST data is sent to browser with all synchronous requests
OpenSocial 0.8 now defines a way to sign requests made back to your server so you can get some basic data about the owner and viewer from the request variables, but, as referenced above, YAP does this automatically for you. This eliminates the need to request user data when the app is initializing. For our app on MySpace, we chained everything to an initial request for owner and viewer data, which seemed like cumbersome architecture at the time and we are glad to be rid of it.

Caja restricts access to insecure aspects of JavaScript
One example of a restricted element is the this object. A reasonable use case for this is in an event handler to access the element that's clicked. Because this is inaccessible, try to use the target property of the event object passed to the handler, as in this example:

    var href = e.target.href

Instead of:

    var href = this.href


Another restricted element is document.location. MySpace developers accustomed to retrieving the user and viewer ids from the url, should use the POST data sent with the request for the app instead. Note also that Caja eliminates the need to silo untrusted JavaScript within an iframe. This improves performance, but it alters the relationship between the app and the page on which it resides. As mentioned above, data that is typically passed to the app through the iframe URL is accessible in YAP as POST data in the content request.

CSS hacks are stripped
What! No CSS hacks, filters, or coding? But the layout will look très horrible in (browser name here). Not to worry. Use the yml:if-env tag instead. For example, instead of this:

* a{color:red}


<yml:if-env ua="ie">

Again, it's wordier, but it's self-descriptive and works in all grade-A browsers.

YAP doesn't use an XML file to define an app
Yes, the platform supports the OpenSocial 0.8 JavaScript API, but in your app definition, instead of referencing an XML spec file, you simply state the base url for the canvas view of your app. When the user loads the app, content is requested from that url. This app architecture is very similar to the way the view @href attribute of the "Content" block defined in OpenSocial 0.9 will work.

Closing remarks
By the time you read this, new features may be implemented and bugs fixed. Please refer to the YAP documentation in general for the most up-to-date information about the platform. For quick reference on the top ten or so issues observed in the latest version of the platform, please read the FAQ section of the docs.

Erik Eldridge, Jon LeBlanc, & Dan Theurer
Yahoo! Developer Network