Professional Documents
Culture Documents
1 2 3
Table of Contents
1. Overview of the Yahoo! Application Platform (YAP) ............................................................... 1 What is YAP? .............................................................................................................. 1 Programming Models ................................................................................................... 1 Server-Side ......................................................................................................... 1 Browser-Side OpenSocial JavaScript ....................................................................... 2 Browser-Side Flash .............................................................................................. 3 Encoding Requirements and MIME Types ........................................................................ 4 Supported Image Formats ...................................................................................... 4 Submission Guidelines ................................................................................................. 5 Application Distribution and Promotion ........................................................................... 6 Publishing With the Add-to-Yahoo! Button ............................................................... 6 Using the Share and Message Features ..................................................................... 8 Leveraging Updates ............................................................................................. 8 Using Preview ..................................................................................................... 8 2. Getting Started: Build Your First Open Application ................................................................. 9 Introduction ................................................................................................................ 9 Prerequisites ............................................................................................................... 9 Getting the Code and Images ......................................................................................... 9 Configuring Your Application ....................................................................................... 10 Previewing Your Application ........................................................................................ 13 Pushing Your Application Live ...................................................................................... 13 Running the Canvas View ............................................................................................ 14 Updating Your Application ........................................................................................... 14 Submitting Your Application to Yahoo! ........................................................................... 15 3. Anatomy of an Open Application ....................................................................................... 16 Introduction .............................................................................................................. 16 Small View ............................................................................................................... 17 Canvas View ............................................................................................................. 18 Preview .................................................................................................................... 20 Chrome .................................................................................................................... 21 Landing Page ............................................................................................................ 21 My Applications ........................................................................................................ 22 Messages .................................................................................................................. 23 Sharing .................................................................................................................... 24 Updates .................................................................................................................... 25 4. Best Practices ................................................................................................................ 26 Introduction .............................................................................................................. 26 Helping Users Discover Your Application ....................................................................... 26 Do's ................................................................................................................. 26 Don'ts .............................................................................................................. 27 Providing a Better Initial Experience ............................................................................. 27 Do's ................................................................................................................. 27 Don'ts .............................................................................................................. 27 Optimizing the Views .................................................................................................. 27 Do's ................................................................................................................. 28 Don'ts .............................................................................................................. 28 Making Applications Social ......................................................................................... 28 Do's ................................................................................................................. 28 Don'ts .............................................................................................................. 29 Respecting Your Users ................................................................................................ 29 Do's ................................................................................................................. 29
iii
Yahoo! Application Platform Developers Guide Don'ts .............................................................................................................. 29 Improving Performance ............................................................................................... 29 Do's ................................................................................................................. 30 Don'ts .............................................................................................................. 30 Image Caching .................................................................................................. 30 Optimizing Your Application for the Gallery ................................................................... 30 Do's ................................................................................................................. 30 Don'ts .............................................................................................................. 31 5. Setting the Small View of an Open Application ..................................................................... 32 Introduction .............................................................................................................. 32 Prerequisites ............................................................................................................. 32 Creating the Default State ............................................................................................ 33 Creating the Personalized State ..................................................................................... 36 Applications Using Private Data ........................................................................... 36 Applications Using Public Data ............................................................................ 37 Source Code ............................................................................................................. 39 6. Yahoo! Markup Language (YML) ...................................................................................... 40 Introduction to YML ................................................................................................... 40 What is YML? ................................................................................................... 40 Benefits ........................................................................................................... 40 Syntax Rules ..................................................................................................... 41 URL Parameter Encoding and Relative Paths .......................................................... 41 YML Lite ......................................................................................................... 42 yml:a ....................................................................................................................... 42 Description ....................................................................................................... 42 Attributes ......................................................................................................... 42 Examples ......................................................................................................... 43 yml:audio ................................................................................................................. 45 Description ....................................................................................................... 45 Attributes ......................................................................................................... 45 Examples ......................................................................................................... 45 yml:customize ........................................................................................................... 46 Description ....................................................................................................... 46 Attributes ......................................................................................................... 46 Examples ......................................................................................................... 46 yml:form .................................................................................................................. 46 Description ....................................................................................................... 46 Attributes ......................................................................................................... 46 Examples ......................................................................................................... 46 yml:friend-selector ..................................................................................................... 47 Description ....................................................................................................... 47 Attributes ......................................................................................................... 47 Examples ......................................................................................................... 47 yml:if-env ................................................................................................................. 47 Description ....................................................................................................... 47 Attributes ......................................................................................................... 48 Examples ......................................................................................................... 48 yml:include ............................................................................................................... 48 Description ....................................................................................................... 48 Attributes ......................................................................................................... 48 Examples ......................................................................................................... 49 yml:message ............................................................................................................. 50 Description ....................................................................................................... 50 Attributes ......................................................................................................... 51
iv
Yahoo! Application Platform Developers Guide Examples ......................................................................................................... 51 yml:name ................................................................................................................. 52 Description ....................................................................................................... 52 Attributes ......................................................................................................... 52 Examples ......................................................................................................... 53 yml:profile-pic .......................................................................................................... 53 Description ....................................................................................................... 53 Attributes ......................................................................................................... 53 Examples ......................................................................................................... 53 yml:pronoun ............................................................................................................. 54 Description ....................................................................................................... 54 Attributes ......................................................................................................... 54 Examples ......................................................................................................... 54 yml:share ................................................................................................................. 54 Description ....................................................................................................... 54 Attributes ......................................................................................................... 55 Examples ......................................................................................................... 55 yml:swf .................................................................................................................... 55 Description ....................................................................................................... 55 Attributes ......................................................................................................... 55 Tag contents ...................................................................................................... 56 Examples ......................................................................................................... 56 yml:user-badge .......................................................................................................... 56 Description ....................................................................................................... 56 Attributes ......................................................................................................... 56 Examples ......................................................................................................... 56 7. Caja Support .................................................................................................................. 58 Introduction .............................................................................................................. 58 What is Caja? .................................................................................................... 58 Caja Status for This Release ................................................................................. 58 Why Do We Need Caja? ...................................................................................... 59 How Does Caja Work? ........................................................................................ 59 How Do I Debug My Application? ................................................................................ 61 YML Alters Caja Line Numbers ........................................................................... 61 What HTML Tags are Blacklisted? ................................................................................ 62 What Works in Caja? .................................................................................................. 62 Browsers Supported ........................................................................................... 62 HTML and CSS ................................................................................................. 62 YML ............................................................................................................... 62 DOM manipulation ............................................................................................ 63 Events and Timers .............................................................................................. 63 OpenSocial 0.9 .................................................................................................. 63 What are Caja's Limitations? ........................................................................................ 63 Server-Side vs. Client-Side Sanitization ................................................................. 63 XHTML Strictness ............................................................................................. 63 HTML Limitations ............................................................................................. 64 CSS Limitations ................................................................................................ 65 JavaScript limitations .......................................................................................... 65 DOM Limitations ............................................................................................... 67 Flash Restrictions ............................................................................................... 68 What Do These Messages Mean? .................................................................................. 69 Compile-Time Errors .......................................................................................... 69 Runtime errors .................................................................................................. 69 8. YUI Support .................................................................................................................. 70
Yahoo! Application Platform Developers Guide Introduction .............................................................................................................. 70 YUI Libraries and Utilities Available in YAP ........................................................... 70 Including YUI Scripts and CSS ............................................................................. 71 Support and Bugs ............................................................................................... 71 YUI Examples for YAP ............................................................................................... 72 Event Handlers .................................................................................................. 72 Scrolling Animation ........................................................................................... 74 9. OpenSocial 0.9 Compatibility ........................................................................................... 77 Overview of OpenSocial Support .................................................................................. 77 Gadget Configuration for OpenSocial .................................................................... 77 OpenSocial JavaScript Features Supported by YAP ........................................................... 78 Activity ............................................................................................................ 78 Messaging ........................................................................................................ 79 Person and People .............................................................................................. 79 Supported DataRequest Fields .............................................................................. 80 Using Environment.supportsField ......................................................................... 80 Permissions ...................................................................................................... 80 Gadget Core APIs .............................................................................................. 80 OpenSocial RESTful APIs Supported by YAP ................................................................. 80 OpenSocial Code Samples ........................................................................................... 81 Activities Demo ................................................................................................. 81 Gifts Demo ....................................................................................................... 84 Yahoo! Profile Demo .......................................................................................... 91 Gadget XML Configuration File ................................................................................... 93 Content Sections ................................................................................................ 97 Application Categories ........................................................................................ 98 Legacy Applications ........................................................................................... 99 10. OpenSocial 0.8 Compatibility ........................................................................................ 101 OpenSocial 0.8 Legacy Support .................................................................................. 101 OpenSocial 0.8 JavaScript Features Supported by YAP .................................................... 101 Activity .......................................................................................................... 101 Messaging ...................................................................................................... 102 Person and People ............................................................................................ 102 Supported DataRequest Fields ............................................................................ 103 Using Environment.supportsField ........................................................................ 103 Permissions ..................................................................................................... 103 Gadget Core APIs ............................................................................................. 103 OpenSocial RESTful APIs Supported by YAP ................................................................ 103 Differences Between Versions 0.8 and 0.7 JavaScript APIs ............................................... 104 Using opensocial.IdSpec .................................................................................... 104 When NOT to Use opensocial.IdSpec ................................................................... 105 Retrieving Friends With NETWORK_DISTANCE ................................................. 105 Activity Response Format .................................................................................. 105 OpenSocial Code Samples ......................................................................................... 106 Activities Demo ............................................................................................... 106 Gifts Demo ..................................................................................................... 109 Gadget Configuration for OpenSocial 0.8 ...................................................................... 116 11. Code Examples ........................................................................................................... 117 Prerequisites ............................................................................................................ 117 YML Code Examples ................................................................................................ 117 Tabs in the Small View ...................................................................................... 117 Friend Selector ................................................................................................ 119 Friend Selector With Style ................................................................................. 120 Navigate from Small View to Canvas View ............................................................ 121
vi
Yahoo! Application Platform Developers Guide Preview Open Application Small View ................................................................. 122 Links to Yahoo! Profiles .................................................................................... 123 Accordion Menu for an Open Application ............................................................. 124 Refreshing the Small View ................................................................................. 126 Refreshing the Small View Dynamically ............................................................... 128 Caja-Ready Code Examples ....................................................................................... 130 Event Handling ................................................................................................ 130 JSON Conversion ............................................................................................. 132 Ajax Request ................................................................................................... 134 Wall-to-Wall Open Application ........................................................................... 136 Other Code Examples ............................................................................................... 138 My Social PHP Application ................................................................................ 138 Additional Code Examples ................................................................................. 145 A. Parameters Passed to an Open Application ........................................................................ 147 B. YAP Developer Web Services .......................................................................................... 151 General Information .................................................................................................. 151 Authorization .................................................................................................. 151 Response Codes ............................................................................................... 151 Set Small View Web Service ....................................................................................... 151 Description ..................................................................................................... 152 URI ............................................................................................................... 152 Methods ......................................................................................................... 152 Request Body .................................................................................................. 152
vii
List of Figures
1.1. Server-Side ................................................................................................................... 2 1.2. Browser-Side JavaScript .................................................................................................. 3 1.3. Browser-Side Flash ........................................................................................................ 4 3.1. Anatomy of an Open Application details the composition of an application with its different Views, states, and locations. ................................................................................................. 17 3.2. Example Small View ..................................................................................................... 18 3.3. Example Canvas View ................................................................................................... 20 3.4. Chrome Screenshot ...................................................................................................... 21 3.5. Landing Page Screenshot ............................................................................................... 22 3.6. My Applications Screenshot ........................................................................................... 23 3.7. Message Screenshot ...................................................................................................... 24 3.8. Sharing Screenshot ....................................................................................................... 25 3.9. Updates Screenshot ...................................................................................................... 25 11.1. Tab 2 Selected .......................................................................................................... 118 11.2. Friend Selector Screenshot ......................................................................................... 119 11.3. Preview of Canvas View ............................................................................................. 122 11.4. Links to Yahoo! Profile With YML ............................................................................... 123 11.5. Accordion Screenshot ................................................................................................ 124
viii
List of Tables
A.1. Parameters Passed to an Open Application ...................................................................... 147
ix
What is YAP?
The Yahoo! Application Platform (YAP) is the software and services that enable developers to build Web applications that are available throughout Yahoo!to the largest audience in the world. The Yahoo! Application Platform has the following components: Development environment: A browser-based tool that enables software developers to quickly create, preview, and publish Web applications. APIs and Web services: Programmatic access to OpenSocial functionality and popular Yahoo! Web services. Distribution and discovery infrastructure: Built-in features for publishing applications in Yahoo! galleries and properties, including Yahoo! Toolbar and My Yahoo!. End users can discover applications by searching or browsing within application galleries. Runtime and rendering environment: The backend servers and software that run applications and convert the code into HTML.
Programming Models
YAP offers several programming models for the development of Open Applications [16]. The diagrams that follow show a simplified view of the runtime components for each model.
Server-Side
In this model, the code for your Canvas View [18] is a Web application that is hosted by and runs on your servers. You can write the code in the language of your choice, such as Python, Java, or PHP. To make it
Overview of the Yahoo! Application Platform (YAP) easier to perform authorization and access Yahoo! social data, several Yahoo! Social API SDKs1 are available. At runtime, the YAP engine proxies requests to your server, adding the additional information listed in Parameters Passed to an Open Application [147]. The Canvas View of your application can access this additional information programmatically. For example, a Canvas View coded in PHP can access the user's GUID from the $_REQUEST superglobal. YAP saves the Small View [17] code in a cache. To specify the default Small View code, you enter HTML and YML [40] statements on the Project Details page. To personalize the Small View to each user, your application can call the setSmallView method of the Yahoo! Social SDK for PHP2. YAP takes several measures to protect the user's private data. When the application accesses data through the Yahoo! Social API3, OAuth verifies that the access is authorized. The YAP engine sanitizes the HTML and processes the JavaScript with Caja [58] before sending the content back to the browser.
1 2
Browser-Side Flash
With the ActionScript 3 Social APIs4, you can create Flash modules in a Canvas View. The Flash module has access to the viewer's session information and can obtain social information by making calls to the Yahoo! Social API. To include a Flash Module in the Canvas View, insert a Yahoo! Markup Language [40] (YML) tag such as the following: <yml:swf src="http://example.com/app.swf" width="750" height="1000"/>
../../flash/yos/classreference/
Overview of the Yahoo! Application Platform (YAP) See also Image Caching [30].
Submission Guidelines
Yahoo! selects a limited number of high-quality Open Applications to feature in the application galleries of our properties, including: My Yahoo!5 Yahoo! Toolbar6 Yahoo! Pulse7 Yahoo! selects these applications from the pool that have been reviewed and approved. If an application has been approved, it does not automatically appear in Yahoo! galleries. To submit an application for inclusion in Yahoo! galleries, click the Submit to Publish button on the Project Details page in My Projects8. Further instructions are available in the tutorial section Submitting Your Application to Yahoo! [15]. Once an application has been submitted, it is added to the review queue for the Open Application Repository and Toolbar; applications published in the Repository and Toolbar are later considered, using additonal criteria, for My Yahoo!. This is an automatic process that does not require further action from the developer. If you want to get information about the status of an application, you can post a message to the Yahoo! Application Platform9 YDN forum. Broadly speaking, Open Applications can be classified as fully featured or feed based. Fully featured apps are self-contained interactive programs whose core functionality resides in the app itself. Feed-based apps are essentially RSS/XML feeds displayed in a YAP container. In evaluating submissions for the My Yahoo! and Yahoo! homepage galleries, there is a preference for fully featured applications. If your application conforms to the following guidelines, it has a better chance of being selected for Yahoo! galleries.
5 6
Overview of the Yahoo! Application Platform (YAP) Links in the Small View go to the Canvas View or to some functionality that keeps the user within the Open Application. The Small View does not contain links to an external site; it does not, for example, simply link headlines to your company's website. (Instead of linking to your site, you can link to the Canvas View and pull in information from your site.) There are exceptions to this rule, as when a link in the Small View sends the user to your website to link the Open Application with the user's account. More than 25% of the links in the Canvas View perform actions with the Open Application. For example, links can display a partial news article (which might then link to a full article on your website), load another page in the application, or configure the content being displayed.
Good Citizenship
The application follows the Yahoo! Terms of Use11 and Yahoo! Guidelines12.
In a Web page, the "Add to Yahoo!" button might look like this:
10 11
To create the "Add to Yahoo!" button, perform the following steps: 1. From the Project Details page, push your application live. (For instructions, see the tutorial section Pushing Your Application Live [13].) 2. Note the Application ID displayed by the Project Details page. 3. Link the required CSS and JavaScript files to your application:
<link rel="stylesheet" href="http://l.yimg.com/a/lib/addtoyahoo/addtoyahoo_1.0.2. <script src="http://l.yimg.com/a/lib/addtoyahoo/addtoyahoo_1.0.5.js"></script> Your page must have an HTML doctype to use these libraries. 4. On the page where you want the "Add to Yahoo!" button, instantiate AddToYahoo. For example: <script> var button1 = new YAHOO.one.AddToYahoo({ id:"add_button_1", intl:"en-US", typeToAdd: ["app","your_app_ID"], dropdownNetworks: ["yCom","yMy"], newWindow: true }); </script> You can publish RSS feeds as well as YAP applications. For example: <script> var button2 = new YAHOO.one.AddToYahoo({ id:"add_button_2", intl:"en-US", typeToAdd: ["url","http://feeds.someserver.com/rss/..."], dropdownNetworks: ["yCom","yMy"], newWindow: true }); </script> For more information about the properties of AddToYahoo, see below. 5. Place an empty element, such as a div or span, on the page where you want to create the button. Include the id of your AddToYahoo object and specify class="addToYButton". For example: <div id="add_button_1" class="addToYButton"></div> You can assign the following properties to AddToYahoo: Property id Description The id of the element where the button is to appear. Must be unique.
Overview of the Yahoo! Application Platform (YAP) Property intl Description Options include "en-US", "es-ES", "fr-FR", "it-IT", "de-DE", "pt-BR", "en-SG", "esAR", "en-AU", "fr-CA", "es-CL", "es-CO", "da-DK", "es-US", "el-GR", "zh-HantHK", "id-ID", "en-IN", "ko-KR", "es-MX", "nb-NO", "en-NZ", "es-PE", "en-PH", "pl-PL", "ru-RU", "sv-SE", "th-TH", "tr-TR", "zh-Hant-TW", "en-GB", "es-VE", and "vi-VN". An array consisting of "app" followed by a YAP application ID, or "url" followed by the URL of an RSS feed. Optional. Boolean (defaults to false). Specify true to open a new window when the button is clicked.
typeToAdd
dropdownNetworks Optional. Creates a pull-down menu. An array containing "yMy" (My Yahoo!). newWindow
Leveraging Updates
Yahoo! Updates [25] appear on many Yahoo! sites, Yahoo! Messenger13, Yahoo! Mail14, Yahoo! Pulse15, and Yahoo! TV16. When a user installs an application on Yahoo! Toolbar or My Yahoo!, an update is generated. To propagate even more viral hooks throughout Yahoo!'s sites, your application should generate additional updates. For information on creating updates, see the Yahoo! Updates API17 and Yahoo! Social API SDKs18.
Using Preview
Preview [20] allows you to present substantive content to users who are not signed in or have not installed your application. In preview content, encourage users to install and customize the app.
13 14
Introduction
This tutorial provides step-by-step instructions for creating an Open Application. The code for this tutorial is a simple PHP script named weather.php1. This script calls YQL with cURL and then displays the information returned: the current weather for zip code 90210. (To learn about YQL, see the YQL Guide2.)
Prerequisites
To understand this material, you must be familiar with PHP, XML, HTML/XHTML, and Web application development. You will need a Web server that can be accessed outside of your local network. You cannot use localhost for an Open Application. Your Web server must be running PHP 5.2 or later.
Getting Started: Build Your First Open Application 2. Copy the following image files to your Web server: weather-16X16.gif5(favicon) weather-20X20.gif6(additional icon) weather-300X250.gif7(screenshot) weather-64X64.gif8(application icon) You will specify the URLs to these images when you configure your application in the next step [10].
4. Click Continue. 5. Verify that you have created a new application by looking at the figure below.
5 6
10
6. Click Download XML and save the generated Gadget XML file on your computer. The file is called ygadget_appID.xml, where appID is the application's ID (e.g. gadget_9g2QuE6o.xml). The file you've just downloaded is a template that provides a starting point for your application. It is fully functional, with all required elements and attributes as well as default content; it defines an application that you can run in Preview mode. In the next step, you'll modify this file to create the Weather sample app. 7. Open the Gadget XML file in a text editor and edit the following fields: In the ModulePrefs element: Set the title attribute to "Weather". Set the description attribute to "Weather Forecast Sample Application". Set the category attribute to "Information-Weather". In the Icon subelement, type the URL of the weather-16X16.gif favicon that you copied in the previous step [9]e.g. <Icon>http://your-domain.com/weather16X16.gif</Icon>. In the Extension named "yap.gadgets.ShortDescription", type "Weather Test App". (See the example below.) In the Extension named "ApplicationIconUrl", type the URL of the weather-64X64.gif application icon that you copied in the previous step [9]. In the Extension named "YahooComIconUrl", type the URL of the weather-20X20.gif icon that you copied in the previous step [9]. In the Extension named "ScreenshotUrl", type the URL of the weather-300X250.gif screenshot that you copied in the previous step [9]. In the first Content element, change the text to "Weather Forecast". In the second Content element, set the href attribute to the URL of the weather.php file that you copied in the previous step [9] (http://your-domain.com/weather.php).
11
Getting Started: Build Your First Open Application You can fill in additional fields if you want: For an explanation of Gadget XML and its contents, see Gadget XML Configuration File [93]. For guidelines on image files, see Optimizing Your Application for the Gallery [30] and Supported Image Formats [4]. Save the file. When you are done, the Gadget XML file should include the following (where your-domain.com is replaced with the address of your Web server): <?xml version="1.0" encoding="UTF-8"?> <Module xmlns:yap="http://www.yahoo.com/ns/yap"> <ModulePrefs title="Weather" description="Weather Forecast Sample Application" category="Information-Weather"> <Icon>http://your-domain.com/weather-16X16.gif</Icon> <Locale lang="en" country="us"/> <yap:Extension name="yap.gadgets.ShortDescription">Weather Test App</yap:Extension> <yap:Extension name="yap.gadgets.ApplicationIconUrl">http://your-domain.com/weather-64X64.gif</yap:Extension> <yap:Extension name="yap.gadgets.YahooComIconUrl">http://your-domain.com/weather-20X20.gif</yap:Extension> <yap:Extension name="yap.gadgets.ScreenshotUrl">http://your-domain.com/weather-300X250.gif</yap:Extension> </ModulePrefs> <Content type="html" view="YahooSmallView, default"> <h1>Weather Forecast</h1> </Content> <Content type="html" view="YahooFullView, canvas" href="http://your-domain.com/weather.php"> </Content> <!-- The content of this CDATA will render if no other content sections are applicable. --> <Content type="html"> <![CDATA[ Hello World, my name is <yml:name uid="viewer" linked="true" capitalize="true"/>. ]]> </Content> </Module> 8. Copy the edited Gadget XML file to your Web server.
12
Getting Started: Build Your First Open Application 9. Click Import New XML and specify the URL for the Gadget XML file on your Web server.
Click Import. YAP will validate the Gadget XML file and report errors. If there are errors, fix them and reimport the file.
13
14
Getting Started: Build Your First Open Application These buttons are meant to be used in order. Reload fetches the Gadget file using the last URL specified with Import New XML; you can't click Reload until you've used Import New XML at least once. Update from Development Gadget switches the "live" version of your app to the most recently updated Gadget file; you can't refresh your app with Update from Development Gadget until you've used Refresh (or Import New XML) to upload the modified Gadget file.
15
Introduction
An Open Application is a Web application that has been registered on the Yahoo! Development Network1 (YDN) and runs on the Yahoo! Application Platform (YAP). An Open Application is defined by a Gadget XML [93] file. As seen by the end user, an Open Application has multiple views, integration points, and components.
http://developer.yahoo.com
16
Figure 3.1. Anatomy of an Open Application details the composition of an application with its different Views, states, and locations.
Small View
Important Notice YAP will stop supporting Small View from 15th April 2012 onwards. The Small View of an application appears to end users as a module contained within a Web page. As the application's teaser, the purpose of the Small View is to draw end users into the Canvas View [18], which provides a richer interaction. The content of the Small View is up to you, but usually a Small View contains information such as the following: One or more triggers to launch the Canvas View. A representation of the user, such as a name and an image. Your application can get this information from the user's Yahoo! Profile. Status or Updates [25] about other end users that will encourage the user running the Small View to open the Canvas View. A Small View has two states: Default: In this state, the Small View should encourage the user to customize the application.
2 3
images/anatomy_big.png images/anatomy_big.pdf
17
To define the default state, in the Gadget XML file create a Content element whose view attribute is set to "YahooSmallView". The Content element must contain HTML or YML [40]; other markup or programming languages are ignored. At runtime, YAP renders the Small View's default code if a personalized state for the end user is not available. Personalized: The end user is signed in to Yahoo! and has installed the application. Yahoo! maintains per-user, per-application customization data on its own servers. To personalize the Small View, an application calls the setSmallView method of the Yahoo! Social SDK for PHP4. This method enables you to tailor the Small View for each end user (identified by GUID) and to dynamically update the Small View. You can use this method wherever you can run the PHP SDK, for example, in the Canvas View and back-end processes. For more information, see Creating the Personalized State [36]. Small Views have the following constraints: The size of a Small View must not be fixed. Be sure to use a fluid layout so that the view will be properly displayed on different Yahoo! sites. A vertical scroll bar appears when necessary. Unlike the Canvas View, advertisements and promotions cannot be served in a Small View. In the Small View, the code is restricted to HTML or YML [40]. You cannot specify JavaScript, PHP, or other languages for the Small View.
Canvas View
The Canvas View is the application's largest and richest interface for the end user. Usually, the Canvas View is rendered within a Yahoo! landing page, surrounded by a Yahoo! header, footer, and an advertisement unit. End users access a Canvas View from a variety of locations: the Small View, links for user Updates [25], email links, and Web links. Unlike the Small View, the Canvas View supports third-party advertisements and promotions. The size of a Canvas View must not be fixed. Be sure to use a fluid layout so that the view will be properly displayed on different Yahoo! sites. A vertical scroll bar appears when necessary.
/social/sdk/php/
18
The application code for the Canvas View is hosted on a server outside of YAP. To specify the code's location, in the Project Details page, enter the URL in the Application URL field. The Canvas View code can be HTML, YML [40], CSS, and the subset of JavaScript allowed by Caja. This code can be generated by a variety of languages, such as PHP, XML/XSLT, and Ruby on Rails. To protect the private information of end users, YAP applies the following security mechanisms to the Canvas View: The Canvas View is presented within an iframe. HTML is sanitized to remove unsafe code. JavaScript is translated by Caja. You should design the Canvas View so that it has the following two states: Uninstalled: The user is visiting your application but has not customized it or given it permission to access Yahoo! user data; the user's identity (GUID) is unknown to the application. In this state, the Canvas View should encourage the user to customize the application. Personalized: The user has installed your application, his or her identity is known, and the full functionality of the Canvas view is available.
19
Preview
Important Notice YAP will stop supporting Preview View from 15th April 2012 onwards. Preview content is shown to users who are not signed in to Yahoo!, have not installed your application, or have not given permission for your app to access their data. Preview content may also appear in other contextsfor example, when a user browses for apps in a Yahoo! gallery, or when a third-party app is featured on a Yahoo! site. If your app does not provide Preview content, users in these contexts will see a simple request to sign in or install your app. To define Preview content, create a Content element in the Gadget XML [97] file whose view attribute is set to "preview". Preview content is subject to certain limitations. YML is supported, but tags cannot retrieve information about the user. For example, the following tag works:
20
<yml:name uid="QPR12345" /> But the following tag does not work in preview content: <yml:name uid="viewer" /> <!-- don't use in preview --> When creating Preview content: Try to include substantive content that is interesting to most users. For example, a non-customized weather app could include information about one or two popular travel destinations. Design the page for display in various widths. Content may appear in containers of different sizes. Encourage the user to install and customize the application. You can use the yml:customize [46] tag for this purpose.
Chrome
YAP may provide navigation aids around the border of an application. These items, which vary depending on the container and context in which the app appears, require no input from the developer.
Landing Page
The Landing Page is the default location where an Open Application's Canvas View is presented. End users can access the Landing Page via a proxied URL (http://apps.yahoo.com/-your_app_id). On a Landing Page, the Canvas View is enclosed by Yahoo!'s standard header and footer, and in some cases by an advertisement unit.
21
My Applications
My Applications lists all Open Applications installed by an end user. When an application is installed, it is added to My Applications regardless of where the installation took place. In My Applications, every application is represented by its icon and name. Clicking on an application sends the end user to the application's Landing Page, displaying the Canvas View of the App. My Applications can be accessed at http://pulse.yahoo.com/y/apps, and will be promoted around the Yahoo! network in future releases.
22
Messages
YAP allows users to send messages to each other through Open Applications. See Using the Share and Message Features [8] and yml:message [50] for more information.
23
Sharing
A sharing request is a special message [23] that invites the recipient to install an Open Application. These invitations are initiated by an end user who as already installed the application in question. See Using the Share and Message Features [8] and yml:share [54] for more information.
24
Updates
Updates are Yahoo!'s user event stream. When an end user installs an Open Application, the Application may be granted rights to read from and write to the user's Updates. For more information see the Yahoo! Updates API5.
/social/updates/
25
Do's
Provide a clear and distinguishable application name, description, and recognizable icons in all sizes [30]. For users that are not signed in to Yahoo!, present the application in a way that encourages them to install your application (example: Flood-it1). Consider using preview [20] for this purpose. Publish your application using a business account rather than your personal Yahoo! account to correctly describe your applications ownership to your users. (Example: Target2) Allow users to share your application with their Connections. Also, let them send messages within your application at relevant moments to drive more traffic. (Example: Mafia Wars3) Add an "Add to Yahoo!" [6] link to your site to drive traffic to your application from Yahoo!. Highlight your application through your product's existing channels, such as site promotion, emails, and advertising.
1 2
26
Best Practices
Don'ts
Don't use your personal Yahoo! account because your application will be attributed accordingly (Example: "by Jane Doe"). Don't ignore the potential for converting signed-out users into signed-in users. An undeveloped signedout state can make your application look broken or unavailable.
Do's
Look up the user's location data in the Profile. (Example: Social Weather4) Use GeoPlanet5 to convert user-submitted locations into usable data such as latitude/longitude coordinates and city name. GeoPlanet is also available through YQL6. Reference yap_jurisdiction (an ISO 3166 country code passed as a post parameter to YAP applications) and Accept-Language (an RFC 2616 section 14.4 language priority list passed as a header to YAP applications).
Don'ts
Don't ask users to provide information they have already provided through Yahoo!, such as Profile data, interests, or location. (Example: "Enter your nickname:") Don't ask the user for their location unless there is no logical way of inferring it. For example, you may not be able to determine the location if the available information is abstract. (Example: "out in the country")
27
Best Practices
Do's
Create a widget-like Small View and a rich, interactive Canvas View. (Example: Addicted to Chappelle's Show9) Allow fluid dimensions for different sizes in different places around Yahoo!. Use a width of 100% for your applications so that its width adjusts if the window size changes. (Example: Flixter10) Ensure that the fluid dimensions of your application enable it to display properly within the smallest available container. Factor in the width of a scrollbar, which is about 20 pixels wide, as well as the fixed height of the window on the Yahoo! homepage (www.yahoo.com). If your window extends below this fixed height, it may not appear without scrolling.
Don'ts
Don't create a Small View that merely duplicates the Canvas View. Don't restrict an application to style="width:478px;">...</div>). a fi xe d width (Example: <div
Dont assume you know the size of the application container. There is currently no method you can call to obtain the container's dimensions. That said, please note the rough dimensions of the Yahoo! homepage's Small View (400 pixels wide by 460 pixels high) and Canvas View (750 pixels wide by 460 pixels high).
Do's
Surface a user's friends inside your application to encourage competition and interaction. (Example: Hey Einstein12) Write informative, inviting messages that encourage other users to click. (Example: "Mark has rated the book Adventures of Huckleberry Finn: 4/5 stars" via Books weRead13)
28
Best Practices Advertise user activity through Yahoo! Updates14 (activity stream).
Don'ts
Don't ask users to create an entirely new set of relationships inside your application.
Do's
Before pushing your application live, test the different states of each view, ensure that Updates are posted properly, and test that sharing works. Use A-Grade browsers15 for testing. Ensure that Updates are posted correctly and sharing works. Allow users to submit bug reports and feature requests easily in your application through links in the bottom right of your application (Example: Lexolous16) Request only those permissions that your application needs to access user data (such as Contacts).
Don'ts
Don't display sensitive or private information to others. (Example: "Mark just bought 4 shares of AAPL stock at $93.14/share.) Don't display user-specific data to users who are not connected to a user. For example, identify users with nicknames instead of full names or other information that your application obtains. Don't force users into submitting comments about your application through the Yahoo! "Report Abuse" link available in each application. Don't request redundant permissions to access user content (such as Contacts) if your application doesn't need it to operate.
Improving Performance
Response time plays a key role in how users perceive your application; nobody likes a slow application. By tracking your application's usage and adjusting its performance, you can dramatically improve the quality of your application's user experience. There are two approaches to improving your application's performance. First, you can improve the actual response time by optimizing the application logic. Second, you can enhance the perceived performance by adjusting the order in which you load resources.
14 15
29
Best Practices
Do's
Use YQL17 to cache queries. Combine multiple queries into one call. Use unique URLs for resources such as images or media files. When you update the content of a resource, you should update the URL so that the cache is flushed with the updated content. Write modular code and reuse it as much as possible. Reuse is especially important because Caja [58]18, the technology used by Yahoo! to ensure the security of user data, can increase the size of your JavaScript code by 2-3 times because it adds a series of checks and verification steps. To improve perceived response time, defer loading resources until your application has launched. Also, load resources after fully rendering the page. Present a progress indicator while resources are being loaded. Monitor the response time of your server. If your application takes more than 9 seconds to load, YAP displays an error message to the user. If an image request takes longer than 3 seconds, the request is terminated and the image will not be available for your application.
Don'ts
Don't use multiple, sequential calls if they can be combined into a single call. Don't overload your front-end with unnecessary JavaScript code if the same functionality can be achieved in the back-end.
Image Caching
YAP caches images from third-party servers, usually for a day or so. You can control this behavior by including the standard Cache-Control19 header in your HTTP responses.
Do's
Provide a 20x20-pixel icon in GIF format. The file name must end in .gif. Provide a recognizable 64x64-pixel icon for your Gallery/My Apps buttons. Provide a 16x16-pixel favicon. This will be used on the Yahoo.com homepage and for Updates events. Provide a 300x250-pixel screenshot that helps users see what your application offers.
17 18
30
Best Practices
Don'ts
Don't leave your first name, last name, nickname, and profile picture empty in your Yahoo! Profile. This information will help identify you and your application to users. Do not leave the application's icon, image, name, and description fields empty.
31
Introduction
This tutorial shows you how to set the contents of the Small View [17] of an Open Application. In the first part of the tutorial, you will set the Small View's default state [17] by entering HTML and YML as inlined text in a Content element of the the Gadget XML file. The second part of the tutorial shows you how to set the personalized state [18] of the Small View by calling the setSmallView method of the Yahoo! Social SDK for PHP1.
Prerequisites
Important Notice YAP will stop supporting Small View from 15th April 2012 onwards. To understand this material, you must be familiar with PHP, HTML/XHTML, and Web application development. You will need a Web server with PHP (version 5.2 or later) installed. On your Web server, install the Yahoo! Social SDK for PHP2. You can download this SDK from github3. You should already be familiar with the step-by-step process described in the Getting Started [9] section. You must have a Yahoo! Profile4.
1 2 3
32
33
6. Close the Preview window and return to the Gadget XML file. Copy the HTML span element shown below and paste it into the Small View default Content. <Content type="html" view="YahooSmallView, default"> <![CDATA[ <span style="background-color: #FFFF00; color: red; font=">You can use HTML, but you can't add links or user info.</span> ]]> </Content> Save the Gadget XML file and re-upload it, if necessary, to your Web server. 7. Click Preview again to see the figure below. Although you can format the Small View with HTML and inline CSS, adding user information is not possible. This is where YML [40] becomes important.
34
8. Close the Preview window. This time copy the YML below and paste it into the Small View default Content element. <Content type="html" view="YahooSmallView, default"> <![CDATA[ <yml:user-badge uid="viewer" linked="true" width="55" reflexive="false" useyou="false" capitalize="true" /> ]]> </Content> 9. The YML tag user-badge creates a default state that displays the user name and image. Try experimenting with other YML Code Examples [117].
35
../../oauth/guide/about.html#oauth-private_public_data
36
Setting the Small View of an Open Application The following steps show how to call the setSmallView with the YahooSession class. These steps are included in the set_small_view.php 6 script provided with this tutorial. 1. The $yahoo_session object is returned from the method requireSession. If $yahoo_session is not NULL, your user has authorized your application to access private data. $yahoo_session SUMER_SECRET); = YahooSession::requireSession(CONSUMER_KEY, CON-
2. From the YahooSession object named $yahoo_session, you call the method getSessionedUser to obtain a YahooUserobject. The YahooUser object will allow your application to set the Small View and get the user's social data. $yahoo_user = $yahoo_session->getSessionedUser(); 3. Before calling the method setSmallView from $yahoo_user, create content for your Small View. The YML below will show the end user's Profile photo and name. // Using YML gives you options for including user information in your content. Be sure to escape quotation marks. $small_view_content = "<yml:name uid=\"viewer\" linked=\"true\" capitalize=\"true\" useyou=\"false\"/>'s photo:" . "<yml:profile-pic uid=\"owner\" width=\"48\" linked=\"true\" />" 4. The method setSmallView in the YahooUser class only takes one parameter (content of Small View) and returns a boolean. Call the method from $yahoo_user, checking if the Small View was set. If the Small View was not set, record an error in the Web server's error log with YahooLogger::error. if(! $yahoo_user->setSmallView($small_view_content)) { YahooLogger::error("Could not set Small View."); }
6 7
./examples/set_small_view.phps ./examples/set_small_view_public.phps
37
Setting the Small View of an Open Application 2. Define constants to store the Consumer Key and Consumer Secret that Yahoo! provides when you create an application. define('CONSUMER_KEY',"your_Consumer_Key_goes_here"); define('CONSUMER_SECRET',"your_Consumer_Secret_goes_here"); 3. Pass the constants CONSUMER_KEY and CONSUMER_SECRET to the YahooApplication constructor to create the object $yahoo_two_legged_app. // You are performing the two-legged OAuth authorization here $yahoo_two_legged_app = new YahooApplication(CONSUMER_KEY,CONSUMER_SECRET); 4. Enter the HTML link to set the Small View. // Link the original photo on Flickr to a Flickr user's photo for the Small View $small_view_content = "<a href=\"http://www.flickr.com/photos/flickr_user/2947006845\"> The Rabbit: <img src=\"http://farm4.static.flickr.com/9821/rabbit.jpg\"></a>"; 5. Pass the $small_view_content and the end user's GUID to the setSmallView. The GUID is hardcoded in this example, but you can obtain the GUID from several different sources: from a database where you store user information, from a three-legged session, or from an authorized REST call to the Introspective GUID8 resource. // The GUID in your application will most likely obtained from a database query $guid = "your_GUID_goes_here"; // Set the Small View content $yahoo_two_legged_app->setSmallView($guid,$small_view_content); 6. The Small View you set should look similar to the figure below.
/social/rest_api_guide/introspective-guid-resource.html
38
Source Code
Important Notice YAP will stop supporting Small View from 15th April 2012 onwards. The set_small_view.php script is for accessing private data:
<xi:include></xi:include>
<xi:include></xi:include>
39
Introduction to YML
What is YML?
Similar in format to XML, Yahoo! Markup Language (YML) provides functionality to Open Applications in a safe and standardized fashion. You include YML tags in the HTML code of an Open Application. At runtime, YAP processes YML tags and converts them into HTML. If necessary, JavaScript libraries on the endpoints attach dynamic behaviors in the user's browser.
Benefits
YML offers the following benefits: Social data: YML tags make it easy for you to create applications that access social data, such as a list of the user's friends.
40
Dynamic and secure interactions: Several YML tags provide UI widgets and and rich interactions that normally require untrusted JavaScript. Data encapsulation: YML tags allow sensitive and timely data to be presented to end users in a uniform manner. The YML interpreter will replace tags with data only if the viewer has the proper access.
Syntax Rules
YML tags must conform to the following rules: YML tags are namespaced with yml:. However, since YML documents are not actually XML, no formal namespace declaration is required. All attributes must be enclosed in double quotes. To specify double quotes within an attribute value, enter the " character reference. If the data type of an attribute is boolean, allowed values are "true" and "false", which must be enclosed in double quotes. Singleton tags (that is, tags with no closing tags) must end with /> . White space and indentations are passed through, but ignored in the interpretation phase. YML tags accept and produce characters in UTF-8 only.
http://example.com/my-full-view params="?x=1"
http://www.ietf.org/rfc/rfc3986.txt
41
YML Lite
YML Lite is a subset of YML designed for improved performance. The Small View of an Open Application can contain only HTML or YML Lite tags, which are: yml:a yml:audio yml:form yml:if-env yml:include yml:name yml:profile-pic yml:pronoun yml:swf yml:user-badge
yml:a
Description
Creates a link to a different Open Application view, which can either be loaded in a new page view or DOM node.
Attributes
Name Type Required/Optional view string optional Description Name of application view linked to. The allowed values for application view are "YahooFullView" and "YahooSmallView". Parameters that are passed to the linked view. For YahooFullView, the params string is appended to the URL. See URL Parameter Encoding and Relative Paths [41]. The ID of a DOM node that will be replaced with the output of the view or params specified. The entire node is replaced. The ID of a DOM node where the contents will be substituted with the output of the view or params specified. Although the contents of the node are substituted, the node itself remains.
*Do not specify both replace and insert in the same element. If either of these attributes is used, the included content is filtered; specifically, JavaScript is removed and CSS is moved to the head of the document (where it can have global effects).
42
Examples
The following example creates a link in the small view that enables the user to navigate to the canvas (full) view. Include this code in the small view.
The next example displays the content of the small view in the canvas view. Include this code in the canvas view.
<div id="content"> You are currently viewing this page in canvas mode. <yml:a view="YahooSmallView">Click here to see your smallview content</yml:a> </div>
The following example shows how to use the insert parameter to place content in the canvas view. In this case, the content is from the small view. When the user clicks the "InsertContent" link, the content in this area disappears and the content from the small view is inserted in its place.
<!-- Include the following code in the small view --> <div id="mysvcontent"> <b> This content appears in the small view </b> </div> <!-- Include the following code in the canvas view --> <div id="myfvcontent"> <yml:a view="YahooSmallView" insert="insertContent">InsertContent</yml:a> </div> <div id="insertContent"> </div>
The following example shows how to use the replace parameter to place content from the small view in the canvas view. The replace parameter removes the div element, which cannot be referenced again. (In contrast, the insert parameter keeps div element, substituting only the content of the element.) Include the following code in the small view.
<div id="mysvcontent"> <b> This content is to be displayed in the smallView </b> </div> <!-- Include the following code in the canvas view -->
43
<div id="myfvcontent"> <yml:a view="YahooSmallView" replace="insertContent">ReplaceContent</yml:a> </div> <div id="insertContent"> When the user clicks the "ReplaceContent" link, the content in this area disappears and the content from the small view is inserted in its place. </div>
The next example passes parameters to the canvas view. The first time the user sees the canvas view, the parameters are not passed. When the user clicks the link created by yml:a, parameters (such as name and perf are passed to the canvas view and displayed by the echo statements. Include the following code in the canvas view.
<b> This Page is served by Welcome3.php <b> <br><br><br> <yml:a view="YahooFullView" params="Welcome3.php?name=kid&perf=good&work=yahoo&loc=us"> Click here to pass params </yml:a> Welcome <?php echo $_REQUEST["name"]; ?>.<br> You are <?php echo $_REQUEST["perf"]; ?>.<br> You work for <?php echo $_REQUEST["work"]; ?>.<br> You are located in <?php echo $_REQUEST["loc"]; ?>.<br>
Like the preceding example, the following example passes parameters to the canvas view. However, the yml:a tag in the following example includes the insert attribute, which inserts the response into the div element of the canvas view. Include the following code in the canvas view.
<div id="insertarea"> <b> This Page is served by Welcome3.php <b> <br><br><br> <yml:a view="YahooFullView" params="Welcome3.php?name=kid&perf=good&work=yahoo&loc=us" insert="insertarea"> Click here to pass params </yml:a> Welcome <?php echo $_REQUEST["name"]; ?>.<br> You are <?php echo $_REQUEST["perf"]; ?>.<br> You work for <?php echo $_REQUEST["work"]; ?>.<br> You are located in <?php echo $_REQUEST["loc"]; ?>.<br> </div>
The next example also passes parameters to the canvas view. When the user clicks the link created by yml:a, the response from folder2/folder3/file2.html is inserted into the div element "insertarea". Include the following code in the canvas view.
44
<div id="insertarea"> <b> This Page is served by Welcome3.php <b> <br><br><br> <yml:a view="YahooFullView" params="folder2/folder3/file2.html" insert="insertarea"> Click here to pass params </yml:a> </div>
More Examples: Navigate from Small View to Canvas View [121] HTML Form in a Canvas View Tabs in the Small View [117] Accordion Menu for an Open Application [124] Refreshing the Small View [126]
yml:audio
Description
Creates an audio media player that plays MP3 files. The contents of the tag may define a playlist in an XML format.
Attributes
Name src Type Required/Optional string required Description Full URL path to the MP3 file. Sets the player to auto start on load. Default is "false". Autostart is not available in a small view. Sets the volume to mute. Default is "false". Defines the volume level. Default is "0.7". Allows the audio track to loop. Default is "false". Defines the artist name. Default is "Unknown Artist". Defines the track name. Default is "Unknown Track".
autostart boolean optional mute loop artist title boolean optional optional optional optional boolean optional string string
volume string
Examples
<yml:audio src="http://www.yourdomain.com/file.mp3" title="My Car is Faster than Your Car" artist="Sammy Speedo" />
45
yml:customize
Description
Creates a link to an installation screen for your app. Use in Preview [20] content.
Attributes
None
Examples
<yml:customize>Click here to customize this app!</yml:customize>
yml:form
Description
Creates a form that posts to a different Open Application view, which can either be loaded in a new page view or a DOM node. Any form controls inside the yml:form will be posted as params to the view.
Attributes
Name Type Required/Optional view string optional Description Name of application view to link to. Allowed values are "YahooFullView" and "YahooSmallView". Parameters to pass to the view being linked to. For "YahooFullView", the params string is appended to the URL. See URL Parameter Encoding and Relative Paths [41]. The name of the form. The HTTP method, for example, POST. The ID of a DOM node that will be replaced with the output of the view or params specified. The entire node is replaced. The ID of a DOM node where the contents will be substituted with the output of the view or params specified. Although the contents of the node are substituted, the node itself remains.
name
string optional
Examples
<yml:form name="myform" params="add.php" method="GET"> <fieldset> Symbol: <input type="text" name="symbol"/> Shares: <input type="text" name="shares"/> <input type="hidden" name="user" value="<?php echo $profile->guid;
46
?>"/> </fieldset> <input type="submit" value="Buy" /> </yml:form> See also HTML Form in a Canvas View.
yml:friend-selector
Description
Displays an HTML select list of the user's friends. In a Yahoo! Profile, friends are called "Connections." Note: If the viewer (person running the application) and the target user (specified by uid attribute) are not the same, the friends list is available only if the viewer and the target user are friends.
Attributes
Name uid Type string Required/Optional optional Description The ID of the user to build a friends list for. Allowed values are a GUID, the string "viewer", and the string "owner". Default is "viewer". Allows multiple selections. Default is "false". Name of the form element that is generated. Default is "selectedFriend". Size of HTML select element. If "multiple" is set, then this defaults to 10. Otherwise, it's ignored. A comma-delimited list of user IDs (uid) that will be pre-selected. Default is nothing selected.
selected string
Examples
<yml:friend-selector uid="viewer"/> <yml:friend-selector uid="PQ12345"/> <yml:friend-selector uid="viewer" multiple="true" selected="PQ12345,AF34291,XP2qaAf3,owner"/> See also Friend Selector [119] and Friend Selector With Style [120].
yml:if-env
Description
Includes content or blocks of application code dynamically, based on the user's browser, version, operating system, or if the browser is considered A-grade2 by Yahoo!.
2
http://developer.yahoo.com/yui/articles/gbs/index.html
47
Attributes
Name ua Type Required/Optional string optional optional optional optional optional Description Specifies the browser user agent. Allowed values: "firefox", "safari", "ie", "opera" Shows the content if the user's browser version is at least the given value. Shows the content if the user's browser version is at most the given value. Specifies the user's operating system. Allowed values: "macosx", "winvista", "winxp", "win2000" Specifies the current view being displayed. Specifies that the browser and operating system must be an Agrade3 browser.
Examples
<yml:if-env agrade ="true">You are browsing with an A-grade browser</yml:if-env> <yml:if-env ua="firefox">You are browsing with Firefox</yml:if-env> <yml:if-env ua="ie" minver="6">IE greater than or equal to version 6</yml:if-env> <yml:if-env view="myview">Showing the "myview" view.</yml:if-env>
yml:include
Description
Includes content from the specified source. This tag also allows an application to refresh data in the Small View periodically. Content fetched by yml:include is filtered: HTML markup is passed through without modification. CSS is moved to the head of the document; it is never kept in the body. This means that styles in fetched content can affect the document globally. JavaScript is always removed.
Attributes
Name Type Required/Optional params string required Description The relative path to the content, including any required parameters. See URL Parameter Encoding and Relative Paths [41].
http://developer.yahoo.com/yui/articles/gbs/index.html
48
Name Type Required/Optional replace string optional* insert delay string optional* integer optional
Description The ID of the DOM node to replace with the output specified by the params attribute. The entire node is replaced. The ID of a DOM node whose contents will be replaced with the output specified by the params attribute. Only the node's contents are replaced. The number of milliseconds to wait before YAP gets the content specified by the params attribute. The content will not be loaded any sooner than the number of milliseconds specified. The default value is 0. The yml:include tag allows a maximum of five requests to run concurrently. If a page has more than five yml:include tags, and if these tags do not specify a delay, then an 400 error will occur. To avoid this error, specify the delay attribute to group the requests, as shown by the second yml:include example below. The delay attribute is not a strict contract. The YAP engine guarantees that the new content will not be loaded any sooner than the number of milliseconds specified by the delay attribute. However, it may take several seconds longer, depending on several factors. For example, if the value of delay is 5000, the new content may be inserted anywhere from 5 to 10 seconds after the content is loaded.
*Specify either replace or insert, but not both. Earlier implementations allowed yml:include elements with neither replace nor insert attributes, but this usage is deprecated.
Examples
In the following example, the yml:include tag initially provides the string "some text here". After a wait of 5000 milliseconds, the content from myprog.php is fetched to replace the string "some text here". <yml:include params="myprog.php?a=b" insert="xyz" delay="5000">some text here</yml:include> A maximum of five yml:include requests can run concurrently. The next example shows how to work around this limitation by setting the delay attribute to a different values in each group of five tags. <yml:include <yml:include <yml:include <yml:include <yml:include <yml:include <yml:include <yml:include <yml:include <yml:include params="http://example.com" params="http://example.com" params="http://example.com" params="http://example.com" params="http://example.com" params="http://example.com" params="http://example.com" params="http://example.com" params="http://example.com" params="http://example.com" insert="target" insert="target" insert="target" insert="target" insert="target" insert="target" insert="target" insert="target" insert="target" insert="target" delay="1000"/> delay="1000"/> delay="1000"/> delay="1000"/> delay="1000"/> delay="2000"/> delay="2000"/> delay="2000"/> delay="2000"/> delay="2000"/>
In the next example, the content from myprog.php replaces the DOM node that has the div ID acct. <yml:include params="myprog.php" insert="acct" /> . . .
49
<div id="acct"> <p>This text will be replaced by the output of myprog.php.</p> </div> The following example shows how the yml:include tag can help engage your users by keeping the data in the Small View up to date. When a user first installs this application, the Small View shows the following: "I am loading right now. Click here to load latest prices." The yml:include tag in the Small View gets data by calling the prices.php program. When prices.php returns the data, the Small View shows a string such as: "Prices as of Wed, 01 Jul 2009 17:51:01 -0600 Reload get_the_prices_or_whatever_it_is_you_do". The yml:include tag in prices.php refreshes the data every 5 minutes (30000 milliseconds). The user can force a refresh by clicking the "Reload" link provided by the yml:a tag of prices.php.
<!-- The following code (the div with id="loading") goes into the Small View. --> <div id="loading"> <yml:include replace="loading" params="prices.php">I am loading right now.</yml:include> <yml:a params="prices.php" replace="loading">Click here to load latest prices.</yml:a> </div> . . . <!-- The next div belongs in the prices.php file, which is installed on your web server. --> <div id="prices"> <yml:include delay="30000" params="prices.php" replace="prices" /> Prices as of <?php echo date('r'); ?> <yml:a params="prices.php" replace="prices">Reload</yml:a> <?php echo get_the_prices_or_whatever_it_is_you_do; ?> </div>
For another examle, see Refreshing the Small View Dynamically [128].
yml:message
Description
Creates a form that opens a message dialog for the user. With the dialog, the user can send a message to Yahoo! Connections (friends) or other users to tell them about the application. Those connections and users receiving the message will get the message in the form of an email and a notification4. The message element contains HTML form controls, each of which must have one of the following names (e.g. <input name="subject" ...>):
http://developer.yahoo.com/social/rest_api_guide/notifications_api.html
50
Name to subject body image GUID(s) of message recipient(s) subject of message content of message image that appears with message
Use
link_href target of link that appears with message link_label link text of link that appears with message submit label of "Submit" button in dialog that sender sees (defaults to "Send")
Attributes
Name Type Required/Optional view string optional params string optional Description Name of application view, for example, YahooFullView. Path to a program, relative to the application containing the yml:message tag. (See URL Parameter Encoding and Relative Paths [41].) The DOM node specified by the insert or replace attribute is inserted into or replaced by the output of the program specified by the params attribute. The ID of a DOM node to replace with the output of the params specified. The ID of a DOM node whose contents will be replaced with the output of the params specified.
Examples
The yml:message and div tags in the following listing are in the code of the Canvas View (YahooFullView). When the yml:message tag is executed, a form in a message dialog appears to the user. The message dialog is prepopulated with the form controls to, subject, and body, which the user can modify. The value of the to control is the GUID of a Yahoo! user. (You can specify multiple GUIDs, separated by commas.) In the message dialog, the "To" field contains the display name of the recipient. When the user clicks the submit button, an email is sent to the user specified by the to form control. The output of myprog.php is inserted into the DOM node of the div with the ID sect1, replacing the contents of the div. In Yahoo! Mail, the message appears as an email in the recepient's inbox. The text in the email's subject and body correspond to the values specified by the form controls in the yml:message tag. The email contains three other elements: an "Add" button, an image, and a link. By clicking the "Add" button, the recipient can install the application run by the sending user (that is, the application containing the yml:message tag). The image in the email is specified by the image form control of the yml:message tag. The link in the email is labelled "Click me", as specified by the link_label form control. The destination of the link is click_from_email.php, as indicated by link_href. . . . <yml:message view="YahooFullView"
51
params="myprog.php" insert="sect1"> <!-- GUID of the Yahoo Connection who is the message recipient. --> <input name="to" type="hidden" value="MHT5XY4FBG2OXXHQYWVPOF4A2E"> <!-- Subject of message. --> <input type="text" name="subject" value="an app you will like"> <!-- Body of message. --> <textarea name="body">This is a really funny app.</textarea> <!-- Image for message that appears to the recipient. --> <input type="text" name="image" value="http://host.domain/pic.jpg"> <!-- Target of link that appears to the recipient. --> <input type="hidden" name="link_href" value="click_from_email.php"> <!-- Label of link that appears to the recipient. --> <input type="hidden" name="link_label" value="Click me"> <!-- Label of submit button in the message dialog that appears to the sender. --> <input type="submit" name="submit" value="Send message now"> </yml:message> . . . <div id="sect1"> <p>This paragraph is replaced by the output of myprog.php.</p> </div> . . .
yml:name
Description
Displays the name of the specified person. Optionally, links to the person's Yahoo! Profile page.
Attributes
Name linked useyou Type Required/Optional boolean optional boolean optional Description If true, the name displayed links to the Yahoo! Profile page of the user. Default is "false". Display the word "you" instead of the user's actual name if the user is the viewer. Default is "false". Used in conjunction with the useyou="true" attribute. If true, shows "yourself" instead of "you". Default is "false". If true, capitalizes the first letter of the user's name. Default is "false".
52
Name uid
Description The ID of the user whose name is displayed. Allowed values are a GUID, "viewer", and "owner". Default is "viewer".
Examples
<yml:name uid="viewer" linked="true" capitalize="true" /> <yml:name uid="QPR12345" />
yml:profile-pic
Description
Displays the user's Yahoo! Profile picture. Optionally, links to the user's Yahoo! Profile page.
Attributes
Name Type Required/Optional linked boolean optional width int uid string optional optional Description If true, the picture displayed links to the user's Yahoo! Profile page. Default: false. The width and height in pixels of the picture. The maximum size is 48. Default: 48. The ID of the user whose picture is to be displayed. Allowed values are a specific user ID, the string "viewer", and the string "owner". Default: "viewer"
Examples
<yml:profile-pic uid="viewer" width="48" linked="false" /> <yml:profile-pic uid="PA385037" width="24" linked="true" /> <yml:profile-pic uid="owner" width="48" linked="true" /> See also Links to Yahoo! Profile [123].
53
yml:pronoun
Description
Displays a pronoun appropriate for the user ID and specified parameters. Note: Only define one of the tense-related attributes (possessive, reflexive, objective) at a time. If more than one is specified, one will take precedence over the rest.
Attributes
Name uid useyou Type Required/Optional string required Description User ID of the pronoun to render. Allowed values include an ID, the string "viewer", and the string "owner". Display "you" instead of a personal pronoun. Default is "true". Only applicable when uid="viewer". Display the possessive form of the pronoun (your, her, his, their). Default is "false". Display the reflexive form of the pronoun (yourself, himself, herself, themselves). Default is "false". Display the objective form of the pronoun (you, her, him, them). Default is "false". Display "they" if the gender cannot be determined. Default is "true". Capitalize the first letter of the pronoun. Default is "false".
boolean optional
possessive boolean optional reflexive objective usethey boolean optional boolean optional boolean optional
Examples
<yml:pronoun <yml:pronoun <yml:pronoun <yml:pronoun <yml:pronoun <yml:pronoun <yml:pronoun uid="viewer" useyou="true"/> uid="viewer" useyou="true" capitalize="true"/> uid="12345" possessive="true"/> uid="viewer" obj="true"/> uid="viewer" reflexive="true" capitalize="true"/> uid="owner"/> uid="viewer" usethey="true"/>
yml:share
Description
Creates a form that will open a "message" dialog for the user. It's just like yml:message, except that the message itself is not customizable, and you cannot specify a view where the user will "land" when they've sent the message. Also, the user has two allotments of messages that they can send per day: one for generic messages and another for sharing messages. Users receiving the message will get the message in the form of an email and a notification5.
http://developer.yahoo.com/social/rest_api_guide/notifications_api.html
54
Attributes
None
Examples
<yml:share> <!-- this is a list of guids, or just one guid --> <yml:friend-selector name="to" multiple="true" size="10" /> <input type="submit" value="Share with your friends!"> </yml:share>
yml:swf
Description
Includes a Shockware Flash (SWF) object in an Open Application.
Note
Caja imposes security restrictions [68] on the use of Flash code.
Attributes
Name src width height play loop menu quality scale align salign Type Required/Optional string int int required required required Description The full path URL to the SWF file. The width of the SWF object in pixels. The height of the SWF object in pixels. Autoplay when the SWF loads. Default is "true". Play the SWF continuously. Default is "false". Display a context menu when the user right-clicks the SWF object. Default is "false". Quality of the object. Allowed values: "high", "medium", "low". Default is "high". Scaling of the SWF object. Allowed values: "showall", "noborder", "exactfit", and "default". Default is "default". Alignment of the SWF object within the DOM object. Default is null. Alignment of the SWF movie within the SWF object. Allowed values: "t" (top), "b" (bottom), "l" (left), "r" (right). Also allowed are the following combinations: "tl", "tr", "bl", "br". Default is "tl". Opacity setting. Allowed values: "transparent", "opaque", "window". Default is "transparent". Hexadecimal SWF background color. Default is "#FFFFFF".
boolean optional boolean optional boolean optional string string string string optional optional optional optional
wmode
string
optional optional
bgcolor string
55
Name
Description Developer-supplied flashvars. The values must be HTML encoded. Default is null.
flashvars string
Tag contents
If the user does not have a high enough version of Flash, they'll see the contents of the tag. If you don't put anything here, then they'll see a default message with a link to download the latest version of Flash. If play is not set to "true", then the user will have to click the fallback content to activate the Flash movie.
Examples
<yml:swf src="http://example.com/app.swf" width="780" height="1000"/> <yml:swf src="http://example.com/app.swf" height="780" width="1000" flashvars="foo=bar"/>
yml:user-badge
Description
Displays the user badge, which is the name and picture of the user's Yahoo! Profile. Optionally, links to the person's Yahoo! Profile page.
Attributes
Name linked width Type boolean Required/Optional optional Description If true, the badge displayed links to the user's Yahoo! Profile page. Default is "true". The width in pixels of the badge with a max of 48. Default is "48". If true, shows "yourself" if useyou="true", otherwise it's ignored. Default is "false". If true, capitalize the first letter of the user's name. Default is "true". If true, and the user is the viewer, it'll show "you" instead of the name. Default is "false". The ID of the user whose badge is displayed. Allowed values are "viewer", "owner", or id. Default is "viewer".
Examples
<yml:user-badge uid="viewer" linked="true" width="48" reflexive="false" useyou="false" capitalize="true" />
56
57
Introduction
What is Caja?
Caja is a system that transforms ordinary HTML and JavaScript into a restricted form of JavaScript. The transformation is called "cajoling", and the result is "cajoled script". The cajoled script is then run within a security sandbox created in your browser. This provides a way to safely include arbitrary third-party content on any Web page. In principle, Caja should be transparent. Most JavaScript behaves the same whether it's run directly or cajoled. However, since Caja is currently evolving and incomplete, there are some noticeable differences. Caja is an Open Source project sponsored by Google and hosted at Google Code1.
http://code.google.com/p/google-caja/
58
Caja Support To get started right away, use a browser that supports console.log(), such as Firefox with the Firebug2 add-on, IE 8, or Safari 4.x. Note the following restrictions that apply to this release: Calls to alert() are redirected to console.log(). You can't use external scripts or external stylesheets yet. Inline them instead. Complex libraries such as YUI, jQuery, and Prototype might partially work if you inline them, but they are not seamless yet. The document.write method is subject to restrictions described in DOM Limitations [67]. However, innerHTML and many commonly-used DOM interfaces are supported.
http://getfirebug.com/
59
Caja Support
Transforming JavaScript into forms known to be safe The JavaScript transformation is the complicated part. It's basically a form of virtualization: Replaces references to real global variables with references to per-sandbox globals Rewrites references to this to prevent access to the real global scope Replaces most JavaScript code with semantically similar code that has runtime checks for security Rejects some JavaScript code early, such as with(obj){...}. Here's an example transformation. This JavaScript source code:
size = 3; function arf(geo, out) { var s4 = geo.compute(4 * size); var s5 = geo.compute(5 * size); out.value = (s4+s5)/2; return this; }; is cajoled into something like this:
$v.so('arf', (function () { function arf$_caller($dis, geo, out) { var s4 = $v.cm(geo, 'compute', [ 4 * $v.ro('size') ]); var s5 = $v.cm(geo, 'compute', [ 5 * $v.ro('size') ]); $v.s(out, 'value', (s4+s5)/2); return $dis; } ___.markFuncOnly(arf$_caller, 'arf$_caller'); return $v.dis(___.primFreeze(arf$_caller), 'arf'); })()); $v.so('size', 3);
Note
The actual Caja transformation is slightly different. This example has been simplified to make it easier to see what Caja is doing under the hood. Simple operations on local variables, such as (s4+s5)/2, are left alone. Some operations on local variables, such as geo.compute(), are rewritten to call $v functions. References to globals, such as size, are rewritten to call $v functions. References to this are rewritten to $dis. For more details about the JavaScript transformation, see the Google Caja page3.
http://code.google.com/p/google-caja/
60
Caja Support
61
Caja Support
For run-time errors, you can sometimes figure out the real location by looking at the JavaScript that Caja generates.
<applet> <base> <basefont> <embed> <frame> <frameset> <iframe> <isindex> <meta> <noframes> <noscript> <object> <param> <title>
Browsers Supported
Firefox 3.0 and 3.5 work pretty well. Safari 3 and 4 work pretty well. IE 7 and 8 work ok. IE 6 is a little flaky. Opera 9 and 10 probably work, but are not tested much.
YML
All YML tags work with Caja.
62
Caja Support
DOM manipulation
Caja provides proxied access to the DOM. If you look under the hood, you can see that you're actually manipulating instances of TameDocument, TameNode, etc. Many of the common DOM operations work, such as document.getElementById, document.createElement, node.firstChild, etc. However, Caja does not implement the complete DOM spec, so uncommon operations may not work yet. The document.write method is subject to restrictions described in DOM Limitations [67]. Setting and getting innerHTML is supported.
OpenSocial 0.9
Most of our OpenSocial 0.9 support is explicitly whitelisted for use in Caja. If you get runtime "Not readable" errors related to OpenSocial objects, check if you're using an older interface that is no longer part of the standard. You might also be using an OpenSocial 0.9 feature that is not supported by YAP; see Chapter 9, OpenSocial 0.9 Compatibility [77].
XHTML Strictness
If your application starts with an <?xml> tag or a <!DOCTYPE> that isn't HTML, then Caja will parse your application as XML, which is stricter than HTML, and stricter than what browsers will usually do.
63
Caja Support
Most of the time, it's easier to tell Caja that your app is HTML. Either omit <!DOCTYPE>, or use some HTML doctype, such as <!DOCTYPE html>. However, if you do want XHTML strictness, here are some common problems you might encounter: Unclosed tags or unbalanced tags are fatal errors, which will prevent your application from rendering at all. The <script> elements are not special. In HTML, a <script> element will read everything as literal text until a closing </script> tag, so you don't have to do anything about "<" or "&" characters in your script. In XML, a <script> element is parsed like any other tag, and the contents must be well-formed XML. So, you will usually want to quote your script bodies with <![CDATA[...]>.
HTML Limitations
<a target=...> We allow target=_blank and target=_top. Other values are deleted with a warning. Omitting target is the same as target=_top. For Flash, use <yml:swf> instead. Other embeds are not supported. All contents of the head element are stripped. Use plain HTML starting from inside the body. Not supported yet. Workaround depends on what you're trying to do. External stylesheets are not supported yet. Workaround is to inline the stylesheet. For Flash, use <yml:swf> instead. Other embeds are not supported. Inline scripts are supported by the server-side cajoler, but they're stripped by the client-side sanitizer. Workaround depends on what you're trying to do. External scripts are not supported yet. Workaround is to inline the script. Stylesheets are supported by the server-side cajoler, but they're stripped by the client-side sanitizer. Workaround depends on what you're trying to do. Caja currently rejects any javascript: URLs. If you're trying to use javascript:void(0) to make <a> buttons, try
<embed>
<head>
<iframe>
<link rel=stylesheet>
<object>
<script>
<script src=...>
<style>
javascript:void(0)
64
Caja Support
<a href="#" onclick="click(); return false">click</a> URL policy We currently allow http, https, and mailto URLs. This applies to any use of URLs, such as <a>, <img>, etc.
CSS Limitations
[] selectors A subset of [] selectors are supported, but only to the extent that the browser supports them. For example, IE7 will still ignore [] selectors. Not supported. Workaround depends on what you're trying to do. Not supported yet. Workaround is to inline the stylesheet. The text-decoration property of :visited is not supported. The following properties are supported: color, background-color, cursor.
expression()
@import
:visited
JavaScript limitations
eval() Not supported. Workaround depends on what you're trying to do. Not supported. This is similar to eval. Workaround depends on what you're trying to do. Code like this is not supported:
new Function()
node.onclick = '...'; That's an implicit eval, and has the same problem as explicit eval. Instead, put your event-handling code in a function, and assign the function to the event handler:
65
Caja Support
} node.onclick = handle_click; Names ending with underscore You can't use names ending with triple-underscore. Those are reserved for Caja's internal bookkeeping. You can't use names ending with double-underscore. Those are reserved for browser extensions. with (obj) { ... } This is not allowed since the dynamic behavior of with makes it difficult to analyze its security implications. The workaround is to remove the with statement and write obj.foo instead of just foo. If obj.foo is a method that refers to this, then peeling it off as a function and calling it directly will cause a runtime error:
<script> var get = document.getElementById; get('x'); // fails </script> That doesn't really work in raw JavaScript either, but instead of silently doing the wrong thing, Caja will throw an error:
Can't call .getElementById on a non function () { throw "This constructor cannot be called directly"; }: USELESS The reason is, JavaScript doesn't have bound methods, so that code probably doesn't do what you want. The code is saying to call getElementById with this bound to the global object, which is window. So if it succeeded, getElementById would get this===window, instead of this===document. The usual way of capturing a method as a function is to wrap the method call in a function:
<script>
66
Caja Support
var get = function(el) { return document.getElementById(el); }; get('x'); // works </script> And that will work with or without Caja.
DOM Limitations
Some limitations in the DOM interface result from missing implementation rather than security concerns. If the function or property you're trying to use isn't available, you may be able to do the same thing using currently supported interfaces. document.write The document.write method is subject to the following restrictions: Prohibited tags and attributes, including script, are silently removed. (The same filtering rules apply to innerHTML.) Incomplete tags are prohibited. For example, document.write('<div class="'); will not work, nor will document.write(className); or document.write('">');. Instead, concatenate the parts and write the result in one piece. Unbalanced tags, however, are allowed. For example, the following will work:
document.write('<b>'); document.write('he You can't change the nesting structure of static HTML. Consider this example:
<div id="div1"> <script> document.write(' A browser would interpret this code by closing div1, making div2 a sibling of div1. In Caja, however, the full structure is created before any scripts are executed, making div2 a child of div1; there is no way to change this with document.write. You can't use document.write to erase a document. In a browser, if a document is "closed", document.write erases it and starts a new document. This typically happens when document.write is called from an event listener. In Caja, however,
67
Caja Support
document.write always appends to the virtual document without erasing anything. As an alternative to document.write, you can use innerHTML:
<div id="x"></div> <script> var x = document.getElementById('x'); x.innerHTML = 'abc'; </script> You can also build up a DOM tree in pieces using document.createElement and so forth. window.event window.event isn't supported. This problem shows up if you have event-handling code like this:
<a onclick="click()">click</a> <script> function click() { alert(window.event); } </script> When you click on the text, the value you get will be undefined. The workaround is to pass in the event as an argument. Caja always binds event within onevent= handlers, so you can rewrite the example this way:
<a ocik"lc(vn|wno.vn)>lc<a nlc=cikeet|idweet"cik/> <script> function click(event) { alert(event); } </script> Another workaround is to use addEventListener instead.
Flash Restrictions
If your application serves Flash code, it should specify allowNetworking="internal" in its <object> and <embed> tags. This prevents Flash from fetching external pages, images, or JavaScript
68
Caja Support
routines (which may violate Caja restrictions). For more information about allowNetworking, see the ActionScript Developer's Guide4 and Flex documentation5 from Adobe.
stdin:stdin:1: <div id='x' foo='hi'></div> ^^^ WARNING: stdin:stdin:1+13 - 16: removing unknown attribute foo on div Most LINT and WARNING messages are harmless and can be ignored, but pay attention to any "failed to load external url" warnings. Here are some of the common errors: WARNING: ...: failed to load external url ... External scripts and stylesheets are currently not supported. Note, failure to load a script is not a fatal error, so Caja will keep processing your application, and it will probably fail on some issue that's a side effect of the load failure. Subsequent error messages are misleading in this case. The real problem is the load failure. Inline the external content to get around this. ERROR: ...: css property color has bad value: ==>...<== Caja is pretty strict about color names in CSS rules. Only the 16 standard color names are recognized. Use hexadecimal colors to get around this.
Runtime errors
Runtime errors usually show up as plain messages in the JavaScript console. Sometimes a runtime error will raise an exception that will be reported as an error, but these exceptions are often unrelated to the actual error.
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS1EFE2EDA-026D-4d14-864E79DFD56F87C6.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7c5b 5 http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7f18.html
69
Introduction
Note
In this release, YUI on YAP is a beta feature providing limited YUI library support. Caja [58], the YAP front-end securer, restricts the use of certain insecure JavaScript features within the Canvas view of a YAP Open application. However, several YUI utilities have been integrated with YAP, enabling you to include YUI functionality in a Canvas View. To understand this chapter, you should already be familiar with YUI. For more information, see the YUI Library sites on YDN1 and yuilibrary.com2.
YUI Core
YAHOO Global Object (base requirement for all YUI components) DOM Collection (convenience methods for DOM interactions) Event Utility (event normalization and custom events)
1 2
http://developer.yahoo.com/yui http://yuilibrary.com/
70
YUI Support
Selector Utility
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.2r1/build/yahoo-do To avoid errors, you would replace the Configurator-supplied script with this:
3 4 5
71
YUI Support
Event Handlers
This example shows how to set up a simple rating widget in an Open Application using the YUI event handler utilities.
Style Block
The CSS defines the core visualization of the rating widget. This style block should be placed within the same file as the widget, not included in an external style sheet. <style type="text/css"> div#ratings{ position:relative; border:1px solid rgb(204, 204, 204); padding:15px; color:rgb(89, 89, 89); width:275px; background-color:rgb(248, 248, 248); } div#ratings div{ width:25px; height:25px; float:left; margin:10px; border:1px solid #4891e9; } div#ratings div.normal{ background-color:#c4d8f0; } div#ratings div.hover{ background-color:#ebc357; } div#ratings div.clicked{ background-color:#4891e9; } div#ratings br.clear{ clear:both; height:1px; } </style>
HTML Block
The HTML of the ratings widget specifies a unique ID for each selectable option.
<div id="ratings"> <div class="normal" id="star1"></div> <div class="normal" id="star2"></div> <div class="normal" id="star3"></div> <div class="normal" id="star4"></div> <div class="normal" id="star5"></div> <br class="clear" /> </div>
JavaScript Block
The JavaScript code defines the event handlers and attaches the event listeners that will handle the mouse events. The ids array contains the unique IDs defined in the preceding HTML Block section. Later in the code, this array will be referenced when adding event listeners.
72
YUI Support
<script type="text/javascript"> //create the id array for all nodes which will be assigned YUI events var ids = ['star1', 'star2', 'star3', 'star4', 'star5'];
The next code snippet sets up the event handlers for the mouseover and mouseout events. The code uses the YUI Event utility to get the DOM node that generated the action. If the DOM node has not already been set to a clicked state, the class of the node is set to hover for the mouseover or to normal for the mouseout.
//handle the hover state by changing the class of the hover target //do not change the class if the target has already been clicked function fnOver(e){ var target = YAHOO.util.Event.getTarget(e, 1); if (! YAHOO.util.Dom.hasClass(target.id, 'clicked')){ target.className = 'hover'; } } //handle the out state by changing the class of the hover target //do not change the class if the target has already been clicked function fnOut(e){ var target = YAHOO.util.Event.getTarget(e, 1); if (! YAHOO.util.Dom.hasClass(target.id, 'clicked')){ target.className = 'normal'; } }
The next code snippet defines a handler for the click event. First, the code gets the DOM node that was clicked and determines the number that was clicked based on the ID of the node. Next, the getElementsByClassName utility gets all nodes that have a clicked state. The first for loop iterates through those nodes, setting them back to a normal class. The second for loop goes through all clickable nodes, from the first node to the node that was clicked, and sets their class to clicked.
//handle the click event function fnClick(e){ //get the node that was clicked var target = YAHOO.util.Event.getTarget(e, 1); var itmNum = target.id[target.id.length - 1]; //purge all clicked states for each previously selected node (reset class tonormal) var clickedEls = YAHOO.util.Dom.getElementsByClassName('clicked', 'div'); for (var i = 0; i < clickedEls.length; i++){ clickedEls[i].className = 'normal';
73
YUI Support
} //set the class for the current and lower nodes to a clicked state for (i = 1; i <= itmNum; i++){ document.getElementById('star' + i).className = 'clicked'; } }
Finally, the code calls the YUI addListener method to add the mouseover, mouseout, and click event listeners. These listeners are added to the nodes of the IDs in the array defined at the top of the JavaScript block.
//attach the YUI event handlers to all provided nodes YAHOO.util.Event.addListener(ids, "mouseover", fnOver); YAHOO.util.Event.addListener(ids, "mouseout", fnOut); YAHOO.util.Event.addListener(ids, "click", fnClick); </script>
Scrolling Animation
This example shows how to create an end-user license agreement (EULA) section scroller in an Open Application.
Style Block
The CSS defines a few simple styles to build out the EULA scroll container. These styles define visual representation of the widget and are independent of the actual animation effects. <style type="text/css"> #eulaScroll { height:6em; width:20em; overflow:auto; margin-bottom:1em; font:13px arial,helvetica,sans-serif; } </style>
74
YUI Support
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a ante non sapien vestibulum ullamcorper eu a elit. Maecenas pretium, magna sit amet volutpat aliquam, elit turpis sollicitudin velit, vel.</p> <p><b>Section 2</b><br /> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a ante non sapien vestibulum ullamcorper eu a elit. Maecenas pretium, magna sit amet volutpat aliquam, elit turpis sollicitudin velit, vel. </p> </div> <button id="btnSec1">Section 1</button> <button id="btnSec2">Section 2</button>
JavaScript Block
The JavaScript code defines the scrolling animations and button events. First, the code instantiates the two variables used in controlling the animation effects: scrollSections - An array that contains a scroll definition for each section that we wish to scroll to. The numeric identifiers defined by "to" are the left and top pixel locations to scroll to. anim - The variable for defining the animation effects on the eulaScroll node.
<script type="text/javascript"> (function(){ //variable instantiation var scrollSections = [{scroll: { to: [0, 0] }}, {scroll: { to: [0, 140] }}]; var anim;
The next code snippet uses the YUI Event utility to attach click events to both buttons defined in the HTML block. When a button is clicked, the code calls the runScrollAnim function, passing the array location of the scroll arguments for that section.
YAHOO.util.Event.on('btnSec1', 'click', function(){ runScrollAnim(0); }); YAHOO.util.Event.on('btnSec2', 'click', function(){ runScrollAnim(1); });
The following code defines runScrollAnim, the scrolling animation function that runs when either button is clicked. The function uses the YUI Animation Scroll utility and the scroll definition specify the animation configuration. Finally, the function animates the scrolling effect.
75
YUI Support
//run animation effects var runScrollAnim = function(sectionRef){ anim = new YAHOO.util.Scroll('eulaScroll', scrollSections[sectionRef]); anim.animate(); }; })(); </script>
76
Note
As a charter member of the OpenSocial Foundation, Yahoo! is committed to supporting OpenSocial specifications and continues to work with the Foundation on new features such as OSML and OpenSocial Templates. However, only the OpenSocial specifications documented here should be regarded as fully compatible with YAP; support for other specifications is provisional or "beta". For information about OpenSocial 0.8 support, see Chapter 10, OpenSocial 0.8 Compatibility [101].
1 2
77
The following OpenSocial features are enabled by specific Require elements in Gadget XML [93]: Lightweight Javascript API (OS Lite)4 <Require feature="osapi"/> Data Pipelining5 <Require feature="opensocial-data"/> Templating6 <Require feature="opensocial-templates"/>
4 5
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/OpenSocial-Specification.html#LightweightJSAPI http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/OpenSocial-Data-Pipelining.html 6 http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/OpenSocial-Templating.html 7 http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.TITLE 8 http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.BODY 9 http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.URL 10 http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.USER_ID 11 http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.APP_ID 12 http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.STREAM_FAVICON_URL 13 http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.STREAM_SOURCE_URL
78
Application Data
YAP supports up to 1,024 bytes of data per key and up to 1 MB per application.
Messaging
YAP does not support requestSendMessage and requestShareApp.
14 15
http://wiki.opensocial.org/index.php?title=Opensocial.Activity_%28v0.9%29#opensocial.Activity.Field.STREAM_TITLE http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.ID 16 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.NAME 17 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.THUMBNAIL_URL 18 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.NICKNAME 19 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.AGE 20 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.GENDER 21 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.STATUS 22 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.CURRENT_LOCATION 23 http://wiki.opensocial.org/index.php?title=Opensocial.Person_%28v0.9%29#opensocial.Person.Field.PROFILE_URL 24 http://wiki.opensocial.org/index.php?title=Opensocial.Name_%28v0.9%29#opensocial.Name.Field.UNSTRUCTURED 25 http://wiki.opensocial.org/index.php?title=Opensocial.Address_%28v0.9%29#opensocial.Address.Field.UNSTRUCTURED_ADDRESS
79
Using Environment.supportsField
The Environment.supportsField method returns true if the specified field is supported by the OpenSocial container. The method does not check to see if the field value exists for a given user. A user might not provide information such as age, gender, and time zone. If this information is not provided, it is not returned in the response. The supportsField method is useful for checking if the container stores data for a certain field, for example, location. If the container does not support location, then the application must store the location data. If the container does support location, but location is undefined, then the application can prompt the user to update location in the container's preferences.
Permissions
If your Yahoo! Open Application makes OpenSocial calls, on the Project Details page specify Read (or Read/Write) for the following data: Yahoo! Profiles Yahoo! Updates
80
OpenSocial 0.9 Compatibility The YAP supports the OpenSocial 0.8.1 RESTful API29. The details of this support follow. OpenSocial REST Endpoint: http://appstore.apps.yahooapis.com/social/rest Authentication: 3 Legged OAuth. For more information, see Yahoo! OAuth30 and OAuth Authorization Flow31. Supported APIs: People, Friends Supported Data formats: JSON Supported People Endpoints: /people/{guid}/@all- Collection of all people connected to user {guid}. /people/{guid}/@self- Profile record for user {guid}. /people/@me/@self- Profile record for requester. Supported Activities Endpoints: /activities/{guid}/@self- Collection of activities generated by given user. /activities/{guid}/@self- Collection of activities generated by an app for a given user /activities/{guid}/@self/{appid}/{activityid}- Individual activity resource, usually discovered from a collection. If you want to use the OpenSocial APIs in languages other than JavaScript, see the OpenSocial REST/RPC client libraries32.
Activities Demo
<!-YAP OpenSocial Activities Demo Reid Burke 10 Sep 2008 --> <script type="text/javascript"> function getViewerActivities() { var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID,
29 30 31
81
opensocial.IdSpec.PersonId.VIEWER); var req = opensocial.newDataRequest(); req.add(req.newFetchActivitiesRequest(idSpec), 'activities'); req.add(req.newFetchPeopleRequest(idSpec), 'people'); req.send(onLoadViewerActivities); } function getViewerFriendsActivities() { var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); idSpec.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); var req = opensocial.newDataRequest(); req.add(req.newFetchActivitiesRequest(idSpec), 'activities'); req.add(req.newFetchPeopleRequest(idSpec), 'people'); req.send(onLoadViewerFriendsActivities); } function onLoadViewerFriendsActivities(response) { var html = processResponse(response); document.getElementById('yap-activity-viewer-friends').innerHTML = html; } function onLoadViewerActivities(response) { var html = processResponse(response); document.getElementById('yap-activity-viewer').innerHTML = html; } function processResponse(response) { var activities = response.get('activities').getData(); var people = response.get('people').getData(); var peopleNames = {}; var peopleLink = {}; var peoplePic = {}; people.each(function(person) { peopleNames[person.getId()] = person.getDisplayName(); peopleLink[person.getId()] = person.getField(opensocial.Person.Field.PROFILE_URL); peoplePic[person.getId()] = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
82
}); var html = new Array(); var size = activities.getTotalSize(); if (size > 0) { var what = ' activities'; if (size == 1) what = ' activity'; html.push('<p>You have ' + size + what + ':</p>'); html.push('<ul>'); activities.each(function(activity) { var userId = activity.getField(opensocial.Activity.Field.USER_ID); var title = activity.getField(opensocial.Activity.Field.TITLE); html.push('<li><img src="' + peoplePic[userId] + '" height="32" width="32"><b>' + title + '</b> from <a href="' + peopleLink[userId] + '">' + peopleNames[userId] + '</a></li>'); }); html.push('</ul>'); } else { html.push('<div class="yap-error">No activities yet!</div>'); } return html.join(''); } function postActivity() { var params = {}; params[opensocial.Activity.Field.TITLE] = 'J. Hacker bookmarked the Yahoo! Application Platform'; params[opensocial.Activity.Field.BODY] = 'The Yahoo! Application Platform allows you to create social applications. Check it out!'; var activity = opensocial.newActivity(params); opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.LOW, function() { document.getElementById('yap-status').innerHTML = '<div>Activity created!</div>'; }); } gadgets.util.registerOnLoadHandler(function() { postActivity(); getViewerActivities(); getViewerFriendsActivities(); }); </script> <style type="text/css"> #yap-app { font-family: Arial, sans-serif; padding: 5px; }
83
#yap-status div, .yap-notice, .yap-error { background: #ffc; padding: 5px 15px 5px; margin-bottom: 3px; } .yap-error { font-style: italic; background: #fcc; } ul { list-style: none; } li { padding: 3px; border: 1px solid #ccc; margin-bottom: 3px; } </style> <div id="yap-app"> <h1>YAP OpenSocial Activities Demo</h1> <div id="yap-status"> <div>Posting a sample activity...</div> </div> <h3>Your Recent Updates</h3> <div id="yap-activity-viewer"> <div class="yap-notice">Loading...</div> </div> <h3>Your Friend's Recent Updates</h3> <div id="yap-activity-viewer-friends"> <div class="yap-notice">Loading...</div> </div> </div>
Gifts Demo
<!-A sample YAP 1.0 ready OpenSocial application. Adapted from http://code.google.com/apis/opensocial/articles/tutorial/tutorial-0.7.html
84
Updated for OpenSocial 0.8 and the Yahoo! Application Platform by Reid Burke 5 Sep 2008 YAP or 0.8 specific comments are annotated with YAPNOTE Updated 27 Oct 2008 Updated for OpenSocial 0.9 22 Oct 2010 --> <script type="text/javascript"> // Original JS code: http://opensocial-resources.googlecode.com/svn/samples/tutorial/tags/api-0.7/gifts_5_streams.js var globalGivenGifts = {}; var globalViewer = {}; var globalFriends = {}; // YAPNOTE: You may store up to 1K of data per AppData key, up to 1MB total. // Currently, using gadgets.json.stringify will include properties attached to objects used by Caja // which take up several hundred bytes. This is a known issue we are working on. // In this example, we will use a simple comma-seperated format for storing data in a // single AppData key to save storage space. function serializeGifts(obj) { var out = new Array(); for (var id in obj) { out.push(id); out.push(obj[id]); } return out.join(','); } function unserializeGifts(str) { var out = new Object(); var arr = str.split(','); var name = false; for (var i in arr) { if (!name) { name = arr[i]; continue; } out[name] = arr[i]; name = false; } return out; } function postActivity(nut, friend) { var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var title = globalViewer.getDisplayName() + ' gave ' +
85
globalFriends[friend] + ' ' + options[nut]; var params = {}; params[opensocial.Activity.Field.TITLE] = title; var activity = opensocial.newActivity(params); // YAPNOTE: HIGH priority events are treated the same as LOW priority activities in YAP v1.0 // The callback here is specified as an empty function opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, function() {}); } function updateReceivedList(viewer, data, friends) { var viewerId = viewer.getId(); var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var html = new Array(); html.push('You have received:<ul>'); friends.each(function(person) { var personData = data[person.getId()]; if (personData) { var json = data[person.getId()]['gifts']; // YAPNOTE: You must be very careful to create well-formed JavaScript when working with Caja. // Missing semicolons are a source of common problems, such as this line: // var gifts = {} // should be var gifts = {}; if (!json) { gifts = {}; } try { gifts = unserializeGifts(gadgets.util.unescapeString(json)); } catch (e) { gifts = {}; } // YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja // Therefore, this code: // for (i in gifts) { // should be: for (var i in gifts) { // YAPNOTE: We use alphanumeric GUIDs, so the +i > 0 check should be removed // This line: // if (+(i) > 0 && i == viewerId) { // should be simply: if (i == viewerId) { html.push('<li>' + options[gifts[i]] + ' from ' +
86
person.getDisplayName() + '</li>'); } } } }); html.push('</ul>'); document.getElementById('received').innerHTML = html.join(''); } function updateGiftList(viewer, data, friends) { var json = data[viewer.getId()]['gifts']; if (!json) { globalGivenGifts = {}; } try { globalGivenGifts = unserializeGifts(gadgets.util.unescapeString(json)); } catch (e) { globalGivenGifts = {}; } console.log(globalGivenGifts); var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var html = new Array(); html.push('You have given:'); html.push('<ul>'); // YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja // Therefore, this code: // for (i in globalGivenGifts) { // should be: for (var i in globalGivenGifts) { // YAPNOTE: We use alphanumeric GUIDs, so this check should be removed: //if (+(i) > 0) { html.push('<li>' + friends[i] + ' received ' + options[globalGivenGifts[i]] + '</li>'); //} } html.push('</ul>'); document.getElementById('given').innerHTML = html.join(''); } function giveGift() { var nut = document.getElementById('nut').value; var friend = document.getElementById('person').value; globalGivenGifts[friend] = nut; var json = serializeGifts(globalGivenGifts);
87
var req = opensocial.newDataRequest(); // YAPNOTE: DataRequest.PersonId was changed to IdSpec.PersonId in 0.8; hence this code: // req.add(req.newUpdatePersonAppDataRequest(opensocial.DataRequest.PersonId.VIEWER, 'gifts', json)); // became: // req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, 'gifts', json)); // In 0.9, the first parameter was eliminated (the ID is always VIEWER), so the call is now: req.add(req.newUpdatePersonAppDataRequest('gifts', json));
// YAPNOTE: For Person requests, specify a string ID as the first argument: // req.add(req.newFetchPersonRequest('VIEWER'), 'viewer'); // Although that code would work, the semantically correct way is to use IdSpec.PersonId when possible: req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
// YAPNOTE: For fetch People and AppData requests, specify an IdSpec object (not a string ID) as the first argument. // In 0.7, VIEWER_FRIENDS is no longer available. Instead, use NETWORK_DISTANCE // Therefore, this code: // req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'viewerFriends'); // req.add(req.newFetchPersonAppDataRequest('VIEWER', 'gifts'), 'data'); // req.add(req.newFetchPersonAppDataRequest('VIEWER_FRIENDS', 'gifts'), 'viewerFriendData'); // is now: var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); var idSpecFriends = opensocial.newIdSpec(); idSpecFriends.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); idSpecFriends.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); // YAPNOTE: Groups aren't supported in YAP v1. If you don't specify one, we assume you want friends req.add(req.newFetchPeopleRequest(idSpecFriends), 'viewerFriends'); req.add(req.newFetchPersonAppDataRequest(idSpec, 'gifts'), 'data'); req.add(req.newFetchPersonAppDataRequest(idSpecFriends, 'gifts'), 'viewerFriendData'); req.send(onLoadFriends);
88
postActivity(nut, friend); } function makeOptionsMenu() { var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var html = new Array(); html.push('<select id="nut">'); for (var i = 0; i < options.length; i++) { html.push('<option value="' + i + '">' + options[i] + '</option>'); } html.push('</select>'); document.getElementById('gifts').innerHTML = html.join(''); } function loadFriends() { var req = opensocial.newDataRequest(); // YAPNOTE: For Person requests, specify a string ID as the first argument: // req.add(req.newFetchPersonRequest('VIEWER'), 'viewer'); // Although that code would work, the semantically correct way is to use IdSpec.PersonId when possible: req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
// YAPNOTE: For fetch People and AppData requests, specify an IdSpec object (not a string ID) as the first argument. // In 0.7, VIEWER_FRIENDS is no longer available. Instead, use NETWORK_DISTANCE // Therefore, this code: // req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'viewerFriends'); // req.add(req.newFetchPersonAppDataRequest('VIEWER', 'gifts'), 'data'); // req.add(req.newFetchPersonAppDataRequest('VIEWER_FRIENDS', 'gifts'), 'viewerFriendData'); // is now: var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); var idSpecFriends = opensocial.newIdSpec(); idSpecFriends.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); idSpecFriends.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); // YAPNOTE: Groups aren't supported in YAP v1. If you don't specify one, we assume you want friends req.add(req.newFetchPeopleRequest(idSpecFriends), 'viewerFriends'); req.add(req.newFetchPersonAppDataRequest(idSpec, 'gifts'), 'data'); req.add(req.newFetchPersonAppDataRequest(idSpecFriends, 'gifts'),
89
'viewerFriendData'); req.send(onLoadFriends); } function onLoadFriends(data) { var viewer = globalViewer = data.get('viewer').getData(); var viewerFriends = data.get('viewerFriends').getData(); var giftData = data.get('data').getData(); var viewerFriendData = data.get('viewerFriendData').getData(); var friends = new Array(); // YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja // Therefore, this code: // html = new Array(); // should be: var 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').innerHTML = html.join(''); globalFriends = friends; updateGiftList(viewer, giftData, friends); updateReceivedList(viewer, viewerFriendData, viewerFriends); } function init() { loadFriends(); makeOptionsMenu(); } gadgets.util.registerOnLoadHandler(init); </script> <style type="text/css"> #yap-app { font-family: Arial, sans-serif; padding: 5px; } #yap-status div, .yap-notice, .yap-error { background: #ffc; padding: 5px 15px 5px; margin-bottom: 3px; } .yap-error {
90
font-style: italic; background: #fcc; } ul { list-style: none; } li { padding: 3px; border: 1px solid #ccc; margin-bottom: 3px; } </style> <!-- HTML that would be within the <Content> gadget XML: --> <div id='yap-app'> <h1>Gift Giving!</h1> <div id='give'> <form id='gift_form'> <!-- YAPNOTE: You can't link to javascript:void in Caja. Use '#' instead --> <!-- This is invalid: Give <span id='gifts'></span> to <span id='friends'></span>. <a href="javascript:void(0);" onclick='giveGift();'>Give!</a> --> Give <span id='gifts'></span> to <span id='friends'></span>. <a href="#" onclick='giveGift();'>Give!</a> </form> </div> <div id='given'></div> <!-- YAPNOTE: You must also be careful to create well-formed HTML markup when working with Caja --> <!-- This is invalid: <div id='received'</div> --> <div id='received'></div> </div>
91
try {function request() { // Prepare array with key value pair var params = {}; params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED; params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT; params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET; // makeRequest call var url = "t/uyaoic//l=lt0vNeC0mym22me0o2oapfe0e%gd0%(lt0i2r%si.nco%wr2wru%m&rts" hp/e.hasovy?se%gea%%fiNeC0a%fm0clri%wr2u%i2se%gd0o2oacntn2he0n_i3efm=o; t:qryop.m1qqec2inm22ala%%ig2r%si.ol2he0i2n0ec2u%fm0cloeis0e%oegdD)oajn gadgets.io.makeRequest(url, response, params); }; function response(obj) { /** obj.text contains the text of the page that was requested **/ var responseData =obj.text; var jsonTextData = gadgets.json.parse(responseData); var markUp = ''; var connectionCount = parseInt(jsonTextData.query.count); if(connectionCount > 1) { for(var i in jsonTextData.query.results.profile) { if(jsonTextData.query.results.profile[i].givenName == undefined) continue; markUp += '<div class="wrap-in"><imgsrc="' + jsonTextData.query.results.profile[i].image.imageUrl +'" width="70px" height="70px" /><h4>' +jsonTextData.query.results.profile[i].givenName + ' ' + jsonTextData.query.results.profile[i].familyName +'</h4></div>'; } } else { markUp += '<div class="wrap-in"><img src="' +jsonTextData.query.results.profile.image.imageUrl +'" width="70px" height="70px" /><h4>' +jsonTextData.query.results.profile.givenName + ' ' + jsonTextData.query.results.profile.familyName +'</h4></div>'; } document.getElementById("result-cell").innerHTML = markUp; }; request(); } catch(e) { document.getElementById("result-cell").innerHTML = e.toString(); } </script> </html>
92
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/Gadgets-API-Specification.html#gadgetsExtendedXSD
93
<?xml version="1.0" encoding="utf-8"?> <Module xmlns:yap="http://www.yahoo.com/ns/yap"> <ModulePrefs title="MyApp" title_url="http://example.com/" description="awesome app" author="John Doe" category="Entertainment-Games" category2="Sports">
<Require feature="yap.feature.classic"/> <Require feature="opensocial-0.8"/> <Icon>http://example.com/my_icon-16X16.gif</Icon> <Locale lang="en" country="us"/> <yap:Extension name="yap.gadgets.ShortDescription">An Awesome App</yap:Extension> <yap:Extension name="yap.gadgets.allow.SignOutRender">false</yap:Extension> <yap:Extension name="yap.gadgets.CreatorImageUrl">http://example.com/my_icon-256X256.gif</yap:Extension> <yap:Extension name="yap.gadgets.ApplicationIconUrl">http://example.com/my_icon-64X64.gif</yap:Extension> <yap:Extension name="yap.gadgets.YahooComIconUrl">http://example.com/my_icon-20X20.gif</yap:Extension> <yap:Extension name="yap.gadgets.ScreenshotUrl">http://example.com/my_screenshot-300X250.gif</yap:Extension> <yap:Extension name="yap.gadgets.TouUrl">http://example.com/tou.html</yap:Extension> <yap:Extension name="yap.gadgets.PrivacyUrl">http://example.com/privacy.html</yap:Extension> <yap:Extension name="yap.gadgets.Tag">games,sports,awesome</yap:Extension> </ModulePrefs> <Content type="html" view="YahooSmallView, default"><![CDATA[ This is the default Small View content. ]]></Content> <Content type="html" view="canvas" href="http://example.com/myApp/" ></Content> <Content type="html" view="preview" href="http://example.com/myApp/preview/" ></Content> <Content type="html"><![CDATA[ Default content ... ]]></Content> </Module>
94
The outline below shows the structure of a Gadget XML file, with elements in bold and attributes in italics. Items marked with an asterisk (*) are required for publication; the title attribute is required for an app to be pushed live.
<Module yap*>*<ModulePrefs title*, title_url, description*, author, category*, cate The fields in the Gadget XML file are documented in greater detail below.
Note
XML element and attribute names are case-sensitive. While some fields are not currently utilized, you should assume that information in the Gadget XML file will be made public when you publish your app.
r e - Use the default setting provided by Yahoo! (xmlns:yap="http://www.yahoo.com/ns/ya quired r e - Application metadata. quired r e - Title for the Open Application. quired ( f o r publicat i o n a n d l i v e testing)
title_url option- A URL that the gadget title links to. al descrip- r e - Description of your app (max 512 characters). tion quired author option- Developer's name. al c a t - r e - Application category. One of the strings listed in Application Categories [98]. egory quired c a t - option- Additional application category. One of the strings listed in Application Categories [98]. egory2 al Require option- Dependencies. al
95
Description
feature r e - Specifies a required feature. Unmodified legacy (pre-2.0) applications may need: quired <Require feature="yap.feature.classic"/> <Require feature="openso
These elements are supplied by Yahoo! in generated Gadget XML files. For other Require para pendix A, Parameters Passed to an Open Application [147], Gadget Configuration for OpenS Gadget Configuration for OpenSocial 0.8 [116]. Icon Link
r e - URL that returns a 16x16-pixel favicon for your application. Used for Yahoo! Updates34 and on quired homepage. See Supported Image Formats [4] for more information.
option- The link associated with the Lifecycle events defined in OpenSocial 8.035. YAP currently only suppor al app event. Example: <Link rel="event.removeapp" href="http://www.exam move?eventtype=removeapp&id=<guid>" /> rel href
r e - The lifecycle event type. Currently, the following is the only allowed value: event.re quired event.removeapp type is intended to help developers track uninstalls of their applications.
r e - The endpoint that is called when the lifecycle event is triggered. When the event type is removea quired should include the GUID of the user uninstalling the application. For example: http://www.exam move?eventtype=removeapp&id=<guid> r e - Supported languages. Use one Locale element for each supported language. quired
Locale lang
country option- ISO 3166-1 two-letter country code. al m e s - option- URL that returns a file conforming to the Message Bundle Schema36. sage al Extension
r e - YAP-specific parameters, e.g. <yap:Extension name="yap.gadgets.Tags">. Some a quired name below). ( s e e D e scription) name
r e - Name of parameter. The following parameters are supported: quired allow.SignOutRender (optional) - boolean determining if a user who is not signed in can insta appplication ApplicationIconUrl (required) - URL returning a 64x64-pixel image CreatorImageUrl (optional) - URL returning a 256x256-pixel image of your company logo CreatorWebsiteUrl (optional) - URL of your website
34 35
96
Description
ScreenshotUrl (required) - URL returning a 300x250-pixel preview image, used in "About" box a ShortDescription (required) - max 128 characaters Tags (optional) - keywords for indexing, comma separated TouUrl (optional) - URL of your terms of use YahooComIconUrl (required) - URL returning a 20x20-pixel GIF (must end in .gif) See Supported Image Formats [4] for more information about image files. Content type view href
r e - Content for your Open Application. Can specify a URL (through the href attribute) or contain a CD quired r e - Always specify "html" (<Content type="html">). quired option- Specifies the container in which content is displayed. See Content Sections [97]. al option- URL that returns HTML content. See Content Sections [97]. al
Content Sections
A Content element can provide content in two ways: Through a URL specified by the href attribute (<Content href="http://...">) or inlined in a CDATA section. If an href value is specified in a Content that also includes a CDATA section, the href attribute takes precedence and the inlined content is ignored. There is no limit to the number of Content elements in a Gadget XML file, but a typical Open Application uses three: one for the nonpersonalized (default) Small View, one for Canvas View, and one providing fallback content. An Open Application can also have Preview content for anonymous or unidentified users. The view attribute, which determines when content is displayed, can contain multiple comma-separated strings. Certain view values"YahooSmallView", "YahooFullView", "canvas", "home", "preview", and "default"have special meanings. You can combine these with identifying strings of your own. For example:
<Content view="YahooSmallView, default" ...> <Content view="YahooSmallView, preview A Content that doesn't specify a view attribute is automatically assigned view="default".
97
For Canvas View, YAP looks for a Content element with view value "YahooFullView"; if it doesn't find "YahooFullView", it looks for the value "canvas"; if it doesn't find "canvas", it looks for "default". If the user is not signed in or is unidentified, YAP looks for a Content element with view value "preview". (See Preview [20].) If multiple Content elements meet the applicable criterion (e.g. if there is more than one "YahooSmallView"): If there is an element that specifies an href attribute, it is preferred over elements with inline content. If more than one element specifies an href attribute, YAP uses the last processed element (usually the last one in the Gadget XML file). If none of the elements specifes an href attribute but there is more than one element with inline content, it concatenates the inline content of all the applicable elements. For fallback/default content, to be used when no other source is available, include a Content element that specifes view="default" or does not have a view attribute.
<Content type="html" view="YahooSmallView"><![CDATA[ <yml:a view="canvas" params="x To resolve the yml:a link in the first Content, "xyzw/info.php" is appended to "http://my_url/" to get "http://my_url/xyzw/info.php". If a yml:a link doesn't have a view attribute, its base URL is taken from the most recently processed "YahooFullView" Content element.
Application Categories
The category and category2 attributes can take any of the values listed below. BusinessAndFinance BusinessAndFinance-Classifieds BusinessAndFinanceJobsAndEmployment BusinessAndFinance-PersonalFinance BusinessAndFinance-RealEstate BusinessAndFinance-StockMarket BusinessAndFinanceOtherBusinessAndFinance Information Information-Blogs InformationCalendarsAndAlerts Information-Education Information-LocalAndMaps Information-Politics Information-Reference InformationVideosAndImages Information-Weather Information-OtherInformation Sports Sports-Basketball Sports-Fantasy Sports-Football Sports-Golf Sports-Local Sports-Soccer Sports-Tennis Sports-OtherSports
98
Lifestyle Lifestyle-Autos Lifestyle-Fashion Lifestyle-Gardening Lifestyle-Health Lifestyle-Hobbies LifestyleHomeImprovements Lifestyle-Horoscope Lifestyle-Parenting Lifestyle-Pets Lifestyle-Relationships Lifestyle-OtherLifestyle News News-Blogs News-International News-Local News-Regional News-OtherNews
Entertainment Entertainment-Celebrity Entertainment-Comedy Entertainment-Games Entertainment-Movies Entertainment-Music Entertainment-TV Entertainment-VideosAndImages Entertainment-OtherEntertainment Food Food-HealthAndResearch Food-Local Food-Recipes Food-OtherFood
Legacy Applications
If you are updating an application originally published under YAP 2.0 or earlier, you need to set up a Gadget XML file on your Web server and import it by clicking Import New XML on the Projects Details page. Because the old Details tab no longer exists on the Project Details page, you won't be able to change your application's metadata or default Small View content without editing this file. YAP automatically generates a Gadget XML file based on your app's existing configuration data. You can download the generated file, modify it, install it on your Web server, and import the new version: 1. In your browser, go to My Projects37. 2. Click the project you want to update, opening the Project Details page. 3. Click Download XML to retrieve the generated Gadget XML file. 4. Save the file to your computer and modify it if desired. 5. Copy the file to a directory on your Web server.
37
http://developer.yahoo.com/dashboard
99
6. On the Project Details page, click Import New XML. 7. Enter the URL of the Gadget XML file on your Web server and click Import. For more information about this process, see Configuring Your Application [10] and Updating Your Application [14]. For legacy applications, the YAP-generated Gadget XML file may contain special Require elements, including <Require feature="yap.feature.classic"/> and <Require feature="opensocial-0.8"/>, that you can remove when you are sure your app is compliant with the latest YAP standards. (See Appendix A, Parameters Passed to an Open Application [147] and Gadget Configuration for OpenSocial 0.8 [116].) We recommend testing your application carefully before publishing it without these Require elements. The text strings used to identify application categories have changed. For example, "Technology & Science:Computers / Software" has become "Tech-ComputersAndSoftware". See Application Categories [98] for a list of supported categories. Previously, applications were configured from the Project Details page under My Projects. The following table shows the correspondence between old Project Details configuration fields and the fields in a Gadget XML file. Old Configuration Field Application URL Small View Default Content Project Name Description Short Description Creator Name Creator Image Creator Website Application Icon Favicon Yahoo.com Icon Screenshot Terms of Use Privacy Policy Suppoted Languages Categories Tags Gadget XML Field Content element ("YahooFullView" or "canvas") Content element ("YahooSmallView" or "home") title (ModulePrefs attribute) description (ModulePrefs attribute) yap.gadgets.ShortDescription (Extensionname) author (ModulePrefs attribute) yap.gadgets.CreatorImage (Extensionname) yap.gadgets.CreatorWebsiteURL (Extensionname) yap.gadgets.ApplicationIconUrl (Extensionname) Icon (element) Icon (element) yap.gadgets.ScreenshotUrl (Extensionname) yap.gadgets.TouUrl (Extensionname) yap.gadgets.PrivacyUrl (Extensionname) Locale (elements) category and category2 (ModulePrefs attributes) yap.gadgets.Tag (Extensionname)
100
101
YAP supports the following Activity fields: opensocial.Activity.Field.ID opensocial.Activity.Field.TITLE opensocial.Activity.Field.BODY opensocial.Activity.Field.URL opensocial.Activity.Field.USER_ID opensocial.Activity.Field.POSTED_TIME
Application Data
YAP supports up to 1,024 bytes of data per key and up to 1 MB per application.
Messaging
YAP does not support requestSendMessage and requestShareApp.
102
YAP does not support other PeopleRequest fields, including FILTER, PROFILE_DETAILS, and SORT_ORDER. YAP behaves as if these fields are set to ALL.
Using Environment.supportsField
The Environment.supportsField method returns true if the specified field is supported by the OpenSocial container. The method does not check to see if the field value exists for a given user. A user might not provide information such as age, gender, and time zone. If this information is not provided, it is not returned in the response. The supportsField method is useful for checking if the container stores data for a certain field, for example, location. If the container does not support location, then the application must store the location data. If the container does support location, but location is undefined, then the application can prompt the user to update location in the container's preferences.
Permissions
If your Yahoo! Open Application makes OpenSocial calls, on the Project Details page specify Read (or Read/Write) for the following data: Yahoo! Profiles Yahoo! Updates
4 5
103
Supported APIs: People, Friends Supported Data formats: JSON Supported People Endpoints: /people/{guid}/@all- Collection of all people connected to user {guid}. /people/{guid}/@self- Profile record for user {guid}. /people/@me/@self- Profile record for requester. Supported Activities Endpoints: /activities/{guid}/@self- Collection of activities generated by given user. /activities/{guid}/@self- Collection of activities generated by an app for a given user. /activities/{guid}/@self/{appid}/{activityid}- Individual activity resource, usually discovered from a collection. If you want to use the OpenSocial APIs in languages other than JavaScript, see the OpenSocial REST/RPC client libraries7.
Using opensocial.IdSpec
When making some data requests, such as Activity, People, and newFetchPersonAppDataRequest, you must use an IdSpec object instead of specifying opensocial.IdSpec.PersonId by itself. Change the following 0.7 code:
7 8
http://wiki.opensocial.org/index.php?title=Client_Libraries http://www.opensocial.org/Technical-Resources/opensocial-release-notes
104
var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); // Greater than 1 is not supported. idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); // Specifying a GROUP_ID is unnecessary and is not supported. Our container assumes you always want friends. var req = opensocial.newDataRequest(); req.add(req.newFetchPeopleRequest(idSpec), 'viewerFriends');
105
Activities Demo
<!-YAP OpenSocial Activities Demo Reid Burke 10 Sep 2008 --> <script type="text/javascript"> function getViewerActivities() { var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); var req = opensocial.newDataRequest(); req.add(req.newFetchActivitiesRequest(idSpec), 'activities'); req.add(req.newFetchPeopleRequest(idSpec), 'people'); req.send(onLoadViewerActivities); } function getViewerFriendsActivities() { var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); idSpec.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); var req = opensocial.newDataRequest(); req.add(req.newFetchActivitiesRequest(idSpec), 'activities'); req.add(req.newFetchPeopleRequest(idSpec), 'people'); req.send(onLoadViewerFriendsActivities); } function onLoadViewerFriendsActivities(response) { var html = processResponse(response); document.getElementById('yap-activity-viewer-friends').innerHTML = html;
106
} function onLoadViewerActivities(response) { var html = processResponse(response); document.getElementById('yap-activity-viewer').innerHTML = html; } function processResponse(response) { var activities = response.get('activities').getData(); var people = response.get('people').getData(); var peopleNames = {}; var peopleLink = {}; var peoplePic = {}; people.each(function(person) { peopleNames[person.getId()] = person.getDisplayName(); peopleLink[person.getId()] = person.getField(opensocial.Person.Field.PROFILE_URL); peoplePic[person.getId()] = person.getField(opensocial.Person.Field.THUMBNAIL_URL); }); var html = new Array(); var size = activities.getTotalSize(); if (size > 0) { var what = ' activities'; if (size == 1) what = ' activity'; html.push('<p>You have ' + size + what + ':</p>'); html.push('<ul>'); activities.each(function(activity) { var userId = activity.getField(opensocial.Activity.Field.USER_ID); var title = activity.getField(opensocial.Activity.Field.TITLE); html.push('<li><img src="' + peoplePic[userId] + '" height="32" width="32"><b>' + title + '</b> from <a href="' + peopleLink[userId] + '">' + peopleNames[userId] + '</a></li>'); }); html.push('</ul>'); } else { html.push('<div class="yap-error">No activities yet!</div>'); } return html.join(''); } function postActivity() { var params = {}; params[opensocial.Activity.Field.TITLE] = 'J. Hacker bookmarked the
107
Yahoo! Application Platform'; params[opensocial.Activity.Field.BODY] = 'The Yahoo! Application Platform allows you to create social applications. Check it out!'; var activity = opensocial.newActivity(params); opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.LOW, function() { document.getElementById('yap-status').innerHTML = '<div>Activity created!</div>'; }); } gadgets.util.registerOnLoadHandler(function() { postActivity(); getViewerActivities(); getViewerFriendsActivities(); }); </script> <style type="text/css"> #yap-app { font-family: Arial, sans-serif; padding: 5px; } #yap-status div, .yap-notice, .yap-error { background: #ffc; padding: 5px 15px 5px; margin-bottom: 3px; } .yap-error { font-style: italic; background: #fcc; } ul { list-style: none; } li { padding: 3px; border: 1px solid #ccc; margin-bottom: 3px; } </style> <div id="yap-app"> <h1>YAP OpenSocial Activities Demo</h1> <div id="yap-status"> <div>Posting a sample activity...</div> </div>
108
<h3>Your Recent Updates</h3> <div id="yap-activity-viewer"> <div class="yap-notice">Loading...</div> </div> <h3>Your Friend's Recent Updates</h3> <div id="yap-activity-viewer-friends"> <div class="yap-notice">Loading...</div> </div> </div>
Gifts Demo
<!-A sample YAP 1.0 ready OpenSocial application. Adapted from http://code.google.com/apis/opensocial/articles/tutorial/tutorial-0.7.html
Updated for OpenSocial 0.8 and the Yahoo! Application Platform by Reid Burke 5 Sep 2008 YAP or 0.8 specific comments are annotated with YAPNOTE Updated 27 Oct 2008 --> <script type="text/javascript"> // Original JS code: http://opensocial-resources.googlecode.com/svn/samples/tutorial/tags/api-0.7/gifts_5_streams.js var globalGivenGifts = {}; var globalViewer = {}; var globalFriends = {}; // YAPNOTE: You may store up to 1K of data per AppData key, up to 1MB total. // Currently, using gadgets.json.stringify will include properties attached to objects used by Caja // which take up several hundred bytes. This is a known issue we are working on. // In this example, we will use a simple comma-seperated format for storing data in a // single AppData key to save storage space. function serializeGifts(obj) { var out = new Array(); for (var id in obj) { if (id.substr(-3) === '___') { continue; // YAPNOTE: Skip Caja properties, which always end with a triple underscore }
109
out.push(id); out.push(obj[id]); } return out.join(','); } function unserializeGifts(str) { var out = new Object(); var arr = str.split(','); var name = false; for (var i in arr) { if (!name) { name = arr[i]; continue; } out[name] = arr[i]; name = false; } return out; } function postActivity(nut, friend) { var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var title = globalViewer.getDisplayName() + ' gave ' + globalFriends[friend] + ' ' + options[nut]; var params = {}; params[opensocial.Activity.Field.TITLE] = title; var activity = opensocial.newActivity(params); // YAPNOTE: HIGH priority events are treated the same as LOW priority activities in YAP v1.0 // The callback here is specified as an empty function opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, function() {}); } function updateReceivedList(viewer, data, friends) { var viewerId = viewer.getId(); var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var html = new Array(); html.push('You have received:<ul>'); friends.each(function(person) { var personData = data[person.getId()]; if (personData) { var json = data[person.getId()]['gifts']; // YAPNOTE: You must be very careful to create well-formed JavaScript when working with Caja. // Missing semicolons are a source of common problems, such as this line:
110
// var gifts = {} // should be var gifts = {}; if (!json) { gifts = {}; } try { gifts = unserializeGifts(gadgets.util.unescapeString(json)); } catch (e) { gifts = {}; } // YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja // Therefore, this code: // for (i in gifts) { // should be: for (var i in gifts) { // YAPNOTE: We use alphanumeric GUIDs, so the +i > 0 check should be removed // This line: // if (+(i) > 0 && i == viewerId) { // should be simply: if (i == viewerId) { html.push('<li>' + options[gifts[i]] + ' from ' + person.getDisplayName() + '</li>'); } } } }); html.push('</ul>'); document.getElementById('received').innerHTML = html.join(''); } function updateGiftList(viewer, data, friends) { var json = data[viewer.getId()]['gifts']; if (!json) { globalGivenGifts = {}; } try { globalGivenGifts = unserializeGifts(gadgets.util.unescapeString(json)); } catch (e) { globalGivenGifts = {}; } console.log(globalGivenGifts); var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var html = new Array();
111
html.push('You have given:'); html.push('<ul>'); // YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja // Therefore, this code: // for (i in globalGivenGifts) { // should be: for (var i in globalGivenGifts) { // YAPNOTE: We use alphanumeric GUIDs, so this check should be removed: //if (+(i) > 0) { html.push('<li>' + friends[i] + ' received ' + options[globalGivenGifts[i]] + '</li>'); //} } html.push('</ul>'); document.getElementById('given').innerHTML = html.join(''); } function giveGift() { var nut = document.getElementById('nut').value; var friend = document.getElementById('person').value; globalGivenGifts[friend] = nut; var json = serializeGifts(globalGivenGifts); var req = opensocial.newDataRequest(); // YAPNOTE: DataRequest.PersonId is now IdSpec.PersonId in 0.8 // Therefore, this code: // req.add(req.newUpdatePersonAppDataRequest(opensocial.DataRequest.PersonId.VIEWER, 'gifts', json)); // is now: req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, 'gifts', json));
// YAPNOTE: For Person requests, specify a string ID as the first argument: // req.add(req.newFetchPersonRequest('VIEWER'), 'viewer'); // Although that code would work, the semantically correct way is to use IdSpec.PersonId when possible: req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
// YAPNOTE: For fetch People and AppData requests, specify an IdSpec object (not a string ID) as the first argument. // In 0.7, VIEWER_FRIENDS is no longer available. Instead, use NETWORK_DISTANCE // Therefore, this code: // req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'),
112
'viewerFriends'); // req.add(req.newFetchPersonAppDataRequest('VIEWER', 'gifts'), 'data'); // req.add(req.newFetchPersonAppDataRequest('VIEWER_FRIENDS', 'gifts'), 'viewerFriendData'); // is now: var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); var idSpecFriends = opensocial.newIdSpec(); idSpecFriends.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); idSpecFriends.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); // YAPNOTE: Groups aren't supported in YAP v1. If you don't specify one, we assume you want friends req.add(req.newFetchPeopleRequest(idSpecFriends), 'viewerFriends'); req.add(req.newFetchPersonAppDataRequest(idSpec, 'gifts'), 'data'); req.add(req.newFetchPersonAppDataRequest(idSpecFriends, 'gifts'), 'viewerFriendData'); req.send(onLoadFriends); postActivity(nut, friend); } function makeOptionsMenu() { var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut']; var html = new Array(); html.push('<select id="nut">'); for (var i = 0; i < options.length; i++) { html.push('<option value="' + i + '">' + options[i] + '</option>'); } html.push('</select>'); document.getElementById('gifts').innerHTML = html.join(''); } function loadFriends() { var req = opensocial.newDataRequest(); // YAPNOTE: For Person requests, specify a string ID as the first argument: // req.add(req.newFetchPersonRequest('VIEWER'), 'viewer'); // Although that code would work, the semantically correct way is to use IdSpec.PersonId when possible: req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
// YAPNOTE: For fetch People and AppData requests, specify an IdSpec object (not a string ID) as the first argument.
113
// In 0.7, VIEWER_FRIENDS is no longer available. Instead, use NETWORK_DISTANCE // Therefore, this code: // req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'viewerFriends'); // req.add(req.newFetchPersonAppDataRequest('VIEWER', 'gifts'), 'data'); // req.add(req.newFetchPersonAppDataRequest('VIEWER_FRIENDS', 'gifts'), 'viewerFriendData'); // is now: var idSpec = opensocial.newIdSpec(); idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); var idSpecFriends = opensocial.newIdSpec(); idSpecFriends.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER); idSpecFriends.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); // YAPNOTE: Groups aren't supported in YAP v1. If you don't specify one, we assume you want friends req.add(req.newFetchPeopleRequest(idSpecFriends), 'viewerFriends'); req.add(req.newFetchPersonAppDataRequest(idSpec, 'gifts'), 'data'); req.add(req.newFetchPersonAppDataRequest(idSpecFriends, 'gifts'), 'viewerFriendData'); req.send(onLoadFriends); } function onLoadFriends(data) { var viewer = globalViewer = data.get('viewer').getData(); var viewerFriends = data.get('viewerFriends').getData(); var giftData = data.get('data').getData(); var viewerFriendData = data.get('viewerFriendData').getData(); var friends = new Array(); // YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja // Therefore, this code: // html = new Array(); // should be: var 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').innerHTML = html.join(''); globalFriends = friends; updateGiftList(viewer, giftData, friends); updateReceivedList(viewer, viewerFriendData, viewerFriends);
114
} function init() { loadFriends(); makeOptionsMenu(); } gadgets.util.registerOnLoadHandler(init); </script> <style type="text/css"> #yap-app { font-family: Arial, sans-serif; padding: 5px; } #yap-status div, .yap-notice, .yap-error { background: #ffc; padding: 5px 15px 5px; margin-bottom: 3px; } .yap-error { font-style: italic; background: #fcc; } ul { list-style: none; } li { padding: 3px; border: 1px solid #ccc; margin-bottom: 3px; } </style> <!-- HTML that would be within the <Content> gadget XML: --> <div id='yap-app'> <h1>Gift Giving!</h1> <div id='give'> <form id='gift_form'> <!-- YAPNOTE: You can't link to javascript:void in Caja. Use '#' instead --> <!-- This is invalid: Give <span id='gifts'></span> to <span id='friends'></span>. <a href="javascript:void(0);" onclick='giveGift();'>Give!</a> --> Give <span id='gifts'></span> to <span id='friends'></span>. <a href="#" onclick='giveGift();'>Give!</a> </form> </div> <div id='given'></div>
115
<!-- YAPNOTE: You must also be careful to create well-formed HTML markup when working with Caja --> <!-- This is invalid: <div id='received'</div> --> <div id='received'></div> </div>
116
Prerequisites
Before trying out the following code examples, you should already know how to create and run Open Applications. The following tutorials will show you the basics: Getting Started [9] Setting the Small View [32] You must also have the following: A Web server accessible outside of your local network. You cannot use localhost. An installation of the Yahoo! Social SDK for PHP1 on your Web server. Your own Yahoo! Profile2.
Summary
This example shows how to create dynamic tabs in the small view of a Yahoo! Open Application. Specifically, it demonstrates the yml:a tag and the setSmallView method of the Yahoo! Social SDK for PHP.
Implementation Notes
The Small View in this example displays a set of three tabs. In the following screenshot of the Small View, the user has selected Tab 2, which shows the user's badge.
1 2
117
Code Examples
The tabs_smallview.php script shown in this example is a Canvas View application that builds the tabs in the Small View. The tabs_smallview.php script constructs the HTML for the tabs with the build_tabs function. Then, it it passes the constructed HTML to the setSmallView method:
. . . $tabCode .= "<div class='pad5'>" . build_tabs($tabNum) . '</div>'; . . . if (!$yahooSession->setSmallView($guid, $tabCode)){ echo "UNABLE TO SET SMALL VIEW"; } . . .
The build_tabs function constructs each tab with the following yml:a tag:
This yml:a tag creates a link, calls tabs_smallview.php with the tab number as the parameter, and replaces the tab contents into the tabContainer element.
examples/tabs_smallview.phps
118
Code Examples
Source Code
<xi:include></xi:include>
Friend Selector
Summary
This example shows how to use the yml:friend-selector tag to create an HTML select element that contains a list of the user's friends.
The following figure shows this example at runtime. When you click "Submit", the application runs the JavaScript showSelected function, which displays the GUID6 of the selected user.
For the full syntax of this tag, see the YML Reference7.
Source Code
<script language="JavaScript" type="text/javascript"> function showSelected() { var fsdiv = document.getElementById('fsdiv'); var fssel = fsdiv.getElementsByTagName('select')[0]; alert(fssel.value); document.getElementById("displayarea").innerHTML = fssel.value; } </script>
5 6
119
Code Examples
<form> <p>Select a user from the Friend Selector <br /> and then click Submit to see the user's GUID.</p> <p>Friend Selector:</p> <div id='fsdiv'> <yml:friend-selector uid="viewer" size="6" multiple="true"/> </div> <br /> <input type="button" value="Submit" onclick="showSelected();" /> <p>GUID:</p> <div id='displayarea' style="border: 2px solid black"> </div><br /> </form>
Next we can style it using a CSS block. We are using the .friend-selector class to select the friend-selector control (and all other friend-selector controls on the page) and add a funky design. This one looks kinda like a barcode. If you have an existing <style> block on your page you might want to reuse that.
<style type="text/css"> .friend-selector { margin: 1em; border: 2px dashed #fff; padding: 0.2em; color: white; background: black; font-family:Ariel,Helvetica,sans-serif; }
120
Code Examples
</style>
Source Code
<style type="text/css"> .friend-selector { margin: 1em; border: 2px dashed #fff; padding: 0.2em; color: white; background: black; font-family:Ariel,Helvetica,sans-serif; } </style> <yml:friend-selector multiple="true" />
../../yap/guide/a.html
121
Code Examples
Source Code
<yml:a view="YahooFullView">Click here to go to the Canvas View</yml:a>
Source Code
Top of canvas view. <div style="margin:20px"> <div id="preview" style="border: 1px dashed #bbb;width:300px;margin-bottom:20px;"> The Small View will appear here. </div> <yml:a view="YahooSmallView" insert="preview">Click to insert Small View.</yml:a> </div>
122
Code Examples
YML Tags
A Yahoo! Profile10 is where a Yahoo! user specifies identity information such as name, location, and gender. Additionally, a Yahoo! Profile contains social data such as a user's Connections (friends). Several YML tags enable you to create links to a user's Yahoo! Profile page. The yml:name tag shows displays the specified user's name. (On the Yahoo! Profile page, it's the Display Name.) In the following tag, the specified user is viewer, the person running the application. Because the linked attribute is true, the Display Name links to the Yahoo! Profile page.
The yml:profile-pic tags displays the photo of the user's Yahoo! Profile page. Again, linked is set to true. If you click the photo, the browser displays the Yahoo! Profile page.
The yml:user-badge displays the name and photo of the user's Yahoo! Profile page.
<yml:user-badge uid="viewer" width="20" linked="true" /> For details on the syntax of these tags, see the YML Reference11. The following screenshot shows the three links generated by the YML tags of this example:
123
Code Examples
Source Code
Hello, my name is <yml:name uid="viewer" linked="true" /> <hr> Click the below photo:<br> <yml:profile-pic uid="viewer" width="25" linked="true" /> <hr> Click the below user badge:<br> <yml:user-badge uid="viewer" width="20" linked="true" />
Implementation Notes
The accordion menu in this example is an HTML unordered list. Each item in the list is a link, created by a yml:a tag. When the user selects a link, the item is expanded and additional content appears. In the following screenshot, the Fruits item has been selected, so the following words are displayed: apples, oranges, pears.
The following code snippet shows how the accordian is implemented with a yml:a tag and the display style property. When the user clicks a list item, the ID of the item is passed to accordion.php as the parameter named expand. The yml:a tag replaces the content of the food element (the unordered list) with the output generated by the accordion.php script. In the foreach loop, if the value of expand matches the current item processed, that item is expanded by setting the display value to block. If the value does not match, display is set to none, hiding the contents. <ul id="food"> <? foreach($items as $index => $item): ?> <li> <yml:a view="YahooFullView" params="accordion.php?expand=<?= $index ?>" replace="food"><?= $item['header'] ?></yml:a> <div style="display:<?= $index == $expand ? 'block' : 'none' ?>"> <?= $item['content'] ?> </div> </li>
124
Code Examples
Source Code
<?php // Put the 3 elements of the accordion in an array. $items = array( array( 'header' => 'Fruits', 'content' => 'apples<br>oranges<br>pears' ), array( 'header' => 'Vegetables', 'content' => 'green beans<br>celery<br>carrots' ), array( 'header' => 'Grains', 'content' => 'rice<br>wheat' ) ); // Get the id of the accordion item to expand. $expand = $_GET['expand']; ?> <!-- The food list is replaced each time the user clicks an item in the accordion. --> <ul id="food"> <? foreach($items as $index => $item): ?> <li> <!-- The yml:a tag creates a clickable link for each accordion header. --> <yml:a view="YahooFullView" params="accordion.php?expand=<?= $index ?>" replace="food"><?= $item['header'] ?></yml:a> <!-- If the user clicked this item in the accordion, then expand it. Otherwise, hide it. --> <div style="display:<?= $index == $expand ? 'block' : 'none' ?>"> <?= $item['content'] ?> </div> </li> <?php endforeach ?>
125
Code Examples
</ul>
Summary
This code example shows how to use the yml:a tag to refresh content for the Small View of an Open Application. The yml:a tag creates a hyperlink that when clicked triggers an AJAX request for the Updates of the logged-in Yahoo! user. The default Small View of the Open Application is then replaced with the new content (the user's Updates).
// The link calls the script with a query string that // defines the key 'uid' and inserts content into the // div tag with the id 'containerHolder' $yml = "<yml:a params=\"refresh_smallview.php?uid=" . $uid . "\" insert=\"containerHolder\">Click Here to Refresh Small View!</yml:a>"; $yml .= "<div id='containerHolder'></div>";
To set the Small View, you use the method setSmallView from the Yahoo! Social SDK for PHP. The code below sets the Small View with the yml:a tag that was assigned to $yml.
12
http://www.nakedtechnologist.com/
126
Code Examples
The query string that was set in the yml:a tag earlier can be checked to determine if the link has been clicked. If the PHP global associative array $_REQUEST contains the uid value, the new content is generated, as shown in the code below:
// Check to see if the uid value has been passed // in the query string if(isset($_REQUEST['uid'])) { // Obtain the last five updates of user $updates = $yahoo_user->listUpdates(0,5); // If updates exist, create a list of links // to updates w/ images. if($updates) . . . }
13
examples/refresh_smallview.phps
127
Code Examples
6. In the Small View, click the link "Click Here to Refresh Small View" to get new content created by the AJAX call. You should now see your last five Updates, as shown in the figure below.
Source Code
<xi:include></xi:include>
Summary
This code example shows how to use the yml:include tag to dynamically refresh the content of the Small View of an Open Application. In this example, the Small View's content is refreshed every 5 seconds.
. . . $html = '<yml:include params="training_sdk.php" insert="loadHere"></yml:include><div id="loadHere">INSERT</div>'; if (!$yahoo_user->setSmallView($html)){ echo "NO SMALL VIEW"; }
14
http://www.nakedtechnologist.com/
128
Code Examples
. . .
The training_sdk.php program contains a yml:include tag and a call to the time() function. The yml:include tag has a delay parameter of 5000 milliseconds. As a result, every 5 seconds the time() function appears in the Small View, inserted into the loadHere div. Here is the code for training_sdk.php:
On some Yahoo! pages, YAP limits the number of times an application can call yml:include within a span of time. If this limit is exceeded, the following error message appears: error-243: maxIncludes limit hit for appid XXX If you encounter this error, reduce the number of calls to yml:include or increase the value of the delay parameter.
Source Code
Source for training_sdk_load.phps:
15 16
examples/training_sdk_load.phps examples/training_sdk.phps
129
Code Examples
<xi:include></xi:include>
<div id="example">Clicking here will do something!</div> <script language="javascript" type="text/javascript"> function handler(){ document.getElementById('example').innerHTML = "I've been handled."; } document.getElementById("example").onclick=handler; </script> To register the event and the handler with either addEventListener or attachEvent, use code like this:
<div id="example">Clicking here will do something!</div> <script language="javascript" type="text/javascript"> function handler(sender){ document.getElementById('example').innerHTML = "I've been handled."; } var myClickEl = document.getElementById('example'); if(myClickEl.addEventListener){ myClickEl.addEventListener('click',handler,false); } else if(myClickEl.attachEvent){ myClickEl.attachEvent('click',handler);
17
http://developer.yahoo.com/yap/guide/caja-support.html
130
Code Examples
} </script>
4. Mouse over or click on the container to see tooltip appear to the right or above the container.
18
examples/cajaready_eventhandling.html.txt
131
Code Examples
5. Great, you can now handle events without Caja affecting your code. To reinforce what you've learned, add code that handles double-clicking and makes the tooltip appear in a different location to the code example.
Source Code
<xi:include></xi:include>
JSON Conversion
Summary
This example shows how to convert a JSON object to a string and how to convert a string into JSON using the OpenSocial methods gadgets.json.stringify19 and gadgets.json.parse 20. Yahoo! has implemented these methods based on the OpenSocial API, so your code can safely convert JSON without being affected by Caja. Caja21 is a system that transforms ordinary HTML and JavaScript into a restricted form of JavaScript. The transformation is called "cajoling," and the result is "cajoled script."
19 20
132
Code Examples
// Define JSON object var myJSONObject = {"bindings": [ {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}, {"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"}, {"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"} ] }; // Use the gadgets.json.stringify OpenSocial method // to convert the JSON object to a string var jsonAsString = gadgets.json.stringify(myJSONObject); </script>
To convert a string into JSON, pass a string to the OpenSocial method gadgets.json.parse. You can then access any of the name/value pairs of the JSON object, as shown by the following code: <script language="JavaScript" type="text/javascript"> // Define JSON text: may also be server-side // serialized JSON string var jsontext = '{"firstname":"Jonathan","surname":"LeBlanc,"phone":["111-1234","222-3456"]}';
// Use the gadgets.json.parse OpenSocial method // to convert the json string to an object // Replaces the traditional JSON.parse JavaScript method var jsonObject = gadgets.json.parse(jsontext); // Display the value "Jonathan" alert(jsonObject.firstname); </script>
133
Code Examples
href="http://my_domain.com/ca-
Source Code
<xi:include></xi:include>
Ajax Request
by Jonathan LeBlanc25
Summary
This code example demonstrates how to use the method OpenSocial.gadgets.io.makeRequest26 to make Ajax requests to the Flickr API. Yahoo! has implemented this method based on the OpenSocial API27, so your code can safely have Ajax functionality without being affected by Caja. Caja28 is a system that transforms ordinary HTML and JavaScript into a restricted form of JavaScript. The transformation is called "cajoling," and the result is "cajoled script."
<script language="JavaScript" type="text/javascript"> // Run ajax request using OpenSocial gadgets.io.makeRequest // Define URL of a feed var url = "URL HERE"; // Define callback function var callback = xhrCallback; var params = {}; // Define content type of return value as FEED // Other possible content types: TEXT,DOM,JSON params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.FEED;
25 26
134
Code Examples
// Define method type (e.g. GET, POST) as POST params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST; // Run Ajax request gadgets.io.makeRequest(encodeURI(url), callback, params); </script> To get plain text from a response to an Ajax request, the callback function accesses the member variable text from the response (for example, response.text). Because the Ajax request in our example requests structured data (XML) with the keyword FEED, the callback function accesses the response with response.data, as shown by the following code: // Ajax request callback function xhrCallback(response){ // Check if data is returned from the request if (response.data){ // Do something with response.data } }
30
examples/cajaready_ajaxcall.html.txt
135
Code Examples
4. Enter three or more characters in the text-entry field to see different photos.
Source Code
<xi:include></xi:include>
31 32 33
136
Code Examples
href="http://my_do-
3. When you run the Canvas View, you should see a window similar to the figure below:
4. Choose a friend and post a message. The message will appear in the Updates stream on your Yahoo! Profile35 and on the application as seen below:
5. You can share the application by clicking the button "Send a share request!". The window below appears, allowing you to invite Connections to use your application.
35
http://profiles.yahoo.com
137
Code Examples
Source Code
<xi:include></xi:include>
MySocial Details
The following sections describe the source code of the mysocial.php script. If you want to jump ahead and try out the script, go to Setting Up this Example [143].
36 37
138
Code Examples
sion object defined in the PHP SDK. The application can then use the YahooSession to access Social Directory data. Note the constants that define the application's Consumer Key and Consumer Secret. These values are required for authorization with OAuth. When you register (create) your application on My Projects39, Yahoo! will create values for the Consumer Key and Consumer Secret. Then, you will insert those values in the following two lines of code. define("CONSUMER_KEY","your_Consumer_Key_goes_here"); define("CONSUMER_SECRET","your_Consumer_Secret_goes_here"); The constants CONSUMER_KEY and CONSUMER_SECRET are passed to the method requireSession in the class YahooSession. The static method call will return the YahooSession object $yahoo_session, which is an authorized session: $yahoo_session = YahooSession::requireSession(CONSUMER_KEY, CONSUMER_SECRET); Debugging is very important because of the complexity of the OAuth authorization. To enable debugging, make a static call to the method setDebug from the YahooLogger class. Debugging information is logged by the PHP function error_log, which writes errors to the Web server's error log. Starting the debugger will yield more descriptive error messages: YahooLogger::setDebug(true);
Getting a GUID
The Global User Identifier (GUID42) is a 26-byte string that identifies a user associated with his or her Social Directory data. A GUID exists for every Yahoo! user, but is never the same as the user's Yahoo! ID. The GUID can be obtained from the user Profile or used to capture the user Profile. The GUID can also be used to access specific user data by passing it as an argument to methods.
39 40 41
139
Code Examples
The member variable guid belongs to the YahooUser class, so you can reference the user's GUID from a YahooUser object. You can also retrieve the YahooUser object associated with a user running your application by calling the method getUser from a YahooSession object with the GUID as an argument. // Obtain the user GUID from the member variable guid in // the YahooUser class $guid = $user_profile->guid; // You can get a YahooUser object by specifying the GUID $next_user = $yahoo_session->getUser($guid);
../../social/rest_api_guide/extended-profile-resource.html ../../social/rest_api_guide/Single-update-resource.html
140
Code Examples
// insertUpdate $yahoo_user->insertUpdate($suid, $title, link_back_to_event); Next, we will get an Update. The method listUpdates takes two integers for the parameters. The two integers represent the start and the number of Updates45 you want to retrieve. In the example below, a list of the first 20 (0-20) Updates of the user are returned. The list of Updates can then be iterated through to access data for each status Update. Update information, such as the user's location, URLs for the icon, and the Update itself, can then be accessed through member variables. // Define the beginning and ending points for the Updates to be returned $user_updates = $yahoo_user->listUpdates(0,20); // Iterate through user updates and retrieve data from member variables foreach($user_updates as $update) { $desc = $update->loc_longForm; $icon = $update->loc_iconURL; $link = $update->link; $update_name = $update->loc_localizedName; $image_tag = sprintf('<img src="%s" height="20" width="20" alt="%s"/>', $icon, $update_name); $link_tag = sprintf('<a href="%s">%s</a>', $link, $desc); print("<p>"); echo "$image_tag"; echo "$link_tag"; print("</p>"); }
45 46
141
Code Examples
By iterating through the list of connections, you can obtain specific information about an individual connection49. foreach($user_updates as $update) { $desc = $update->loc_longForm; $icon = $update->loc_iconURL; $link = $update->link; $update_name = $update->loc_localizedName; $image_tag = sprintf('<img src="%s" height="20" width="20" alt="%s"/>', $icon, $update_name); $link_tag = sprintf('<a href="%s">%s</a>', $link, $desc); print("<p>"); echo "$image_tag"; echo "$link_tag"; print("</p>"); }
48 49
../../social/rest_api_guide/connections.html ../../social/rest_api_guide/connection.html
142
Code Examples
To set the status, call the method setPresence. This method takes a string, the user's message, as an argument. Once again, you call this method from the YahooUser object $yahoo_user. The return value will be an HTTP status code indicating the success or failure of the method call: // Pass a string (user's text message) to setPresence to // change user's status (Presence) $yahoo_user->setPresence("I'm on a raft floating down the Amazon."); To get the status, call the method getPresence. This method is called on the YahooUser object $yahoo_user and returns the status message entered by the user (or null if there is no status): // The method getPresence returns the user's status message $user_presence = $yahoo_user->getPresence();
50 51
examples/mysocial.phps http://developer.yahoo.com/social/sdk/php/
143
Code Examples 7. From the APIs and Services tab of the Project Details page, copy the values of the Consumer Key52 and Consumer Secret53. Paste the values into the following lines of mysocial.php: define("CONSUMER_KEY","your_Consumer_Key_goes_here"); define("CONSUMER_SECRET","your_Consumer_Secret_goes_here"); 8. From the Project Details page, run the Canvas View. A window similar to the following figure should appear. If you encounter errors, see Troubleshooting Your Application [144].
52 53
../../yos/glossary/gloss-entries.html#consumer-key ../../yos/glossary/gloss-entries.html#consumer-secret
144
Code Examples
1. Error: HTTP Code 404 Not Found Cause: The application was not found or could not be loaded. Fix: Make sure you entered the correct URL in your project's Gadget XML file. Check that you copied the the mysocial.php file to the correct directory on your Web server. 2. Error: Cannot get yahoo_session. Cause: This error message is specific to mysocial.php. It usually occurs if you have changed Permissions in the Project Details page, but did not update the Consumer Key and Consumer Secret values in the PHP source code. Whenever you save a modified Permissions, the Project Details page generates new values for the Consumer Key and Consumer Secret.
Note
This error also occurs if you try to run mysocial.php outside of YAP (that is, by specifying an URL that goes directly to your Web server and not to apps.yahoo.com). Fix: Make sure that the values for the Consumer Key and Consumer Secret in the source code match those displayed by the Project Details page. Also, make sure that the URL you use for running the application refers to apps.yahoo.com. 3. Error: Class 'YahooLogger' not found in ... Warning: include_once(.../Yahoo.inc) [function.include-once]: failed to open stream: No such file or directory in ... Cause: The Yahoo.inc file, which contains the Yahoo! Social SDK for PHP, could not be found. Fix: Make sure you installed the PHP SDK on your Web server. If the SDK is installed, check your source code, and make sure that the path for Yahoo.inc in the include_once or require_once statement is correct. 4. Error: Cannot get object-name, where object-name is one of the following: user_profile, user_updates, user_contacts, connections, presence. Cause: This error message is specific to mysocial.php. It occurs if the Permissions in the Project Details page are incorrect. For example, if the error message is "Cannot get user_contacts", the permission setting for Yahoo! Contacts is "No Access Needed", but it should be "Read". Fix: Specify the correct Permissions in the Project Details page. Note that when you save a changed Permissions, new values for the Consumer Key and Consumer Secret are generated, so you must update the source code with the new values.
Source Code
<xi:include></xi:include>
145
Code Examples
Reference/Resource basic_3_legged.php
54
Description
Author/Source
Shows you how to make a basic 3-legged Jonathan LeBlanc, Yahoo!, OAuth request. http://github.com Jonathan LeBlanc, Yahoo!, http://github.com
profile_get.php
56
Shows you how to get the profile for a user. Jonathan LeBlanc, Yahoo!, http://github.com
relationships_get.php Shows you how to get the relationships of Jonathan LeBlanc, Yahoo!, 57 a user and display their profiles. http://github.com updates_get.php 58 Shows you how to get updates for a user. Jonathan LeBlanc, Yahoo!, http://github.com updates_set.php
59
Shows you how to push a new update for Jonathan LeBlanc, Yahoo!, the user. http://github.com Shows you how to make a basic YQL re- Jonathan LeBlanc, Yahoo!, quest. http://github.com
yql_get.php 60
54 55
146
User Information Viewer In- Cookie in POST formation the session Owner Inform- Owner of POST ation the Profile Page Lan- Publisher guage Requested yap_viewer_guid yap_owner_guid
HEAD- Accept-Language ER
No
POST
lang
No
POST
country
No
P a g Timezone
e Publisher
POST POST
yap_tz yap_jurisdiction
Yes Yes
ISO 31661 country code identifying the country whose rules should be used for content moderation. OAuth 1.1 Access Token
Session Information Viewer's Ac- Registration POST cess Token and YAP
1
yap_viewer_access_token
No
http://en.wikipedia.org/wiki/ISO_3166
147
Parameters Passed to an Open Application Viewer's Ac- Registration POST cess Token and YAP Secret AppID Dropzone YAP Publisher POST POST yap_viewer_access_token_secret yap_appid yap_dropzone_id No OAuth 1.1 Token Secret
Yes Yes
Application ID The ID of the Yahoo! property, such as Yahoo! Finance, where the application will appear. The following lists the dropzone IDs and the associated Yahoo! properties: 852096 - My Yahoo! 852224 - Yahoo! Pulse 854272 - Yahoo! Toolbar 854400 - Yahoo! Messenger 854912 - Yahoo! Games 855808 - Yahoo! Sports
POST
yap_page_url
Yes
The URL where the application is hosted. This parameter has been deprecated and will no longer be available for YAP 2.6 and later versions. OAuth 1.0a Consumer Key Timestamp of the request in Unix time2. HMAC_SHA1 method signature
YAP Authentication C o n s u m e r YAP Engine POST Key Request Time YAP Engine POST Request Signa- YAP Engine POST ture Method Request Signa- YAP Engine POST ture OAuth Authorization Information OAuth Hash YAP Engine POST Algorithm oauth_body_hash No The body hash algorithm is determined by the OAuth signature method used.If the OAuth signature method is HMAC-SHA1 or RSA-SHA1, SHA1 [RFC3174] 3MUST be used as the body hash algorithm.If the OAuth signature method is PLAINTEXT, use of this specification provides yap_consumer_key yap_time oauth_signature_method oauth_signature Yes Yes No No
2 3
http://en.wikipedia.org/wiki/Unix_time http://tools.ietf.org/html/rfc3174
148
Parameters Passed to an Open Application no security benefit and is NOT RECOMMENDED. C o n s u m e r YAP Engine POST Key OAuth Nonce YAP Engine POST Value o a u t h _ c o n sumer_key oauth_nonce No No OAuth 1.0a Consumer Key A random string used to uniquely identify a request and required by the OAuth Core 1.0 Spec, Section 84. OAuth 1.0a Signature The signature method used to sign the request. Current timestamp of the request. This value must be +600 seconds of the current time. The OAuth version being used. YAP uses OAuth 1.0 Revision A5.
Request Signa- YAP Engine POST ture Request Signa- YAP Engine POST ture Method Request Time YAP Engine POST
No No No
OAuth sion
oauth_version
No
Browser Information User Agent Accept Browser Browser HEAD- H T ER TP_USER_AGENT HEAD- HTTP_ACCEPT ER HEAD- H T T P _ A C ER CEPT_ENCODING POST yap_view No No No
Yes
The request is targeted to either the Small View or Canvas View. The application ID that is obtained during application registration. The absolute URL to the gadget for the current view of the application. The GUID of the application owner. Indicates if the gadget has proxied content. The value is 1 if there is proxied content and 0 if there is no proxied content.
OpenSocial Information Application Registration POST ID and YAP Gadget URL Registration POST and YAP Owner GUID Owner of POST the Profile Content Proxy YAP Engine POST opensocial_app_id No
opensocial_app_url
No
opensocial_owner_id opensocial_proxied_content
No No
4 5
http://oauth.net/core/1.0/#nonce http://oauth.net/core/1.0a/
149
Parameters Passed to an Open Application User GUID Cookie Session in POST opensocial_viewer_id No The GUID of the user viewing the application.
150
General Information
This appendix describes the REST web services for development on the Yahoo! Application Platform (YAP). At the time of this writing, only the Set Small View web service is available for YAP development.
Authorization
The calls to the web services must use OAuth 1.1, with 2-legged authorization that matches the consumer key. Only HMAC-SHA1 signatures are supported.
Response Codes
Response Code Response Body Contents 200 400, 401 403 5xx No content No content No content Unstructured body OK OAuth failure OAuth signature mismatch Internal failure Description
151
Description
Replaces the statically rendered small view for a single user.
URI
The {guid} string is the Global User ID (GUID) of the Yahoo! user whose small view is set. http://appstore.apps.yahooapis.com/v1/cache/view/small/{guid}
Methods
POST PUT
Request Body
YML or HTML for the small view contents. The content-type is ignored, but content encoding is honored.
152