OSML Tags
From OpenSocial
Contents |
WARNING
This documentation is out of date with the official 0.9 Opensocial Templates spec. Please see:
Summary
This is a proposal for an initial set of OSML tags. These tags came out of discussions on the OpenSocial template discussion list, see earlier work at http://wiki.opensocial-templates.org/index.php?title=OpenSocial_Markup#Template_Tags.
Tags are proposed for generating user interface elements: <os:PersonSelector>, <os:UserBadge>, <os:Tabs>, and <os:Name> (a linked name). General templating mechanisms are proposed for other use cases that could be handled with tags, including inserting text content and supporting flow control, for reasons covered in the Non-Tags section below.
The proposal is contained in section #2 "Proposal: Initial Tag Set". The rest of the document is context and reasoning behind which tags were proposed.
Spec Updated
- http://sites.google.com/site/opensocialdraft/Home
- http://sites.google.com/site/opensocialdraft/Home/osml-tags
Proposal
<Require feature="..."/>
To use OSML tags, you need to add the "osml" feature to your gadget spec:
<Require feature="osml">OSML tags are a strict subset of OpenSocial Templating, you can also use tags if you use the "opensocial-templates" feature:
<Require feature="opensocial-templates">The reason for separate require features is that templates may not be supported on all views for all containers, due to processing and/or latency costs. OSML tags must be supported in all views.
Initial Tag Set
<os:Name>
Inline tag to show a person's name, linked if the a profile URL an may have additional container bling (i.e. more information on hover)
Attributes:
@person {string|Object} The person object or DataContext key referring to a person object. (required)Examples:
Welcome, <os:Name person="${Viewer}"/><os:PeopleSelector>
Tag to show a UI that chooses from a list of people, and set a form field with the associated value.
Attributes:
@group {string|Object} An array of person objects or DataContext key referring to an array of person objects.
@inputName {string} Name of the form input element that will contain selected id(s). Containers can provide a default here. (optional)
@multiple {boolean} Allow multiple selections? (optional)
@max {number} Maximum number of people that can be selected. (optional)
@var{string} Name of the top level data context variable that is set with the selected id(s). (optional)
@onselect {string|function} Client side script function to invoke when a person is selected. (optional)Examples:
<form action="/top_friends.php" method="POST"> Select your top 8 friends: <os:PeopleSelector group="${ViewerFriends}" multiple="true" max="8" inputName="top8"/> </form>
<os:Badge>
Block level tag to show information about a person in the style of the container, usually with an image.
Attributes:
@person {string|Object} The person object or DataContext key referring to
a person object. (required)Examples:
My top friends:<br/> <os:Badge repeat="${TopFriends}" person="${Cur}"/>
<os:Get>
Tag that loads HTML content from a URL and inserts into the DOM of the page.
- Content is sanitized before insertion
- No authorization credentials are sent with the request; request must be for public data
- Containers will cache the request based on HTTP headers
- Cached data will be invalidated by the Invalidation APIs (if they are agreed to)
- Content must be directly inlinable into the DOM. External CSS or <script> file references are ignored
Attributes:
@href {string} The URL from which to retrieve HTML content (required)Examples:
${Viewer.Name}'s pet information
<os:Get href="http://developer.superpetstore.com/petHtml?petId=${viewer.appData.petId}"/>Next Round of Tags
Here's a list of tags that didn't make the initial cut, but could be added if people felt they were especially useful.
<os:TabSet>
Constructs a tab layout used to organized pages of information.
This tag didn't make it into the first pass of tags because the embedded HTML content in Tabs makes it more difficult to process in proxied content. However a complete proposal is here that can be used for building a prototype.
Elements:
<os:Tab> Any number of tabs. (optional)os:Tab Attributes/Elements:
@name {string} Name used to identify the tab. (required)
@selected {boolean} Is this tag initially selected? (optional)
<title> The contents of the tab title. (required)
<body> The contents of the tab itself. (required)Examples:
<os:TabSet name="sampleTabSet"> <os:Tab name="basicTab" selected="true"> <title>Basic Info</title> <body> Name: ${Viewer.Name}<br/> Gender: ${Viewer.gender.displayValue} </body> </os:Tab> <os:Tab name="interestsTab"> <title>Interests</title> <body> Books: ${Viewer.details.books}<br/> Music: ${Viewer.details.music}<br/> </body> </os:Tab> </os:Tabset>
<os:Link> / <os:A>
Create a navigation link, similar to <a href="#" onclick="gadgets.views.requestNavigateTo(...); return false">link</a>
<os:Share>
Standard UI element to show a share/link button
<os:List>
Show a list in the style of the container, similar to using "* Text" in media wiki
<os:Layout>
Complex layout control
<os:Zippy>
Text that can be hidden or shown using a disclosure triangle
Non-Tags
There are a number of potential tags that can be better supported using templating, for reasons outlined below.
If people feel strongly any of these tags are significantly more convenient than the alternate proposed syntax, we should consider adding them in - there is no harm in these tags except for having two ways of accomplishing the same thing.
Non-tag: Inserting Text Content
For generating text content, expressions are used instead of tags.
Example:
-
${Viewer.name}or -
${Owner.jobs[0].Title}instead of -
<os:Name>(note that<os:Name>is for showing a linked name, not for inserting text only).
Reasoning:
- Extends to all OpenSocial fields (see http://code.google.com/apis/opensocial/docs/0.8/reference/#opensocial.Person.Field for a list)
- Can be used in attributes, such as <input type="submit" value="Share with ${Name}">
Non-tag: Flow Control
For conditional content, a conditional statement in OpenSocial templating is used along with an expression.
Example:
-
<div if="${!viewer.hasApp}"><a href="...">Click here to install!</a></div>or -
<div if="${jobs[0].Title}">${name}'s job is ${jobs[0].Title}"</div>
instead of
-
<os:HasApp>etc.
Reasoning:
- Extends well to a large number of conditional constructs (no need for one tag per condition)
- Equivalently simple to use
Non-tag: Pronoun
For pronouns, conditional HTML blocks based on gender are used.
Example:
-
<span if="${person.gender == 'MALE'}">He said "boo"</span> <span if="${person.gender == 'FEMALE'}">She said "boo"</span>instead of -
<span><os:Pronoun> said "boo"</span>
Reasoning:
- You need full sentences to localize properly.
Interaction with Proxied Content
The combination of tags, templates, and proxied content leads to a number of combinations for developer to use.
Here are a few common use cases and how developers might handle them. This is for informational purposes only - it doesn't extend the proposal, but hopefully clarifies a few use cases.
Flow control and repeated elements
OpenSocial data will be posted on the developer server and flow control will be handled on the developers own server, in PHP, JSP, ASP, or the language of the developer's choice.
Example Gadget XML:
<Content href="http://developer.com/canvas"> <os:PeopleRequest userId="@viewer" groupId="@friends" fields="name,birthday" key="ViewerFriends"> </Content>
Example PHP (excuse my bad syntax):
<?php // Some code that pulls POST param into $ViewerFriends here foreach ($ViewerFriends as $friend) { if ($friend.birthday) { echo "<div>".$friend['name']."'s birthday is".$friend['birthday']"</div>"; } } ?>
Tags
Tags can be inserted into the output and will be processed by the container or JavaScript on the client side.
Example Gadget XML:
<Content href="http://developer.com/canvas"> <os:PersonRequest userId="@owner" key="Owner"/> </Content>
Example PHP:
<?php // Some code that pulls POST param into $Owner echo "High score for <os:Name person=\"${Owner}\"> is ".getHighScore($Owner.id); ?> or <?php echo "High score for <script type=\"text/os-template\"><os:Name person=\"${Owner}\"></script> is ".getHighScore($Owner.id); ?>
(Note: Separate discussion going on about whether we need the <script> tag)
Change Log
11/17/08 - Updated with feedback from OpenSocial 0.9 summit:
- Added separate <Require> feature for "osml"
- Added <os:Get> tag to render inline HTML
- Moved <os:TabSet> to Next Round of Tags, as it wasn't clear that containers were ready to support the processing required for HTML content embedded inside of OSML tags
