Defining Content Views

The concept of views may be completely foreign to many application developers, but it’s a critical one to understand when you’re developing gadgets for social networking containers.

Having a cohesive view architecture is vital to an application’s success. There are countless instances where an application with a good concept fails because its developer expects people to use it from a specific view, so he neglects the other views by simply putting an image of, or call to action to load, the larger view (or vice versa, if he develops a small view but ignores the large).

The most important point here is that a user will never use your products in exactly the way that you intended them to be used. For this reason, you must spend equal time thinking about all of the views and how they interact, rather than focusing 99% of your attention on a single view and leaving the others as an afterthought. Some users may want to interact only with the subset of functionality defined in a small view, while others want to use all of the views depending on the particular tasks they want to complete at a given time. With this in mind, let’s explore view functionality in the context of an application gadget.

Each container defines its own views and variations depending on its use for gadgets (e.g., whether the container is inherently social in nature or geared to business applications). Table 3-9 outlines the view types that can be used in many of the available containers.

Table 3-9. View types

View name

Description

default

Renders on any view that does not have a Content section currently associated with it.

profile

Renders on the user’s profile. profile is visible to individuals viewing the user’s profile, even if they don’t have the gadget installed. This view can be used as a call to action for a viewer to install the application.

home

Renders within a smaller view, which is visible to the user only. This view is indicative of a gadget window and usually contains numerous gadgets installed by the user.

canvas

Renders within a larger “full” view. This view is typically used in conjunction with the smaller views (profile and home) and generally comprises a more extensive and fully featured version of the smaller views.

Many of the current containers implementing the OpenSocial standard are listed on the OpenSocial wiki at http://wiki.opensocial.org/index.php?title=Containers. If you click the links to view details, you’ll find some more container-specific information, including the supported view names.

Now that you understand the container views, we’ll explore the numerous methods for defining the views that you would like the gadget to build upon.

Creating a Content section

Note

If you are using inline markup within the Content nodes of your gadget instead of loading markup from an external file, you should always wrap the content in <![CDATA[ ... Content ... ]] tags. This will prevent the markup from being rendered as part of the gadget XML file—that is, as gadget-specific tags—when it loads.

A base-level Content section within a gadget includes a few items. Within the ModulePrefs element, if you want to be able to work with views through the gadget JavaScript layer, you will need to require the views feature by using the Require element. Following that, you can define a Content element with the view you want to load the content for. If you wish to inline your HTML, CSS, and JavaScript within the gadget, you should wrap the code within the Content section in CDATA tags. This will prevent your HTML elements from being treated as if they were part of the gadgets XML spec.

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="canvas">
      <![CDATA[
      This text will show up in my larger canvas gadget
  view
      ]]>
   </Content>
</Module>

Creating multiple Content sections

We can build upon our definition of a single Content section by defining additional sections the same way; we simply define a new Content element with another view. These new Content elements may include either inline or proxied content and will be treated in the same way as the original section.

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="canvas">
      <![CDATA[
      This text will show up in my larger canvas gadget view
      ]]>
   </Content>
   <Content view="home"
            type="url"
            href="http://www.site.com/index.php"
  />
</Module>

Creating one Content section with multiple views

If you want one Content section to define the content for multiple sections, you may define multiple comma-separated view names within the view attribute. This technique is especially useful when you have multiple small views within a container (such as home and profile) and wish to serve up the same content in each.

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="home, profile">
      <![CDATA[
      This text will show up in my home and profile gadget views
      ]]>
</Content>
</Module>

Creating cascading Content sections

There may be instances where you have pieces of content, such as a header, that should appear in multiple views. Instead of repeating the same code within each Content section for each view, you can create multiple Content sections with redundant views; when the gadget is rendered, the Content sections are concatenated together into a single code base for each section.

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="canvas">
      <![CDATA[
      <div>This is the content of my larger canvas view</div>
      ]]>
   </Content>
   <Content view="canvas, profile">
      <![CDATA[
      This is my footer
      ]]>
   </Content>
</Module>

If we load the preceding example in a container’s profile view, it produces the following:

This is my footer

If we load the example in the canvas view, however, the two sections are concatenated and give us the following:

This is the content of my larger canvas view
This is my footer

Navigating between views

In a social networking gadget container, Content sections are strictly tied to specific pages on the site. For instance, if I had a profile on a site and a gadget loaded on that profile, I would expect the Content section with the view attribute set to profile to load in that view. This is how containers are able to delegate locations for each section of a gadget. But this is not the only method for loading different Content sections—there are also JavaScript methods available within your gadget to push users through from one view to the next while keeping them in the context of your application. You enable these JavaScript functions by adding a Require element for the views feature.

This following example defines two views, profile and canvas, and uses an onclick handler to include a button within each view. These onclick handlers invoke the OpenSocial JavaScript gadgets view method requestNavigateTo to forward the user browser to the view specified as the function’s parameter:

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="profile">
      <![CDATA[
      <button onclick="gadgets.views.requestNavigateTo('canvas'), ">
         Click to navigate to the canvas view
      </button>
      ]]>
   </Content>
   <Content view="canvas">
   <![CDATA[
      <button onclick="gadgets.views.requestNavigateTo('profile'), ">
         Click to navigate to the profile view
      </button>
   ]]>
   </Content>
</Module>

This functionality allows you to control the view flow for your application. You could define a subset of functionality on the profile view, for instance, and include a call to action for the user to click a button to go to the canvas view, where she can see the full range of functionality for the application.

Passing data between views

While the navigation functionality is a valuable asset for controlling the flow of your application, you may need to pass data between the views during the navigation process. If the user were to set temporary state details in the profile view and then navigate to the canvas view, for example, you would want to pass that state information to the canvas view for processing.

You can pass information this way by extending the requestNavigateTo(...) parameter list to include a second parameter. This second parameter is a string containing all of the information to be passed to the next view:

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="profile">
      <![CDATA[
      <script type="text/javascript">
      function loadCanvas(postData){
         gadgets.views.requestNavigateTo('canvas', postData);
      }
      </script>
      <button onclick="loadCanvas('user123'),">
         Click to navigate to the canvas view
      </button>
      ]]>
   </Content>
   <Content view="canvas">
      <![CDATA[
      <div id="postData"></div>
      <script type="text/javascript">
         var postVal = gadgets.views.getParams();
         document.getElementById('postData').innerHTML = postVal;
      </script>
      ]]>
   </Content>
</Module>

Our profile view button will call a function, passing in a string representing a user variable. This variable is passed as the second parameter to our requestNavigateTo(...) method. The browser will then forward the user to the canvas view. Once the canvas view content loads, we capture the data passed to the view with the gadgets.views.getParams(...) method and insert it into a div in the view.

Creating and working with subviews

Subviews are a way to define different content pages (or slates) for a single view. They allow the developer to switch the content of a particular view without having to control that content flow with JavaScript. The developer will need JavaScript only to navigate from a main view to the subview.

To define a subview, you create a Content section as you did previously, but you name the view using the convention view.subviewname. For instance, if I want to create a subview named “sub” that resides on the canvas view, I would set the view attribute to canvas.sub. We can navigate to the subview by making a request to requestNavigateTo(...), as we’ve done before, and insert view.subviewname (e.g., canvas.sub) as the first parameter:

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="canvas">
      <![CDATA[
      <button onclick="gadgets.views.requestNavigateTo('canvas.sub'),">
         Click to navigate to the canvas sub page
      </button>
      ]]>
   </Content>
   <Content view="canvas.sub">
      <![CDATA[
      This is the content of my subpage
      ]]>
   </Content>
</Module>

When the preceding code runs and the user is viewing the canvas view, she will see a button asking her to click to navigate to the canvas subview. When she clicks this button, the content of the canvas view will be replaced with the content defined in the Content section with the view of canvas.sub.

Defining error view states

If you are implementing views that use a proxied content approach (i.e., that link to an external file via the href attribute), the OpenSocial specification defines standard methods for handling HTTP error states automatically within a gadget. Containers should process these content views, but at the very least they should display meaningful error messages to the user.

You should integrate an error view into your gadgets wherever possible. In an ideal world, your code will always work and your servers will have 100% uptime, but this is the real world—things break. An error fallback view, where you can display a pleasant “something went wrong” message with relevant links or instructions, is always better than an impersonal HTTP error message.

If containers encounter an error while trying to retrieve the proxied content, they should obtain the error message from a view with a name of viewname.error. So, for example, if the container gets a 404 Not Found error message when trying to retrieve the content for the canvas view, it should display an error message from content obtained from a view named canvas.error:

<Module>
   <ModulePrefs>
      <Require feature="views" />
   </ModulePrefs>
   <Content view="canvas" href="http://www.mysite.com/canvas.php" />
   <Content type="html" view="canvas.error">
      <![CDATA[
      An error occurred, please refresh the application window.
      ]]>
   </Content>
</Module>

In the preceding example, should a request to http://www.mysite.com/canvas.php fail, the container should display the message “An error occurred, please refresh the application window” to the user instead of something like “HTTP 404 Error: Resource Not Found.”

When a container supports these error views, they should be defined for each Content section that uses a proxied content approach.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.142.166