1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Building OpenSocial Apps- P6 doc

50 222 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Building OpenSocial Apps
Trường học Vietnam National University, Hanoi
Chuyên ngành Information Technology
Thể loại Thesis
Năm xuất bản 2024
Thành phố Hanoi
Định dạng
Số trang 50
Dung lượng 654,44 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

226 Chapter 10 OSML, Gadgets, and the Data Pipeline Table 10.8 OSML Markup Tags os:Name The specified person’s display name, hyperlinked to the person’s Profile hyperlinked to the perso

Trang 1

224 Chapter 10 OSML, Gadgets, and the Data Pipeline

Table 10.6 os:ActivitiesRequest Attributes

Key Required A string value used to identify this data within

the DataContext The key value must be unique within the app across all data tags.

userId Required A comma-delimited list of IDs to use in

conjunction with the groupId attribute Valid values are

@viewer

@owner

a specific user ID groupId Optional The group of users to get, relative to the value

defined in the userId attribute If this is not fied, it defaults to @self, which means the person object(s) corresponding to the value of the userId attribute Valid values are

speci-@self

@friends The value @self means the records specified in the userId attribute The value @friends means friends

of the user(s) specified in the userId attribute.

Fields Optional A comma-delimited list of OpenSocial activity

fields to return with each record.

startIndex Optional In a paged list of records, this specifies the

starting index for results.

number of records to return.

Table 10.7 os:DataRequest Attributes

Key Required A string value used to identify this data within

the DataContext The key value must be unique within the app across all data tags.

Currently, only GET requests are allowed Valid requests are

people.get (equivalent to os:PeopleRequest) activities.get (equivalent to

os:ActivitiesRequest) More endpoints are being added all the time, so check the MySpace developer site for the latest information.

Trang 2

JavaScript Blocks in OSML Apps

WarningGadget XML and OSML must be a well-formed XML document To prevent surprise parsing errors stemming from your JavaScript code, always make use of CDATA tags in your JavaScript blocks.

All apps that make use of OSML or Data Pipelining must be in gadget XMLformat and consist of well-formed XHTML content only If your Contentblockswrap their innards in CDATA tags as is suggested in some of the older GadgetXML documentation, none of the OSML or Data Pipeline tags will be evaluated

As a result, your app code must consist of well-formed XHTML content only AnyJavaScript code containing a “less-than” or “greater-than” test will violate thisrequirement

//]]>

</script>

Wrapping the client script block contents with CDATA sections instructs the OSMLparser to ignore things that might otherwise look like tags inside Even though tags arenot evaluated, expression language statements will be.Therefore, the following statementwill still work:

var greeting = "Welcome to my app, ${vwr.displayName}";

OpenSocial Markup Language The OpenSocial Markup Language, or OSML, is a tag-based markup language foradding and defining reusable user interface components, easily displaying content from

an external server, and managing simple control flow.When OSML is coupled with DataPipelining, it becomes a formidable new way of writing apps

In this section we introduce some of the basic tags available in the initial version ofOSML

OpenSocial Markup Language 225

Trang 3

Basic Display Tags

There are a limited number of convenience tags defined within OSML.These tags allowsimple and common UI elements to be easily rendered.The tag set is currently small, butlook for more complex UI elements to be added over time.Table 10.8 identifies the cur-rent built-in OSML markup tags

Remote Content Display Tags

HTML partial fragment rendering has become a common Ajax technique OSMLprovides a simple tag for displaying inline content from remote servers via a GETrequest MySpace also provides a more general-purpose display extension tag.Table 10.9identifies these two tags

Control Flow Tags

There are two basic mechanisms provided for display control flow:os:Ifandos:Repeat Additionally, MySpace provides an extension to os:Ifto give it an “else”

syntax as well.Table 10.10 identifies the control flow tags available in OSMLPutting It Together: OSML Tic-Tac-ToeOur previous “Hello World” gadget app gave a light introduction to using Data Pipelinetags along with the general gadget structure Now we’re going to take what we’ve seen

so far and apply it to our existing Tic-Tac-Toe app to see what happens

226 Chapter 10 OSML, Gadgets, and the Data Pipeline

Table 10.8 OSML Markup Tags

os:Name The specified person’s display name, hyperlinked to the

person’s Profile

hyperlinked to the person’s Profile os:PeopleSelector Displays a FriendPicker, scoped to the identified group

Table 10.9 Remote Content Display Tags

GET request and displays it inline at the tag location myspace:RenderRequest Fetches the markup using any HTTP method supported

by gadgets.io.makeRequest Contents may be displayed inline or in a specified element.

Trang 4

Setting Up the Gadget

Our first step is to move the existing code as is into the gadget XML format For this

step we’ll make use of our desktop code editor to paste all three of the existing appsurfaces into an empty gadget XML file.The OpenSocial Sandbox tool will be our bestfriend for validating our work in this initial stage

Creating the Initial Gadget File from Existing CodeHere we will construct the initial app gadget XML source file from the code blocks wehave already developed using the app Surface Editor At the end of these steps we willhave our same app in the gadget XML format

1 Navigate to the Sandbox by clicking Tools → OSTool/Harness from the developersite and clicking the Try the Beta OpenSocial Sandbox Editor link to open theSandbox Editor (shown in Figure 10.1)

2 Copy the contents of the Blank Sample Gadget and paste it into a new code file

in your code editor (Aptana for us)

3 Change the value of the “title” attribute of the <ModulePrefs>element from

“Hello World” to “OpenSocial Tic-Tac-Toe.”

4 Save your file as OpenSocialTTTGadget.xml

5 Open the source for the Home Tic-Tac-Toe surface in your code editor

6 Copy the entire contents of the Profile code file and paste it into your new gadget

in the Profile view template script.The surrounding code will look like this:

<Content type="html" view="home">

Putting It Together: OSML Tic-Tac-Toe 227

Table 10.10 OSML Control Flow Tags

os:If A conditional block that is shown if the expression

statement evaluates to true osx:Else Inverse conditional support for os:If This is a

MySpace extension to the OSML specification The osx:Else tag must appear immediately adjacent to

an os:If tag.

os:Repeat Iterates over an array of data items and displays the

contents of the repeat tag, evaluated for each data item

Trang 5

8 Select the Home view from the Views drop-down and click Render.You will see

an error similar to the following:

An error occurred while parsing EntityName Line 210, position 43.

// First check if there was an error back from the proxy if(!response || (response.errors && response.errors.length > 0)

|| response.errorCode){

retryRequest();

}

We need to fix these parsing errors before we can get any further

Fix Parsing ErrorsThe error we encountered was caused by a greater-than comparison occurring within aJavaScript block.To get around this, we’ll wrap all client JavaScript script tag contents inCDATA sections:

1 Go back to the gadget code in your source editor

2 Search for all the <script>tags that do not have a type attribute of

text/os-templateortext/os-data

228 Chapter 10 OSML, Gadgets, and the Data Pipeline

Figure 10.1 OpenSocial Sandbox Editor.

Trang 6

3 Add an opening CDATA tag immediately after the script tag and a closingCDATA tag immediately before the closing </script>tag.These tags should bepreceded by JavaScript inline comment characters Here is an example of what theupdated script block will look like:

Adding Other SurfacesThe other two surfaces must also be added to the gadget file Paste the Profile andCanvas code into the templates in the appropriate Contentblocks of your gadget file

Make sure you add CDATA sections to all JavaScript blocks until the Sandbox Editorcan render all three surfaces without any parsing errors

There is one more issue that will surface when reconciling the existing JavaScript appwith the gadget/OSML format Activity templates make use of an expression marker intheir templates that’s similar to one found in the Data Pipelining expression language

Both use the format ${SOME_VAR} to define an expression.The OSML renderer, findingthe embedded activity templates, will attempt to resolve the contained tokens as

Putting It Together: OSML Tic-Tac-Toe 229

Figure 10.2 Sandbox rendering of Home.

Trang 7

expressions and hiccup.The resolution is to build up the activity template strings in away that does not look like an expression to the server-side OSML processor

Search the gadget code for "${"and make the following changes:

// Version using the default template function rsmNotification(recipient, game_id){

// Set up all the data we'll need var body = "$"

body += "{sender} has finished their move ";

body += "in $"

body += "{app}, it's your turn!";

This splits the activity template expression up so the server doesn’t recognize it, but thetemplate still looks the same to the client code

Reusing Common Content

We have now created a single-source-file behemoth for our app, weighing in at almost

2500 lines of code It’s nice to have a single source file for storage and tracking purposes,but it can be a bit ungainly to manage from a code maintenance standpoint.The AptanaIDE does a nice job of allowing you to expand and collapse nodes for easier visibility,but that’s no substitute for cleaning up our code.We need to DRY things out a bit

230 Chapter 10 OSML, Gadgets, and the Data Pipeline

The DRY PrincipleThe acronym DRY stands for Don’t Repeat Yourself It’s a clever catchphrase to remind developers to reuse code as much as possible One of the failings of using the Surface Editor for writing apps is that you will find yourself repeating the same code over and over again With an OSML gadget an app can reuse parts of the code through the use of shared Content blocks.

If we look at our code, we’ll see a lot of repeated lines across the three surfaces Infact, putting the original Home and Profile source files in a diff tool (we usedWinMerge), we find that there are only five differences, consisting of an additional style

on Profile, some slightly different text on the button between the two, and a trailing div

on Profile.Through the use of shared Contentblocks, we can almost immediatelyremove 98% of the code associated with one of these surfaces

Merging Home and Profile with Shared Content BlocksGadgets and, by extension, OSML define their different surfaces with <Content>blocks

Theviewattribute of a Contentblock identifies the surface for which the enclosedcontent is valid During rendering of the OSML gadget, any and all Contentblocks that

Trang 8

have a view value matching the current surface are rendered in the order in which theyare encountered in the gadget XML file If a particular block of content is valid on morethan one surface, it may be identified as such by using a comma-delimited list of surfacenames for which it is to be rendered.This is in contrast to the app Surface Editor, whichallows one and only one discrete view per surface

Our diff of the Home and Profile sources showed that there are relatively few ences between the two Since Profile seems to be a superset of the Home view, withsome small textual changes, we’ll use that as the basis for both surfaces

differ-Creating Shared Style Content BlocksOne of the powers of the gadget XML format is the ability to stream shared code blocksacross multiple surface views In this section we use the notion of specifying multiplevalid viewvalues in a single Contentblock in order to share common markup, styles,and JavaScript between the Home and Profile surfaces

1 Edit your app’s gadget XML file to completely delete the home Contentblock

2 Change the profile Contentblock to also include the Home view, like this:

<Content type="html" view="profile, home">

3 Save your changes and view them using the Sandbox tool.The Home and Profilesurfaces should now match

4 Add three new Contentblocks with template script tags above the existing bined Home and Profile block.The first block will be used to hold the commonstyles.The second two will hold view-specific styles.The code should look likethis:

com-<Content type="html" view="profile, home">

5 Add the complete <style>block to the first shared Contentblock

Putting It Together: OSML Tic-Tac-Toe 231

Trang 9

6 Create new style elements in both the subsequent blocks and cut and paste thesubtitle-style class definition out of the shared style area and into each privatestyle block Modify the Home surface’s version to be display:none; the two private style blocks should appear as shown here:

<Content type="html" view="profile">

<script type="text/os-template">

<style>

.subtitle {

Customizing the Button Text Between ViewsThere are supposed to be some minor differences between the Home and Profile views

of our app In this section we add some subtle changes in a Contentblock specific tothe Home view that fixes the button to show appropriate text whether on the Homeview or the Profile view

1 Find the button element in the shared Profile/Home content template It shouldlook like this:

<button onclick="rNT(gadgets.views.ViewType.CANVAS);">

Click here to challenge me!</button>

2 Modify the element to add an attribute of id="playButton"to the buttonelement

232 Chapter 10 OSML, Gadgets, and the Data Pipeline

Trang 10

3 Add a new Contentblock after the shared Profile/Home Contentblock that isspecific to the Home view Include the template script tags and client-sideJavaScript script tags

<Content type="html" view="home">

"Click here to play now!";

5 Save and view the results.The Home view should now show the proper buttontext Here is an abbreviated code listing of the updated Home/Profile contentblocks:

<Content type="html" view="profile, home">

<script type="text/os-template">

<style>

body { background-color:#1E4C9F;

color:#fff;

margin:0;

padding:0;

} img { border:0;

}

Trang 11

<style>

.subtitle {

Trang 12

Working with Data

Having shared display code among the surfaces is great Having shared data is even moreawesome.The next step is to start migrating some of our data calls and our display tomake use of the Data Pipeline

We’ll start by changing the Viewer request to an os:ViewerRequestand use theexpression language to display the Viewer info

Getting Viewer Information with os:ViewerRequest

1 Edit the canvas Contentblock to add a new os-datasection above the os-templatesection.The modified code section will look like this:

<Content type="html" view="home">

<os:ViewerRequest key="viewer" fields="@all" />

3 Edit the contents of the myinfodiv to pull the Viewer image and name from ournew pipelined data stored under the viewerkey in the DataContext An expres-sion language statement is used to set the name and image URL:

<div id="myinfo" class="player_info right_column">

<img class="profile_image" src="${viewer.thumbnailUrl}" />

Trang 13

Updating the Player Bio Lightbox to Use Client-Side DataContext

In this section we make some minor refactors to the existing JavaScript function thatcontrols the display of the opponent box At this point we only swap out some ofthe data calls with calls to the DataContext and leave most of the code intact

Moving to using a template will be introduced in the next chapter: Chapter 11,Advanced OSML

1 Add a new div below the myinfodiv with the ID of playerBioWrapperand setthe style equal to display:none

2 Search for the printPersonfunction Notice all of the HTML being built later

in the function In the original version of this function the div element for thelightbox is created dynamically.We’re going to code the lightbox content containerdirectly on the page

3 Copy out the wrapping divs and close button divs Add these to the div created instep 1.Your markup should appear like this:

<div id="playerBioWrapper" style="display:none;">

<div id='player_bio'><div id='player_bio_title'>Player Bio</div>

<div id="bio_contents"></div>

<div class='clear'></div>

<div id='bio_close'><a href='javascript:TTT.LightBox.hide();'>close </a></div>

Trang 14

str += vwr.thumbnailUrl str += "' /></div><div>\n";

var tryAppendLine = function(val){

if(val && val != ""){

return val + "<br />\n";

} } str += tryAppendLine (vwr.DisplayName);

str += tryAppendLine (vwr.DateOfBirth);

7 Assign the contents of your string to the innerHTMLof the element internal tothe player bio div and assign the entire bio contents to the lightbox:

var bioElem = document.getElementById("playerBioWrapper");

var bioContents = document.getElementById("bio_contents");

bioContents.innerHTML = str;

//Add to lightbox TTT.LightBox.setContent(bioElem.innerHTML);

//Now show TTT.LightBox.show();

8 Update the More link to fire the new showViewerBiofunction instead of directlyinvoking the lightbox.Your code should properly show the lightbox again

Displaying Data Lists

The next operation is to display a list of friends.This is done by combining the results of

anos:PeopleRequesttag with an os:Repeatcontrol.We’re going to update theInvite tab to use OSML and the Data Pipeline instead of client XHR requests

Displaying Friends with a Repeater

A repeater allows your app to apply the same display content to multiple items in a list

The most common use case is to display a list of friends In this section we’ll use arepeater to display the friends in the Invite tab of our app instead of the previouslydesigned JavaScript function for manually outputting this code

1 Add an os:PeopleRequesttag to the Data Pipeline script (text/os-data) for ourCanvas view.We’ll place it under the key "friends"and get the Viewer’s friendswith it.The following tag states that “I’m going to get a group of friends”—denoted

by the special value "@friends"in the groupIdattribute—”and these friends will

be friends of the Viewer”—denoted by the special value "@viewer"in the userIdattribute:

<os:PeopleRequest key="friends" userId="@viewer" groupId="@friends" />

Putting It Together: OSML Tic-Tac-Toe 237

Trang 15

2 Find the invite_containerdiv.We’re going to modify this div to add a repeattag to iterate over friends Ahead of the last closing div on this element, add thefollowing:

The astute reader will also notice that as we ported over our Tic-Tac-Toe app to useOSML, we were not cleaning out the retired JavaScript.With the exception of com-menting out some clashing client JavaScript calls, the now unused script code is still inplace A partial listing of the retired JavaScript functions includes

n getInitialData

n getDataCallback

n printPersonSince proper refactoring and cleanup of old code can be an arduous process, we willleave the code in place for now.We leave it to the reader to fully identify supersededcode blocks and clean them out of the app

What we’ve seen so far are some of the most common operations in OSML

Remember, OSML is a late addition to the OpenSocial spec and supported starting only

in version 0.9 At the time of this writing, OSML and Data Pipelining are not even fullyreleased and aren’t recognized by previous versions, whereas the OpenSocial JavaScriptAPI has more than a year under its belt and is fairly stable.We encourage you to pushthe limits with OSML, though, and give your feedback both to MySpace and to theOpenSocial community so that we may continue to improve things

NoteCode listings and/or code examples for this chapter can be found on our Google Code page under http://opensocialtictactoe.googlecode.com

238 Chapter 10 OSML, Gadgets, and the Data Pipeline

Trang 16

OSML provides significant features beyond simple markup reuse and tag-based data declaration In this chapter we’re going to explore some of the more advanced features

of OSML.These features include defining custom tags, translating your app to differentcultures and languages, and direct rendering from your external server

In the preceding chapter we covered some different ways of solving the same lems we’ve previously solved, but using OSML In this chapter we’ll do a little more ofthat, plus introduce some new features that open even more doors to our app

prob-Remember, though, OSML is a very late addition to the OpenSocial spec, and it issupported beginning only with version 0.9 of the OpenSocial specification; previousversions do not recognize OSML

Inline Tag TemplatesInline tag templates are reusable components that are declared directly inside the maingadget XML.They look very similar to standard inline templates with one exception:

the presence of a tagattribute in the declaring template scripttag.Templates defined

in this manner are not rendered in place but are instead registered as custom tags for uselater in the app

Trang 17

Defining and Using a Tag Template

Tag templates are an easy and convenient way to create reusable display elements For theTic-Tac-Toe app, we’re going to convert the Player Info box (shown in Figure 11.1) to acustom tag.This element is used for the current Viewer as well as an opponent Our custom tag will display based on the person object passed in as a parameter

Creating the Custom Tag Template DefinitionThe first step is to create our custom tag definition In the following steps we’ll convertthe existing Player Info box into a custom tag template for use in our app.We’llgeneralize it so that it can be used for both the Viewer and the opponent

1 Create a new template script element in the Contentblock of your Canvas code

This element should appear at the top of the block, before any other templatescripts In addition to the normal template script tags, it has an additional attribute

oftag="my:PlayerInfo"

<Content type="html" view="canvas">

<script type="text/os-template" tag="my:PlayerInfo">

</script>

2 Find the Player Info box markup in our existing app gadget It can be found bysearching for the div with an ID of myinfo Copy and paste the contents of themyinfodiv into our new tag:

<script type="text/os-template" tag="my:PlayerInfo">

<div id="myinfo" class="player_info right_column">

<div class="left"><a href="javascript:openProfile();">

<img class="profile_image" src="${viewer.thumbnailUrl}" /></a>

<div class="record" id="myrecord"></div></div>

240 Chapter 11 Advanced OSML: Templates, Internationalization, and View Navigation

Figure 11.1 Player Info box.

Trang 18

Inline Tag Templates 241

3 Now we’re going to clean out the hard-coded data and change the tag template touse parameters Parameters are local values passed in from a tag instance.They areaccessible through the reserved variable ${My} Our tag requires that a personobject be passed into the tag instance in the Playerelement Replace all the

${viewer.X}statements with ${My.Player.X}statements:

<script type="text/os-template" tag="my:PlayerInfo">

<div id="myinfo" class="player_info right_column">

<div class="left"><a href="javascript:openProfile();">

<img class="profile_image" src="${My.Player.thumbnailUrl}" /></a>

<div class="record" id="myrecord"></div></div>

6 Modify the styles to accommodate the blue/pink (male/female) background colors

on this element It would be a little tedious to do an "if"test within this markupfor male/female on the My.Playerobject, so we’ll accommodate this feature byusing style class names instead.The player_infostyle definition will have a bluebackground (default), and an additional player_info_FEMALEstyle will bedefined to override the background to pink:

.player_info {

border:solid 2px black;

padding:5px;

background-color:#09f;

} player_info_FEMALE {

background-color:#fcf;

}

Trang 19

<div style="border:2px solid ${My.borderColor};"

class="player_info right_column player_info_${My.Player.gender.key}">

Using the Custom TagNow that we’ve defined our template, the next step is to use it.We’re going to addinstances of the custom tag for both the current Viewer and for the opponent, if present

1 Search again in the code for the div with an ID of myinfo Delete this entire divand all contained elements

2 Add in place of the myinfodiv an instance of our my:PlayerInfotag with theid="myinfo":

<my:PlayerInfo id="myinfo" >

</my:PlayerInfo>

3 Add in parameter elements for PlayerandborderColor.The Player valueshould be ${viewer}and the borderColorcan be any valid CSS color string orcolor hex.We chose the color green

Using Client-Side Templates

Custom templates are also available for use in client-side code All your custom templatesare available for use on the client side via the new opensocial.template namespace

This allows your app to create and render new template instances on the client.The callsequence looks something like this:

var templateInst = opensocial.template.getTemplate("my:CustomTag");

var tdata = {}

tdata["background"] = "red";

242 Chapter 11 Advanced OSML: Templates, Internationalization, and View Navigation

Trang 20

To avoid client-side template-rendering issues, use only complete DOM element blocks

as a template—for example, div elements, fully enclosed tables, and the like Avoid ing your templates with elements that are typically nested in other elements, such as list items ( LI ) and table rows ( TR ) Tables in particular are problematic because many browsers introduce a multitude of new elements, such as TBODY , THEAD , and TFOOT , without telling you Favor styled div blocks in these instances The same problem also exists with client-side repeaters and tables If you wish to repeat a table row ( TR ) element, you must make use of attribute-based repeaters, not the os:Repeat element in your template.

start-We’re going to use client templates to render the opponent’s display block using ourmy:PlayerInfocustom tag template

Client-Side Rendering with Custom TagsBecause apps are dynamic, the information that is needed doesn’t always exist at serverrender time User interactions affect the app In our case, the opponent is selected afterthe initial app load.To address this, we use the templating JavaScript methods todynamically render our custom tag after the opponent has been selected

In the following steps we will convert the opponentinfodiv element from markupthat required tedious editing in JavaScript code to a second implementation of ourcustommy:PlayerInfotemplate

1 Edit the div element with an ID of opponentinfo and delete all the contents

Also remove the style class attribute so that we are left with an empty div element

<div id="opponentinfo" >

</div>

2 Add an os:PeopleSelectortag element immediately above the opponentinfodiv defined in step 1 It should specify the group as the contents of our friendsdata item and a var= "selectedOpponent"to have the selected friend placed in

Trang 21

the DataContext under that key.We’ll also tie its select behavior into our existingselectOpponentmethod.This replaces the client-side FriendPicker we added inChapter 7, Flushing and Fleshing

<os:PeopleSelector group="${friends}" var="selectedOpponent"

onselect="selectOpponent()" />

</div>

3 Remove the div with an ID of opponentPickerand comment out the call toloadFriendPickersince this is now being handled by the os:PeopleSelector.You may skip this step if you did not implement app data person-to-person play(discussed and outlined in Chapter 7)

4 Define a new function to trigger the client-side rendering of a new templateinstance in the opponentinfo div named updateOpponentTemplate.Thisfunction gets a template instance using the opensocial.template.getTemplatefunction and then calls renderInto to render the template into our

opponentinfodiv.The function looks like this:

//Construct the data to pass into the template var data = {};

244 Chapter 11 Advanced OSML: Templates, Internationalization, and View Navigation

Trang 22

Working with Subviews 245

Working with SubviewsSubviews are a new concept introduced with OSML So, yes, that means they work onlystarting with version 0.9 of the OpenSocial spec If you’re writing or editing an app for alower version, you won’t be able to use subviews

In addition to the main surface views (Home, Profile, and Canvas), subviews allow formultiple views or view parts to be defined on a particular surface.The app can then

“navigate” to these subviews without forcing a page reload

Using subviews is quite simple All you have to do is name the subview in a Contentblock’s viewattribute, then use the following call:

gadgets.views.requestNavigateTo(<target_view_name>);

This call causes the target subview to show, and all other subviews are hidden

Subviews are useful, but they do have some design and behavior characteristics youshould be aware of:

n Subview Contentblocks must consist of coherent, well-formed XHTML

n Adjacent non-subview Contentblocks must also be well formed (this means nopartial nesting of elements)

n By default, activating one subview turns off all other subviews

n On initial load, all subviews are hidden

Converting Tabs to Subviews

We’re going to reimplement our tab interface (shown in Figure 11.2) by making use ofsubviews Changing the interface in this way allows us to make use of the built-in viewnavigation call gadgets.views.requestNavigateToinstead of manually manipulatingCSS classes or styles on the elements It gives us the added benefit of not having to writeloops to manage turning off other elements that should be hidden; it’s all handled by thesubview processing

Figure 11.2 Tab interface in app.

Trang 23

246 Chapter 11 Advanced OSML: Templates, Internationalization, and View Navigation

Editing the Markup to Use Subviews for Tab ContentTabs are currently defined as div blocks.We need to modify the markup so that theheader is a Contentblock, the footer is a Contentblock, and each subview is aContentblock.This allows our app to control the display of the tabs as subviews but stilldisplay the header and footer in a consistent manner

1 Find the location of the first tab content container by searching for the div with

<Content type="html" view="canvas.play">

of the Contentblock element)

5 Edit each tab content element’s CSS class attribute to remove the hideclass:

<div id="invite_container" class="container">

Table 11.1 New Subview Names

Trang 24

1 Edit the TTT.Tabobject to simplify its representation It will now hold the view name instead of a reference to the tab container DOM element.

sub-TTT.Tab = function(tab_dom, view, action){

if(tab){

gadgets.views.requestNavigateTo(tab.view);

} else{

return;

}

}

Working with Subviews 247

Trang 25

The well-formedness constraint can be a problem in some interfaces with tag nesting.

As a result, subviews tend to lend themselves best to absolutely positioned elements (forexample,<div style="position:absolute;">xxx</div>) or root children DOMelements of the view In this way the subviews do not interfere with layout flow whenbeing enabled or disabled

HTML Fragment RenderingOne of the most common paradigms we have found with OpenSocial apps is that ofcontent rewriting Many apps perform an initial load of a Bootstrap page, then call back

to their external servers for the actual app content and perform a wholesale innerHTMLrewrite of the app.While this is very flexible, it is also a very slow user experience As wepreviously mentioned, OSML brings a number of new options to the table for fine-grained content rewriting

In our app we’re going to add a tab to view one of our favorite sites and then render

a banner ad from a pretend ad server URL (actually, a historic Web site)

Adding Content with os:Get

In this section we’ll create a new tab that displays content from an external site.We’ll usetheos:Gettag to pull content directly from the external site and display it inline on asubview

1 Add a new tab to our series of tabs Search for the div with an ID of tab3 Create

a copy of this immediately after as tab4and adjust the text to be “Laugh.” Alsoadjust the CSS class definitions as shown here:

<div id="tab3" class="left tab" onclick="TTT.Tabs.selectTab(3);">

Ngày đăng: 21/01/2014, 12:20

TỪ KHÓA LIÊN QUAN

w