<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='./rfc2629.xslt' ?>
<?rfc toc="yes"?>
<!DOCTYPE rfc PUBLIC "-//IETF//DTD RFC 2629//EN"
"http://xml.resource.org/authoring/rfc2629.dtd">
<rfc ipr="full3978"
     docName="opensocial-markup-language-tags-specification-v0_9">
 <front>
  <title abbrev="OpenSocial Tags">OpenSocial Markup Language Tags Specification
  v0.9</title>
  <author surname="OpenSocial and Gadgets Specification Group"
          fullname='OpenSocial and Gadgets Specification Group &lt;opensocial-and-gadgets-spec@googlegroups.com&gt;'>
   <address>
    <email>opensocial-and-gadgets-spec@googlegroups.com</email>
   </address>
  </author>
  <date month="April"
        year="2009" />
  <area>General</area>
  <keyword>OpenSocial</keyword>
  <keyword>social networking</keyword>
  <keyword>REST</keyword>
  <keyword>XML</keyword>
  <keyword>Extensible Markup Language</keyword>
  <keyword>JSON</keyword>
  <keyword>JavaScript Object Notation</keyword>
  <keyword>Atom</keyword>
 </front>
 <middle>
  <section title="Notation and Conventions">
   <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
   document are to be interpreted as described in 
   <xref target="RFC2119">RFC2119</xref>. Domain name examples use 
   <xref target="RFC2606">RFC2606</xref>.</t>
  </section>
  <section title="Overview">
   <t>OpenSocial Markup Language tags defines a set of tags that every
   OpenSocial compliant container makes available to an OpenSocial
   application.</t>
  </section>
  <section title="Gadget Feature Name">
   <t>To use OSML tags, you need to add the "osml" feature to your gadget spec:
   
   <figure>
    <artwork xml:space="preserve">
&lt;Require feature="osml"&gt;
</artwork>
   </figure>OSML tags are a strict subset of OpenSocial Templating, you can
   also use tags if you use the "opensocial-templates" feature: 
   <figure>
    <artwork xml:space="preserve">
&lt;Require feature="opensocial-templates"&gt;
</artwork>
   </figure>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.</t>
  </section>
  <section title="Tag Invocation">
   <t>An OSML tag is invoked much like an OpenSocial template. It needs to be
   surrounded by a &lt;script&gt; tag with @type="text/os-template": 
   <figure>
    <artwork xml:space="preserve">
Welcome, &lt;script type="text/os-template" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;&lt;os:Name person="${Viewer}"/&gt;&lt;/script&gt;!                                     
</artwork>
   </figure></t>
  </section>
  <section title="Tags">
   <t>An implementing Container MUST support at least the tags listed in this
   section. A Container MAY support additional tags - an effort will be made to
   make such support as consistent as possible across different Containers, and
   tags that are deemed useful may be adopted into this specification in the
   future.</t>
   <section title="&lt;os:Name&gt;">
    <t>Inline tag to show a person's name. If a profile URL is available it
    will be linked to. The tag may display additional container bling (i.e.
    more information on hover), but must do so without breaking up text
    flow.</t>
    <t>Attributes: 
    <list style="symbols">
     <t>@person {Object} The person object. (required)</t>
    </list>
    <figure>
     <preamble>Example</preamble>
     <artwork xml:space="preserve">
&lt;script type="text/os-template" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;Welcome, &lt;os:Name person="${Viewer}"/&gt;&lt;/script&gt;
</artwork>
    </figure></t>
   </section>
   <section title="&lt;os:PeopleSelector&gt;">
    <t>Tag to show a UI that chooses from a list of people, and set a form
    field with the associated value.</t>
    <t>Attributes: 
    <list style="symbols">
     <t>@group {Object} An array of person objects.</t>
     <t>@inputName {string} Name of the form input element that will contain
     selected id(s). Containers can provide a default here. (optional)</t>
     <t>@multiple {boolean} Allow multiple selections? (optional)</t>
     <t>@max {number} Maximum number of people that can be selected.
     (optional)</t>
     <t>@var{string} Name of the top level DataContext variable that is set
     with the selected person object (or array of objects). (optional)</t>
     <t>@onselect {string|function} Client side script function to invoke when
     a selection is made. The function will get the selected person object (or
     array of objects) as a parameter. (optional)</t>
    </list>
    <figure>
     <preamble>Example</preamble>
     <artwork xml:space="preserve">
&lt;form action="/top_friends.php" method="POST"&gt;
  Select your top 8 friends:
  &lt;script type="text/os-template" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;
    &lt;os:PeopleSelector group="${ViewerFriends}" multiple="true" max="8" inputName="top8"/&gt;
  &lt;/script&gt;  
&lt;/form&gt;
</artwork>
    </figure></t>
   </section>
   <section title="&lt;os:Badge&gt;">
    <t>Block level tag to show information about a person in the style of the
    container, usually with an image.</t>
    <t>Attributes: 
    <list style="symbols">
     <t>@person {string|Object} The person object or DataContext key referring
     to a person object. (required)</t>
    </list>
    <figure>
     <preamble>Example</preamble>
     <artwork xml:space="preserve">
My best friend is:&lt;br/&gt;
&lt;script type="text/os-template" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;&lt;os:Badge person="${TopFriend}"/&gt;&lt;/script&gt;
</artwork>
    </figure></t>
   </section>
  </section>
  <section title="Non-Tags">
   <t>There are a number of potential tags that can be better supported using
   templating, for reasons outlined below.</t>
   <t>Note that most of these capabilities will require using the
   "opensocial-templates" feature.</t>
   <section title="Non-Tag: Inserting Text Content">
    <t>For generating text content, expressions are used instead of tags.</t>
    <t>Example: 
    <list style="symbols">
     <t>${Viewer.name} or</t>
     <t>${Owner.jobs[0].Title} instead of</t>
     <t>&lt;os:Name&gt; (note that &lt;os:Name&gt; is for showing a linked
     name, not for inserting text only).</t>
    </list>Reasoning: 
    <list style="symbols">
     <t>Extends to all OpenSocial fields (see 
     <xref target="OS">OpenSocial</xref>, opensocial.Person.Field for a
     list).</t>
     <t>Can be used in attributes, such as &lt;input type="submit" value="Share
     with ${Name}"&gt;.</t>
    </list></t>
    <section title="Non-Tags: Flow Control">
     <t>For conditional content, a conditional statement in OpenSocial
     templating is used along with an expression.</t>
     <t>Example: 
     <list style="symbols">
      <t>&lt;div if="${!viewer.hasApp}"&gt;&lt;a href="..."&gt;Click here to
      install!&lt;/a&gt;&lt;/div&gt; or</t>
      <t>&lt;div if="${jobs[0].Title}"&gt;${name}'s job is
      ${jobs[0].Title}"&lt;/div&gt;</t>
     </list>instead of 
     <list style="symbols">
      <t>&lt;os:HasApp&gt; etc.</t>
     </list>Reasoning: 
     <list style="symbols">
      <t>Extends well to a large number of conditional constructs (no need for
      one tag per condition).</t>
      <t>Equivalently simple to use.</t>
     </list></t>
    </section>
    <section title="Non-Tags: Pronoun">
     <t>For pronouns, conditional HTML blocks based on gender are used.</t>
     <t>Example: 
     <list style="symbols">
      <t>&lt;span if="${person.gender == 'MALE'}"&gt;He said "boo"&lt;/span&gt;
      &lt;span if="${person.gender == 'FEMALE'}"&gt;She said "boo"&lt;/span&gt;
      instead of</t>
      <t>&lt;span&gt;&lt;os:Pronoun&gt; said "boo"&lt;/span&gt;</t>
     </list>Reasoning: 
     <list style="symbols">
      <t>You need full sentences to localize properly.</t>
     </list></t>
    </section>
    <section title="Non-Tags: Get">
     <t>Inlining of remote HTML markup is possible via a combination of Data
     Pipelining's &lt;os:HttpRequest&gt; tag and OpenSocial Templates variable
     inlining via the ${data} syntax. Thus a dedicated &lt;os:Get&gt; tag is
     not needed.</t>
     <t>Example: 
     <list style="symbols">
      <t>&lt;os:HttpRequest key="Data" href="http://example.com/data.html"
      format="text"&gt;</t>
      <t>Then use &lt;os:Html code="${Data}"/&gt; in your template.</t>
     </list>Reasoning: 
     <list style="symbols">
      <t>Re-using existing capabilities avoids doing the same thing in two
      different ways.</t>
     </list></t>
    </section>
   </section>
  </section>
  <section title="Interaction with Proxied Content">
   <t>The combination of tags, templates, and proxied content leads to a number
   of combinations for developer to use.</t>
   <t>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.</t>
   <section title="Flow control and repeated elements">
    <t>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. 
    <figure>
     <preamble>Example Gadget XML</preamble>
     <artwork xml:space="preserve">
&lt;Content href="http://developer.com/canvas" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;
  &lt;os:PeopleRequest userId="@viewer" groupId="@friends" fields="name,birthday" key="ViewerFriends"&gt;
&lt;/Content&gt;
</artwork>
    </figure>
    <figure>
     <preamble>Example PHP</preamble>
     <artwork xml:space="preserve">
&lt;?php
// Some code that pulls POST param into $ViewerFriends here
foreach ($ViewerFriends as $friend) {
  if ($friend['birthday']) {
    echo "&lt;div&gt;".$friend['name']."'s birthday is".$friend['birthday']"&lt;/div&gt;";
  }
}
?&gt;
</artwork>
    </figure></t>
   </section>
   <section title="Tags">
    <t>Tags can be inserted into the output and will be processed by the
    container or JavaScript on the client side. 
    <figure>
     <preamble>Example Gadget XML</preamble>
     <artwork xml:space="preserve">
&lt;Content href="http://developer.com/canvas" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;
  &lt;os:PersonRequest userId="@owner" key="Owner"/&gt;
&lt;/Content&gt;
</artwork>
    </figure>
    <figure>
     <preamble>Example PHP</preamble>
     <artwork xml:space="preserve">
&lt;?php // Let the Container know that the Owner object is needed for post-processing ?&gt;      
&lt;script type="text/os-data" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;
  &lt;os:PersonRequest userId="@owner" key="Owner"/&gt;
&lt;/script&gt;
&lt;?php
// Some code that pulls POST param into $Owner
echo "High score for &lt;script type=\"text/os-template\" xmlns:os=\"http://ns.opensocial.org/2008/markup\"&gt;"
  . "&lt;os:Name person=\"${Owner}\"&gt;&lt;/script&gt; is " . getHighScore($Owner['id']);
?&gt;
</artwork>
    </figure>
    <figure>
     <preamble>PHP Output</preamble>
     <artwork xml:space="preserve">
                                     
&lt;script type="text/os-data" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;
  &lt;os:PersonRequest userId="@owner" key="Owner"/&gt;
&lt;/script&gt;
High score for 
&lt;script type="text/os-template" xmlns:os="http://ns.opensocial.org/2008/markup"&gt;&lt;os:Name person="${Owner}"&gt;&lt;/script&gt;
is 100
</artwork>
    </figure>
    <figure>
     <preamble>Final Container output after OSML is processed</preamble>
     <artwork xml:space="preserve">
High score for John Doe is 100
</artwork>
    </figure></t>
   </section>
  </section>
 </middle>
 <back>
  <references>
   <reference anchor='RFC2119'>
    <front>
     <title>Key words for use in RFCs to Indicate Requirement Levels</title>
     <author initials='S.'
             surname='Bradner'
             fullname='Scott Bradner'>
      <organization abbrev='HarvardU'>Harvard University</organization>
     </author>
     <date month='March'
           year='1997' />
    </front>
    <seriesInfo name='RFC'
                value='2119' />
   </reference>
   <reference anchor='RFC2606'>
    <front>
     <title>Reserved Top Level DNS Names</title>
     <author initials='D.'
             surname='Eastlake'
             fullname='Donald E. Eastlake 3rd'>
      <organization abbrev='IBM'>IBM</organization>
     </author>
     <author initials='A.'
             surname='Panitz'
             fullname='Aliza R. Panitz'></author>
     <date month='June'
           year='1999' />
    </front>
    <seriesInfo name='RFC'
                value='2606' />
   </reference>
   <reference anchor="OS"
              target="./Opensocial-Specification.xml">
    <front>
     <title>OpenSocial Specification v0.9</title>
     <author initials='o.'
             surname='social'
             fullname='OpenSocial and Gadgets Specification Group &lt;opensocial-and-gadgets-spec@googlegroups.com&gt;'>
     </author>
     <date month='January'
           year='2009' />
    </front>
   </reference>
  </references>
 </back>
</rfc>
