<?xml version="1.0" encoding="utf-8"?>
<html>
<div style="float:right; margin: 0 0 10px 10px;">Version|opensocial-0.9
</div>
OpenSocial Templates gives you an easy, fast, and secure way to build
gadgets without using JavaScript to generate HTML. Use it to declaratively
create templates for your gadgets by making minor modifications to
standard HTML markup without using string concatenation and DOM
manipulation. Because the library is part of OpenSocial, you can use it
to bind to both the OpenSocial APIs and to custom variables that you define.
Here is an example of a simple gadget that uses server-side OpenSocial Templates to display the text "Hello world!" in the gadget UI:
<source lang="xml">
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Hello World"> <script type="text/os-template"> |
</Module>
</source>
To use server-side OpenSocial Templates in your gadget, include the following tag in your
ModulePrefs |
:
<source lang="xml">
<Require feature="opensocial-templates">
</Require>
</source>
The canonical template format is well-formed XML that contains HTML and OpenSocial Template markup. To define a template inside of your gadget file, use
<script> |
tags of
type="text/os-template" |
, following this syntax:
<source lang="xml">
<script type="text/os-template">
</script>
</source>
Template markup can contain both HTML and custom tags.
OpenSocial Templates become a lot more useful when you can bind data to them. The OpenSocial Data Pipelining spec describes a declarative syntax for defining data to process in your gadget. You can access data from an external server or an OpenSocial container.
To work with data in your template, first add
<Require feature="opensocial-data" /> |
to your gadget's
ModulePrefs |
. Then refer to the Data Pipelining spec and the examples below for the types of data that you can access.
One tag you can use from the Data Pipelining spec is
<os:PeopleRequest> |
, which returns profile information for a group or list of people. For example, if you want to access the current viewer's friend list, use the following code:
<source lang="xml">
<script xmlns:os="http://ns.opensocial.org/2008/markup" type="text/os-data">
<os:PeopleRequest key="friends" userId="@viewer" groupId="@friends"/> |
</script>
</source>
Note that this example uses
<os:PeopleRequest> |
with the following attributes:
key="friends" |
userId="@viewer" |
groupId="@friends" |
You can find a complete list of fields to use with
<os:PeopleRequest> |
in the Data Pipelining spec.
After you fetch the data, you can render it using the following OpenSocial Template:
<source lang="xml">
<script type="text/os-template"> |
</script>
</source>
Note that the template uses standard HTML list tags to format the friends list and sets the
id |
attribute of each
span |
node. It also uses the special
repeat |
attribute to iterate over the friends object, the special variable
Cur |
to reference the current item, and the
$\{\} |
notation to de-reference data objects. You can find more detail about repeaters, special variables, and expressions in subsequent sections of this Developer Guide.
Here is the complete gadget that fetches the OpenSocial data and then renders it:
<source lang="xml">
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Server-side Template"> |
<script type="text/os-template"> |
</Module>
</source>
See the Data Pipelining spec for more information about requesting other types of OpenSocial data, including viewer or owner profiles, activities, and container-specific endpoints.
In addition to fetching OpenSocial data to render into templates, you can also request JSON or text data from a URL using
<os:HttpRequest> |
. Suppose you have the following
friends |
JSON data object stored at
<nowiki>http://myfriendsserver.com</nowiki> |
:
<source lang="javascript">
{
"friends" : [ |
}
</source>
You can fetch this data like this:
<source lang="xml">
<script xmlns:os="http://ns.opensocial.org/2008/markup" type="text/os-data">
<os:HttpRequest key="request" href="http://myfriendsserver.com"/> |
</script>
</source>
Note that this example uses the
<os:HttpRequest> |
tag with the following attributes:
key="request" |
href="http://myfriendsserver.com" |
You can find the complete list of fields to use with the
<os:HttpRequest> |
tag in the Data Pipelining spec.
After you fetch the data, you bind it to the template by setting the
require |
attribute of the template's
script |
tag to the data's
key |
. Here is an example of a simple template that displays each friend's name and interests:
<source lang="xml">
<script type="text/os-template" require="request"> |
</script>
</source>
Here is the complete gadget that fetches the JSON data and then renders it:
<source lang="xml">
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Server-side Template"> |
<script type="text/os-template" require="request"> |
</Module>
</source>
Use template expressions to access your data. Embed expressions into the template XML using the syntax
$\{Expr\} |
. Here is an example of template content that uses an expression to evaluate and display a viewer's name:
<source lang="xml">
<div>Hello ${Viewer.displayName}</div>
</source>
The syntax of template expressions is defined from a subset of the JSP Expression Language specification. You can use raw variable references in your expressions, as in the example above, or create more complex expressions that use operators, as in this example:
<source lang="xml">
<div>Next step is ${Step + 1}</div>
</source>
JSP Expression Language allows you to use most standard operators (e.g. comparison, arithmetic, etc.) in expressions, although OpenSocial Templates provides a few XML-escaped operators for use in XML. For example, you should use
$\{a lt b\} |
instead of
$\{a < b\} |
,
$\{a gt b\} |
instead of
$\{a > b\} |
, and
$\{a and b\} |
instead of
$\{a && b\} |
. See the full list of XML-escaped conditional operators in Conditional Operators.
Most expressions are evaluated as strings. The only exception is if the expression is enclosed in an attribute without additional text content, in which case OpenSocial Templates processes and evaluates the object that is referenced in the expression. In the following example, the Viewer object is passed in to the
os:Name |
template.
<source lang="xml">
<os:Name person="${Viewer}"/>
</source>
By default OpenSocial Templates escapes all strings before inserting them into the HTML document. However, OpenSocial Templates may alternatively URL-encode or JavaScript-escape strings, depending on the context.
Below is a list of XML-escaped expressions and the conditional operators that they map to. You should use the XML-escaped versions of these operators to evaluate
if |
expressions:
<table>
<tr>
<th>Conditional operator</th>
<th>XML-escaped expression</th>
</tr>
<tr>
<td>
< |
</td>
<td>
lt |
</td>
</tr>
<tr>
<td>
> |
</td>
<td>
gt |
</td>
</tr>
<tr>
<td>
<= |
</td>
<td>
lte |
</td>
</tr>
<tr>
<td>
>= |
</td>
<td>
gte |
</td>
</tr>
<tr>
<td>
&& |
</td>
<td>
and |
</td>
</tr>
<tr>
<td>
== |
</td>
<td>
eq |
</td>
</tr>
<tr>
<td>
!= |
</td>
<td>
neq |
</td>
</tr>
<tr>
<td>
|| |
</td>
<td>
or |
</td>
</tr>
<tr>
<td>
! |
</td>
<td>
not |
</td>
</tr>
</table>
Templates have two types of variables: a set of global objects that are referenced by special variables and a set that includes all other declared JavaScript variables, including JSON data that's passed in to a template for processing and rendering.
Variables are accessed using the syntax
Object.Property |
. For example, the notation
Foo.Bar |
maps to getting the property
Bar |
on the JSON object
Foo |
. You can use this notation for arbitrarily deep nested properties, for example
Foo.Bar.Baz |
maps to the property
Baz |
on the JSON object
Foo.Bar |
.
If Top and Viewer are JSON objects, then
evaluates to
. |
OpenSocial Templates reserves a small set of special variables for template processing:
Cur |
,
Context |
,
Top |
, and
My |
. It also reserves the special tag
<os:Html> |
. See below for details of how to use each variable and tag.
Use
Cur |
to refer to the item that is currently being processed within a repeater. The example below repeats over a user's friends list and prints out each user's name:
<source lang="xml">
<div repeat="${Top.ViewerFriends}">
<div><strong>${Cur.Name}</strong></div> |
</div>
</source>
See more information about repeaters in Repeated Elements.
OpenSocial Templates uses the
Context |
variable as a holding area for additional variables that you might need when processing templates. You can use the following properties of
Context |
:
$\{Context.UniqueId\} |
$\{Context.Index\} |
$\{Context.Count\} |
Here is an example of using the
Context |
variable to keep track of items that are used in a repeater element:
<source lang="xml">
<div repeat="${Top.ViewerFriends}">
Showing friend ${Context.Index} of ${Context.Count}: |
</div>
</source>
The variable
Top |
refers to all of the data that's available by key.
Use
My |
to reference data that is passed into a template via the tag that calls the template. If you use the expression
$\{My.foo\} |
, OpenSocial Templates first looks for an attribute named
foo |
in the tag that called the template. If it does not find the attribute, it then looks for an element named
foo |
.
Use
Msg |
to access localized messages in templates and evaluate expressions within the message body.
For example, suppose you had a message bundle that included the following localized message:
<source lang="xml">
<messagebundle>
<msg name="PLAY_SONG">Click here to play Love song #15</msg> |
</messagebundle>
</source>
In your template, you can use this markup to directly access and evaluate the localized message:
<source lang="xml">
<a href="${song.url}">${Msg.PLAY_SONG}</a>
</source>
You can even also use the
$\{\} |
expression syntax to include an expression in the message bundle. For example:
<source lang="xml">
<messagebundle>
<msg name="PLAY_SONG">Click here to play ${song.title}</msg> |
</messagebundle>
</source>
In this example, the expression
$\{song.title\} |
in the message body is evaluated at the time of template rendering. Note that you cannot use repeaters and conditionals in messages and variable markup is evaluated in the context in which the message is placed.
See Localizing OpenSocial applications for specific instructions on setting up your gadget for localization.
<os:Html> |
Use the
<os:Html> |
tag to include dynamic content that you want to be treated as HTML (and not escaped) in your template.
For example, if you had an expression
$\{Cur.someText\} |
whose value was "<b>Bold</b>",
Then if you evaluated the expression:
<source lang="xml">
${Cur.someText} |
</source>
The result would be: <b>Bold</b>
However, if you pass the expression to the
os:Html |
tag using the
code |
attribute, like this:
<source lang="xml">
<os:Html code="${Cur.someText}"/>
</source>
Then the result would be: Bold (the word "Bold" in bolded font).
Note: Be careful when using this tag! You must properly sanitize the HTML content that you pass in, or else you can introduce XSS attacks.
<os:If> |
Use the
<os:If> |
tag to conditionally display content based on the evaluation of an expression. Use this syntax for
<os:If> |
:
<source lang="xml">
<os:If condition="${Expr}">
</os:If>
</source>
For example, the content between the
div |
tag below is rendered only if the expression
$\{Top.YourScore == Top.HighScore\} |
evaluates to
true |
:
<source lang="xml">
<os:If condition="${Top.YourScore h1. Top.HighScore}">
<div>You have the high score of ${Top.YourScore}!</div> |
</os:If>
</source>
<os:Repeat> |
Use
<os:Repeat> |
to render a tag multiple times based on the evaluation of an expression. Use this syntax for the
<os:Repeat> |
tag
<source lang="xml">
<os:Repeat expression="${Expr}">
</os:Repeat>
</source>
For example, you can use the template below to display a list of friends' names:
<source lang="xml">
<os:Repeat expression="${Top.ViewerFriends}">
<div> |
</os:Repeat>
</source>
You can also use the
var |
attribute to set a variable name of your choice for the repeater, for example:
<source lang="xml">
<os:Repeat expression="${Top.ViewerFriends}" var="Friend">
<div> |
</os:Repeat>
</source>
In addition to using built-in OpenSocial Templates tags, you can also define custom tags to use in your gadget. You can create custom tags inline in your gadget, or refer to tags that are defined in an external template library.
You must register all of your custom tags in a unique namespace. You cannot use the default (HTML) namespace.
Typically the best way to uniquely create a namespace is to use the URL of your domain. However, full URLs tend to be long and unwieldly to insert into tag names, so you can create a prefix instead. For example, if you want to register the namespace
example.com/myapp |
, you can choose the prefix
myapp |
and all of your custom tags will take the form
<myApp:TagName> |
.
You can create a custom tag out of any inline template by adding the
tag |
attribute to the
<script> |
tag and using
xmlns |
to declare your namespace.
Use this syntax to create a custom inline tag:
<source lang="xml">
<script type="text/os-template" xmlns:yourNamespace="yourURL" tag="yourNamespace:tagName">
</script>
</source>
Note: You must declare your namespace in the
script |
block for each custom inline tag you create.
Here is an example of creating a custom Hello World tag:
<source lang="xml">
<script type="text/os-template" xmlns:myapp="http://example.com/myapp" tag="myapp:HelloWorld">
<div style="font-size: 40px">Hello World</div> |
</script>
</source>
Here is an example of using the tag that you just created:
<source lang="xml">
<script type="text/os-template">
<myapp:HelloWorld/> |
</script>
</source>
You can pass parameters into custom tags as XML attributes or elements, and access the parameters using the special variable
$\{My\} |
.
Here is an example of passing in a color parameter to the custom Hello World template:
<source lang="xml">
<script type="text/os-template" xmlns:myapp="http://example.com/myapp" tag="myapp:HelloWorld">
<div style="color: ${My.MessageStyle.color}">Your message is: ${My.message}</div> |
</script>
<script type="text/os-template">
<myapp:HelloWorld message="Hello World"> |
</script>
</source>
It is good practice to gather your template definitions into a single custom library, rather than defining them in all in the same file as your gadget.
Create your custom template library in a well-formed, valid XML file and fill in template definitions according to this structure:
<source lang="xml">
<Templates xmlns:foo="http://foo.com/">
<Namespace prefix="foo" url="http://foo.com/"/> |
<Style>
.warning { color: red; } |
<JavaScript>
function usedByAllTemplates() { ... }; |
<Template tag="foo:bar"> </Template> |
<TemplateDef tag="foo:baz"> function usedByFooBaz() { ... }; |
</Templates>
</source>
<blockquote>Note: Use
<Template> |
and
<TemplateDef> |
tags to define templates in a library rather than
<script> |
tags of
type="text/os-template" |
.</blockquote>
<p>Refer to the table below for a list of tags to use when defining your template library: <table border="1">
</td>
for <strong>each</strong> namespace. For example, if you use any tags in the OpenSocial namespace via the OpenSocial Templates library, you must include
.
</td>
.
</td>
tags). </td>
</td>
tags).</td>
</td>
</td>
,
, and
tags.</td> |
For example:
<source lang="xml">
<?xml version="1.0" encoding="UTF-8"?>
<Templates xmlns:os="http://opensocial.org/templates">
<Namespace prefix="os" url="http://opensocial.org/templates"> |
</Templates>
</source>
To load this template library into your gadget, add the
<Param name="requireLibrary"> |
tag to the
<Require feature="opensocial-templates"> |
tag in your gadget. The content of the
<Param> |
tag must be a valid Template library XML file. If you use a relative URL path, it is interpreted in relation to the location of the Gadget Spec XML file.
For example:
<source lang="xml">
<Require feature="opensocial-templates">
<Param name="requireLibrary">http://www.example.com/templates.xml</Param> |
</Require>
</source>
Use multiple
<Param> |
tags to load multiple libraries. For example:
<source lang="xml">
<Require feature="opensocial-templates">
<Param name="requireLibrary">http://www.example.com/templates.xml</Param> |
</Require>
</source> Attributes h1. h2.
if |
Set the
if |
attribute of an element to an expression and OpenSocial Templates only displays the element if the expression evaluates to true. For example, the text between the
<div> |
tags below is only displayed if
Top.YourScore == Top.HighScore |
:
<source lang="xml">
<div if="${Top.YourScore Top.HighScore}">
You have the high score of ${Top.YourScore}! |
</div>
</source>
You can set the
if |
attribute for any element within a template, as in the examples below:
<source lang="xml">
<os:ShowPerson person="${Top.Owner}" if="${Top.HasOwner}"/>
<div repeat="${Top.ViewerFriends}" if="${Cur.profileUrl}">
Link to: <a href="${Cur.profileUrl}">${Name}</a> |
</div>
</source>
repeat |
You can set the
repeat |
attribute of a tag to an expression and OpenSocial Templates renders the tag against each of the results. Use the special variable
Cur |
to reference the current item being evaluated in the repeated list.
The following example iterates over all items of the array
Top.ViewerFriends |
and displays each friend object's name:
<source lang="xml">
<div repeat="${Top.ViewerFriends}">
Your friend's name is ${Cur.Name} |
</div>
</source>
You can also use nested repeats with the
Cur |
keyword when iterating over multi-dimensional arrays of data. For example:
<source lang="xml">
<!--
table: [
]
-->
<script type="text/os-template">
<div repeat="${table}"> |
</div>
</div> |
</script>
</source>
index |
var |
As a convenience, you can rename the
Cur |
variable and specify an index variable by adding
var |
and
index |
attributes, respectively:
<source lang="xml">
<div repeat="${Top.ViewerFriends}" var="${Friend}">
Your friend's name is ${Friend.Name} |
</div>
<div repeat="${rows}" index="x">
<div repeat="${cols}" index="y"> |
</div>
</source>
context |
You can explicitly set the scope of data to evaluate using the
context |
attribute. For example, to repeat over
Interests |
of the first object in the data
Friends |
, you can use this expression:
<source lang="xml">
<div context="${Friends0}">
<div repeat="${Interests}"> |
</div>
</source>
require |
Use the
require |
attribute to specify all data that's required for rendering your inline template. The value of
require |
should be a comma-separated list of top-level variable names for the required data. If you list more than one variable, the template only renders when all of the variables are set.
For example, the message below is only rendered when both
$Viewer |
and
$Owner |
are set (i.e. non-null):
<source lang="xml">
<script type="text/os-template" require="Viewer, Owner">
Hello, <os:Name person="${Viewer}"/>, welcome to <os:Name person="${Owner}"/>'s application |
</script>
</source>
autoUpdate |
Set the
autoUpdate |
attribute to
true |
in your template definition if you want the template to be re-rendered automatically when any of its required data changes.
For example, the content of the template below is automatically re-rendered whenever the
Friend |
data is modified via the function
opensocial.data.DataContext.putDataSet("Friend", friend) |
:
<source lang="xml">
<script type="text/os-template" require="Friend" autoUpdate="true">
You have selected, <os:Name person="${Friend}"/>. |
</script>
<script type="text/javascript">
function setFriend(friend) { |
</script>
</source>
</html>