Flickr based sMash Application

IBM® WebSphere® sMash allows developers to build server-side mashup applications that enhance end-user experience by aggregating and manipulating content from different providers. We describe a simple Flickr based mashup application (zero.flickr.demo) developed using WebSphere sMash and PHP.

Features of the Flickr sample

This application illustrates the basic principles of server-side mashups by integrating content from Flickr into a rich single page AJAX application. The application requests XML content for photos associated with a particular search tag from Flickr using WebSphere sMash's connection API. The content is then re-packaged to represent a collection of photos in JSON, that can be rendered easily by a Dojo toolkit based client.

The next section describes how to run this application and is followed by an explanation of some of the interesting components of the application.

Installing and running the application

Obtaining a Flickr API key

This application leverages Flickr services to retrieve photos that are tagged with a specified keyword. The use of Flickr services requires obtaining an API key from the Flickr website. This can be done as follows.

  1. Use a browser to go to the Flickr services page
  2. Click the "Apply for a new API key" link on the page. This will take you to a login page where you will be required to use a Yahoo account to login.
  3. You may be required to create a new Flickr Account if you do not have one. At the end of this process, you should be able to apply for the API key.
  4. Keep the Flickr API key at hand so that it can be used later on in the setup.

Installing with the Command Line Interface

Download and unzip the WebSphere sMash command line (CLI) from Project Zero download page. Add the path to zero script located in the directory where the CLI was un-zipped to the PATH environment variable.

Create the flickr sample application from the WebSphere sMash repository as follows

zero create flickr.demo from zero:zero.flickr.demo

This will create the application by installing the application artifacts in a directory named flickr.demo.

Update the application's configuration file with the Flickr API key that you obtained earlier. The application's configuration file is located at flickr.demo/config/zero.config. Edit this file and uncomment the last line that sets the /config/flickr/key configuration value. Add the Flickr API key between the empty quoted string. This should look like the following, except that instead of the invalid key "11111222223333344444", you should use your Flickr API key.

# HTTP port (default is 8080) /config/http/port = 8080 # Runtime mode (default is "production") /config/runtime/mode="development" /config/flickr/photos_per_page = 24 # To use this application you need to obtain a valid API key from flickr. # Use the following http://www.flickr.com/services/api/misc.api_keys.html to get a API key # Uncomment the following line and specify a valid API key in quotes as the value /config/flickr/key = "11111222223333344444"

Start the application.

zero start

Installing with App Builder

Use the following steps to install and run the application with App Builder:

  1. Open the App Builder according to the instructions in the Getting Started guide.
  2. Click Create from repository.
  3. Specify the module to copy: zero:zero.flickr.demo.
  4. Application name: flickr.demo
  5. Destination folder: directory into which the new application folder is created, or keep in default directory.
  6. Click "Create"; the flickr.demo application is shown in your application list.
  7. Click "Edit" icon to open the flickr.demo application

Update the application's configuration file with the Flickr API key that you obtained earlier. The application's configuration file is located at /config/zero.config. Edit this file and uncomment the last line that sets the /config/flickr/key configuration value. Add the Flickr API key between the empty quoted string. This should look like the following, except that instead of the invalid key "11111222223333344444", you should use your Flickr API key.

# HTTP port (default is 8080) /config/http/port = 8080 # Runtime mode (default is "production") /config/runtime/mode="development" /config/flickr/photos_per_page = 24 # To use this application you need to obtain a valid API key from flickr. # Use the following http://www.flickr.com/services/api/misc.api_keys.html to get a API key # Uncomment the following line and specify a valid API key in quotes as the value /config/flickr/key = "11111222223333344444"

Click the Start button to start this application.

Accessing the application

Access the list_photos.html page on the application using http://localhost:8080/list_photos.html. The URI provided here assumes a typical configuration.

In the search field rendered by the page, you should be able to specify any arbitrary keyword and see a set of photos hosted at Flickr. You can click any of the photos to see a larger image of the photo on the right along with its title as shown in the following image.

The zero.flickr.demo sample application UI.

Understanding how the application works

We shall now look at the application code for this application to understand how this application works. We will start with the application configuration and PHP scripts that work with the Flickr service to provide the resource for the photo service. We will conclude with the client side XHTML artifacts that render the images on the browser.

Setting up the dependencies

We start by reviewing the dependencies for the sample application in the config/ivy.xml file of the application. The sample application has PHP scripts and hence the dependency to the zero.php module. The scripts use the WebSphere sMash's connection API through the zero.php.connection dependency. And lastly it uses the Dojo toolkit for the client side rendering of the photos through the zero.dojo dependency. These dependencies get resolved from the WebSphere sMash repository when the user types zero resolve on the command line to set up the application.

The Flickr service dependencies.

Configuring the Flickr service

While most WebSphere sMash application run with the default minimal configuration, we have chosen to incorporate some configuration in the application to illustrate configuration concepts. A more thorough treatment of configuration for WebSphere sMash application is presented as part of the Developer's guide. Let us examine the configuration for the application in the config/zero.config file. The configuration keys in line 1 through 5 are common to all applications and will not be discussed here. The configuration key /config/flickr/photos_per_page has the default value 24. All configuration keys look like URI separated by /. The convention is that configuration related keys are prefixed with /config. The value (right hand side) of these directives are JSON encoded strings.

The other configuration key is /config/flickr/key which is used to set the value of Flickr API key. This has been described in more detail in the section titled Application setup.

The configuration of the Flickr service.

Integrating with the Flickr service

The PHP script in the next two images, located at /app/scripts/flickr.php, defines a couple of functions that integrate with the Flickr service. The function flickr_search takes the search string as its argument and returns a collection of photo resources associated with the search tag.

The function sets up the Flickr REST uri to retrieve the photos from, in line 9. It appends the Flickr API key as a query parameter, which it retrieves from sMash Global Context using the key (/config/flickr/key) specified in the configuration file in line 10. All the configuration key value pairs are populated in the Global Context and can be accessed using the WebSphere sMash Global Context accessor function, zget function.

After creating the URI, the script attempts to retrieve the contents from the Flickr site, in line 15. To do this, it uses the sMash Connection API function, connection_get, which takes the uri and optional request headers as its argument. The response body is accessed from the result using result['body'], in line 18 of the script.

The default response from Flickr in encoded in XML. The script uses the WebSphere sMash XML decode function, xml_decode to create a XML object that can be used to access the XML data. In line 19, the script checks to see if the stat attribute for root element of the response is ok to signify a valid response, according to the Flickr API. The script then, gets the first and only photos element in the response, in line 21. In line 22, the script counts the number of photo elements in the photos element and processes each photo element by invoking the make_resource function on each element.

The PHP script that drives the Flickr service.

The function make_resource takes each photo object and creates a resource representation for the photo. It creates the thumbnail and image urls, according to the Flickr URI specification. It also includes the owner and title attributes in lines 46 and 47. The resource representation in the script is an associative array with title, owner, tnail and image attributes in line 48.

The PHP script that drives the Flickr service.

Photo resource handler

The sample application defines a photo resource that returns a collection of photo resources. By convention, the resource handler for this resource (photo) is located at app/resources/photo.php. This resource can be accessed using a server-relative URI of /resources/photo. The photo resource handler is a PHP script with a class named photo as indicated in line 3. Observe that we have included the functions defined in the previous section by including the flickr.php script in line 2.

This resource handler defines the onList method, which is dispatched to when a request with the GET method is made for the resource (collection) photo. In line 6, the method looks for the query parameter search using the global context key /request/params/search. If one was not found, the default value of flowers is used. The collection is retrieved by passing the query parameter to the flickr_search function described in the previous section. The resulting collection will be returned to the client as a JSON encoded string. In line 8, the Content-Type header is set appropriately and in line 9, the collection is encoded as a JSON string using the sMash function json_encode.

The photo resource handler.

Javascript utilities for working with Resource collections and XHTML

The sample application makes use of javascript helper functions to perform common operations involving the Document Object Model (DOM) of the page, XHTML and XML HTTP Request (XHR). The image below is a snippet from the javascript file public/zeroutil.js.

The getCollection function retrieves content (JSON array) from a specified URL which is processed one element at a time. Each element (JSON object) in the array is transformed in to a XHTML div node.The attributes of the object are represented as attributes of the div node for subsequent access. The contents of the div node are attribute values of specified attributes from the original JSON object. Each div node can be post processed to customize the content or attributes of the div node.

The javascript utilities for working with Resource Collections and XHTML.

The Dojo/Javascript imports for rendering the photos

We now look at the JavaScript and XHTML code that executes on the browser to render the UI for the application. We begin with the file public/list_photos.html. The following image illustrates the dojo initialization code.

Lines 6 through 10 imports the various styles associated with different aspects of UI. We will look at the styles defined in flickr.css, imported at line 9 in more detail later on. Lines 11 and 12 import the base Dojo Toolkit which is needed for any Dojo Toolkit based application. The src tag specifies the location of the dojo.js file relative to the page. Lines 13 through 21 declares the dependencies on various Dojo widgets and functions using the dojo.require method. Line 23 imports the zeroutil.js script described in the previous section.

The Dojo/javascript imports for rendering the photos.

The Javascript callback functions

This section describes the JavaScript callback functions that are triggered by various actions on behalf of the user. The function send_tag, defined in line 27, is triggered when the from containing the search string is submitted by the user. In line 28, it extracts the search string from a globally defined variable searchText associated with the appropriate input field in the form. The function uses the getCollection function defined in zeroutils.js to retrieve the photo collection associated with the search string. It instructs the getCollection function to render the resulting collection as div nodes in the container node with the id photos. Each resultant div node is also to be processed using the function photo_processor.

The photo_processor function, is invoked for each photo resource that is part of the collection retrieved by the getCollection function. In line 33, the function creates a img node in the DOM, followed by setting the src attribute of node to the _zero_tnail attribute of the div. Note that the getCollection function has prefixed _zero to the attributes associated with the resource, to prevent namespace collision with DOM attributes. In line 35, it sets the class of the image node to thumb defined in flickr.css. It attaches the img node as a child of the div node associated with the resource. In line 37, the div node is associated with the class multicolumn defined in flickr.css to provide a multi-column rendering of the thumbnails of the photos. In line 38, a mouse click event on the div node for the resource will cause the function zoom_photo to be invoked.

The zoom_photo function is invoked by the dojo runtime, when a mouse click event occurs on a photo div container. The parameter for the callback is the event. In line 42, the div container on which the click was targeted is retreived using currentTarget attribute of the event. In line 43, we create a img node in the DOM. In line 44, we set the src attribute of the DOM node, to the image attribute of the resource. Remember, the getCollection() function, prefixed all the attribute names of the resource with "_zero". The function then gets the object associated with a dojo widget defined called displayphoto using the dojo function dijit.byId. The displayphoto widget is defined in the next section as a ContentPane widget. The functions sets the content of widget to the img node created earlier and sets the title of the photo in a widget with id phototitle.

The javascript code for working with the REST service.

The XHTML for rendering the photos

The following image is a snippet of the XHTML content associated with list_photos.html. Line 53 associates the body of the page with the Dojo theme soria. The form element defined in line 54 is used to render and submit the search query for the photo resource. The script element of type, dojo/method, in lines 55 through 58, specify that the send_tag function should be invoked on form submission.

The input field for the form is Dojo widget of type dijit.form.TextBox and has an attribute jsId with value searchtext. The jsId attribute instructs the Dojo runtime to create a global variable named searchtext that represents the widget. This is used in the send_tag callback function described in the previous section.

The dijit.layout.BorderContainer widget declared in line 70 allows the rest of the content of the page to be laid out according to the style and region attributes in the contained div elements. The dijit.layout.ContentPane with id, photos, forms the bulks of the page and is used by send_tag callback described earlier to populate the thumbnails of the photos as the content of the widget. The style attribute of the widget specifies that this container should occupy 75% of the width of the containing BorderContainer widget. The Dojo widgets with id, phototitle and displayphoto declared in lines 78 through 86. These widgets are rendered to the right of the thumbnails due to the region attribute specified in line 78. The content for the widgets are set by the zoom_photo callback described in the previous section.

The XHTML associated with rendering the photos.

The CSS for rendering the photos

The following image is associated with some of the styles used in the application and located at public/css/flickr.css. The styles defined in lines 1 through 4 pertain to the body element for the DOM. It specifies the font size and the margin.

The styles defined in lines 6 through 11 are associated with any class named thumb. The style is associated with a class because the a . (period) precedes the name of the class. Similarly lines 13 through 15 are associated with a class named multicolumn. The float CSS property indicates that the element is to be floated to the left with the content flowing towards the right.

The styles for rendering photos.

Version 1.1.31300