| OpenSocial | OpenSocial and Gadgets Specification Group |
| <opensocial-templating-specification-v0_9> | April 15, 2009 |
OpenSocial Templating Specification v0.9
opensocial-templating-specification-v0_9
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 RFC2119 [RFC2119]. Domain name examples use RFC2606 [RFC2606].
OpenSocial Template (OST) provides a declarative way for gadget developers to create templates by copying and pasting HTML, then making minor modifications to that HTML. Because OST is part of OpenSocial, it also provides a means to bind to the OpenSocial APIs and custom, developer defined variables. OST accomplishes this through tag libraries and special markup.
An OST implementation can fetch, inject, cache, and store data requests for the application before any client side code executes. OST does not represent a full replacement for JavaScript. OST assumes that applications can fallback to JavaScript whenever a combination of application and container cannot make use of a given OST feature.
OST creates a new feature name for use in the Gadgets Specification: opensocial-templates. When a Module requires OST, the Module must contain this XML:
<ModulePrefs> <Require feature="opensocial-templates"/> </ModulePrefs>
A common usage of the feature would be with other OpenSocial features.
Example
<ModulePrefs title="Hello World"> <Require feature="opensocial-0.9"/> <!-- Allows templates --> <Require feature="opensocial-templates"/> <!-- Allows multiple views to be defined and thus rendered client or server --> <Require feature="views"/> </ModulePrefs>
The canonical template format is a well-formed XML document. This document can include HTML tags which will be output directly when rendering the template, and custom tags which will be evaluated when rendering the template.
Example
<Template> <div style="font-size: 20px">Hello world!</div> </Template>
A common use case will be embedding this XML into an HTML document. The following snippet can be embedded directly into a gadget <Content> section or HTML document:
<script type="text/os-template">
<div style="font-size: 20px">Hello ${Viewer.name.formatted}!</div>
</script>
Templates can also define template markup libraries, which will map to XML namespaces.
Blocks of markup using OSML appear embedded in other markup within script tags. The type of an OSML script is set to "text/os-template". The only attribute that an OpenSocial OSML processor MUST understand is @tag. The OSML processor MUST ignore any attributes it does not recognize. The OpenSocial specification reserves the following attribute names for future usage:
Containers MAY choose to experiment with these attributes to define a consistent meaning and behavior for the attributes in a future release of OpenSocial.
Expressions can be embedded into the template XML using the syntax ${Expr}.
Example template content with an expression
<div>Hello ${Viewer.Name}</div>
Expressions are honored inside text nodes and attribute values. They will be ignored inside tag and attribute names.
Expressions are defined using a subset of the JSP Expression Language [JSPEL], with a couple of minor modifications. We use a subset of the JSP Expression Language specification. This allows for expressions that are raw variable references, as in the example above, or expressions with operators:
<div>Next step is ${Step + 1}</div>
JSP Expression Language allows you to use most standard operators (comparison, arithmetic, etc.), although some operators have an alternate name for use in XML. ${a < b} becomes ${a lt b}, ${a > b} becomes ${a gt b}, ${a && b} becomes ${a and b}, etc.
Expressions are usually evaluated as strings. The only exception is when expressions are in attributes without additional text content, and in this case, the value of the expression is the object referenced, and this object is passed to the template for processing. In the following example, the viewer is passed in to the os:Name template.
<os:Name person="${Viewer}"/>
Strings are escaped before inserting into the HTML document. By default strings are HTML escaped, however based on context they may be URL encoded or escaped as JavaScript strings or CSS content.
HTML specified some element attributes whose mere presence affects browser behavior. For example, the @selected attribute of the <option> tag. An exception is made for this small subset of attributes: if their value contains an expression which evaluates to a "false-like" value (that is any of, null/undefined, the boolean false, the number 0, empty string, or the literal string "false"), the attribute will be removed during template processing.
This allows markup like the following to work as expected and cause the Viewer option to become selected:
<select>
<option repeat="${friends}" selected="${Cur.id == Viewer.id}" >${Cur.name.formatted}</option>
</select>
Some examples of tag-attribute combinations to which special processing will apply:
Variables are accessed using Foo.Bar (or Foo.Bar.Baz) notation. .Bar maps to getting the property Bar on the JSON object. If Top and Viewer are JSON objects, then
${Top.Viewer.Name}
evaluates to
data['Viewer']['Name']
Properties of DOM Nodes have special evaluation rules. For a given Node object, ${Node.Param} will attempt to evaluate as follows:
Evaluation of Nodes or lists of Nodes as strings results in the merged text content of these nodes. So <Color>Red</Color> would become the string "Red". This is mostly applicable to results of ${My} evaluation (see below).
Data is used with all calls to render templates. When rendering templates through Javascript, - i.e.: opensocial.template.getTemplate('foo').renderInto(div, data) - data can be passed in explicitly. When no data is supplied, such as when templates are automatically rendered, the default application Data Context, which can be populated declaratively via Data Pipelining, will be used. The data passed in must be a JSON object. The templates will have two 'types' of variables. One set is a set of global objects with reserved names. The other set includes everything else or all other declared JavaScript variables.
Template processing reserves a small set of variables.
${Top} refers to the data context passed into the template rendering - i.e.: for automatic rendering, ${Top} == Data Context; for programmatic rendering via template.renderInto(div, data) -> ${Top} == data.
${Context} is a holding area for additional variables generated while processing templates. ${Context} will include the following set of properties:
${Cur} refers to the current data item being processed, either within a repeater, or specified via the @cur attribute (see below). At the top of the template rendering stack ${Cur} == ${Top}. When a custom tag is invoked, ${Cur} will start out as null.
${My} refers to data that is passed into a template via Custom Tag XML. ${My} is only available within templates invoked as Custom Tags.
The ${My} variable evaluates to the XML template node that was used to invoke the current Custom Tag, with all expressions, conditional elements and repeated elements already processed.
Properties of ${My} are evaluated as with any other DOM node (see above), with one exception: any attribute expressions that would normally evaluate to Objects are not converted to string by default. So, for <foo:Bar person="${Viewer}"/>, ${My.Viewer} will resolve to an Object whose properties can be further accessed: ${My.Viewer.name.formatted}.
Example of a template that uses ${My}
<script type="text/os-template" xmlns:myapp="http://example.com" tag="myapp:EmployeeCard">
<div class="card" style="background: ${My.color};"<
<img src="${My.employee.photo}"/> ${My.employee.name}
</div>
</script>
<script type="text/os-template" xmlns:myapp="http://example.com">
<myapp:EmployeeCard color="red" employee="${Viewer}"/>
</script>
Special variable names are optional for all but ${Context}. Expressions will be evaluated against each of the other special variable contexts. The first matching variable will be the result of expression evaluation. The order of precedence is ${Cur}, ${My} and then ${Top}. For example, ${Top.Name} == ${Name} unless there exists ${Cur.Name} or ${My.Name}. The following examples show why this is helpful:
Example with special variables in place
<div repeat="${Top.ViewerFriends}">
<div>${Cur.Name}"</div>
<div repeat="${Cur.Phone}">${Cur.Number} of type ${Cur.Type}</div>
</div>
Equivalent script using precedence rules
<div repeat="${ViewerFriends}">
<div>${Name}"</div>
<div repeat="${Phone}">${Number} of type ${Type}</div>
</div>
"Top" refers to the data context passed in via Javascript, so ${Top} will return the data passed in during template rendering.
Variables are accessed using Foo.Bar (or Foo.Bar.Baz) notation. .Bar maps to getting the property Bar on the JSON object. If Top and Viewer are JSON objects, then
${Top.Viewer.Name}
evaluates to
data['Viewer']['Name']
Templates can be rendered automatically, or via a Javascript API available under the opensocial.template namespace (see below). An implementing container may disable the Javascript API for some or all application Views. In this case templates will only be renderable automatically when the application loads.
Templates embedded into the application markup via <script> elements will be processed automatically when the application loads. By default, templates will be rendered into the application content in the place where they appear in the markup.
Example of an automatically rendered template
<h1>
<script type="text/os-template">
Hello, <os:Name person="${Viewer}"/>
</script>
</h1>
Result of rendering such markup
<h1> Hello, <span class="name">John Doe</span> </h1>
Automatic rendering is done against the application Data Context which can be populated declaratively via Data Pipelining, or programmatically via opensocial.data.DataContext.putDataSet().
Automatic rendering can be prevented by setting the "disableAutoProcessing" parameter of the opensocial-templates feature in the gadget spec
<Require feature="opensocial-templates"> <Param name="disableAutoProcessing">true</Param> </Require>
Data required for rendering of inline templates can be specified using the @require attribute. The attribute value must be a comma-separated list of top-level variable names required to render this template. If the application Data Context does not have all of these variables set, automatic rendering of the template will be deferred until the time they become available.
This template will only render when both ${Viewer} and ${Owner} are set
<script type="text/os-template" require="Viewer, Owner">
Hello, <os:Name person="${Viewer}"/>, welcome to <os:Name person="${Owner}"/>'s application
</script>
It is possible to request that the template be re-rendered when any of its required data changes. This is done by setting @autoUpdate attribute to "true". When this is set, the template will re-render any time any of its required data is modified via opensocial.data.DataContext.putDataSet(key, data).
Example of using @autoUpdate
<script type="text/os-template" require="Friend" autoUpdate="true">
You have selected, <os:Name person="${Friend}"/>.
</script>
<script type="text/javascript">
function setFriend(friend) {
opensocial.data.DataContext.putDataSet("Friend", friend);
}
</script>
During rendering templates can call other templates via Custom Tags. You can add a @tag attribute to any template (both on the <Template> element or on the <script> tag for embedded templates). This allows the template to be called by using an XML element of the same name.
The value of the @tag attribute must be a namespaced string. Creating custom tags in the default (HTML) namespace is not allowed.
Templates defined via inline <script> elements that also specify a @tag attribute do not get rendered in place automatically.
Example of defining a custom tag and then calling it
<script type="text/os-template" xmlns:myapp="http://example.com/myapp" tag="myapp:HelloWorld"> <div style="font-size: 40px">Hello World</div> </script> <script type="text/os-template"> <myapp:HelloWorld/> </script>
Parameters can be passed into templates as XML attributes or elements. These parameters are accessed using the special variable ${My}:
<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">
<MessageStyle color="blue"/>
</myapp:HelloWorld>
</script>
The scope of data to evaluate (${Cur}) can be explicitly set with the @cur attribute. For example, to repeat over Interests of the first object in Friends, you can use this expression:
<div cur="${Friends[0]}">
<div repeat="${Interests}">
${Title}
</div>
</div>
Content can be displayed conditionally based on evaluation of an expression. Elements with an @if attribute will only be displayed if the @if attribute evaluates to true. For example, the following will only be displayed if Top.YourScore == Top.HighScore:
<div if="${Top.YourScore == Top.HighScore}">You have the high score of ${Top.YourScore}!</div>
The contents of an <os:If> element are only displayed if the @condition attribute evaluates to true.
The example above rewritten using the <os:If> element
<os:If condition="${Top.YourScore == Top.HighScore}">
<div>You have the high score of ${Top.YourScore}!</div>
</os:If>
Note: The @if attribute, and the @condition attribute of <os:If/> will be evaluated as a boolean. This means null or empty string values will evaluate to "false". A Node, NodeList or non-empty string will evaluate to "true".
The use of @if and @repeat attributes on <os:If/> is not supported.
The @if attribute can be used on any element within a template other than <os:If/> and <os:Repeat/>. Some examples are as follows:
<!-- Custom tags -->
<os:Name person="${Top.Owner}" if="${Top.HasOwner}"/>
<!-- Tag contents -->
<os:Button>
<title>Click me!</title>
<help if="${Top.Viewer.NeedsHelp}">You need help.</help>
</os:Button>
Tags can be rendered multiple times based on evaluation of an expression.
Tags with a @repeat attribute are displayed once for each item in evaluating the expression in the repeat attribute. The current item in the repeated list will be put into the ${Cur} variable.
The value of the @repeat attribute will be evaluated as a list. If the result is a scalar value, (including mixed content which evaluates to a string) it will be treated as a list of one element.
Example
<div repeat="${Top.ViewerFriends}">
Your friend's name is ${Cur.Name}
</div>
The contents of an <os:Repeat> element is displayed once for each item in evaluating the expression in the @expression attribute. The current item in the repeated list will be put into the ${Cur} variable, and a @var attribute can also be used to rename the iteration variable.
<os:Repeat expression="${Top.ViewerFriends}">
<div>
Your friend's name is ${Cur.Name}
</div>
</os:Repeat>
and
<os:Repeat expression="${Top.ViewerFriends}" var="Friend">
<div>
Your friend's name is ${Friend.Name}
</div>
</os:Repeat>
The use of @if and @repeat attributes on <os:Repeat/> is not supported.
Repeating over an expression that evaluates to a NodeList or a single Node (such as the result of ${My.tag}) will result in one iteration rendering for each Node found. In this case, the ${Cur} variable will be set to the current node for each successive iteration.
Repeaters are evaluated before conditionals on the same element. This allows a conditional to apply to each iteration of a repeater. The following template, for example, would list all the viewer's friends with a profile URL:
Repeated elements evaluated on each iteration.
<div repeat="${Top.ViewerFriends}" if="${Cur.ProfileUrl}">
Link to: <a href="${Cur.ProfileUrl}">${Cur.Name}</a>
</div>
This is equivalent to
<os:Repeat expression="${Top.ViewerFriends}">
<os:If condition="${Cur.ProfileUrl}">
<div>Link to: <a href="${Cur.ProfileUrl}">${Cur.Name}</a></div>
</os:If>
</os:Repeat>
The ${Context} special variables can be used during repeater processing to access repeater state. Its properties are ${Context.Count} which holds the total number of elements in the repeater list, and ${Context.Index} which is the number of the current iteration, a value from 0 to ${Context.Count} - 1.
Example
<div repeat="${Top.ViewerFriends}">
Showing friend ${Context.Index + 1} of ${Context.Count}:
Your friend's name is ${Cur.Name}
</div>
To support nested repeaters, custom names can be specified for the current item variable and the current context variable via the @var and @context attributes respectively. The values are then made available as variables specified, as well as with their default names. (So when @var="Foo" is used, each item is made available in ${Cur} and in ${Foo}.)
Example
<!-- Renaming variable ${Cur} -->
<ul repeat="${Top.ViewerFriends}" var="Friend">
<li repeat="${Friend.Books}">
<!-- Here ${Cur} refers to the current Book -->
${Friend.Name} likes to read ${Cur}
</li>
</ul>
<!-- Specifying an Context variable -->
<div repeat="rows" context="Outer">
<div repeat="cols" context="Inner">
<myapp:DrawPoint row="${Outer.Index}" col="${Inner.Index}"/>
</div>
</div>
As stated above, all expression evaluation results will be treated as a String, and escaped in a context-appropriate manner. However, there are cases where HTML markup from trusted sources needs to be injected into the template from the DataContext. For such use cases, the built-in <os:Html> tag may be used.
The <os:Html> tag will evaluate its @code attribute as a string, and render the resulting code as HTML.
Example of using <os:Html>:
<div repeat="${BlogEntries}">
<h2>${Cur.Title}</h2>
<p><os:Html code="${Cur.Summary}"/></p>
<a href="${Cur.Url}">Read more...</a>
</div>
Containers may chose to define what subset of HTML will be honored by the <os:Html> tag, and what will be sanitized away. Containers should allow minimal functionality such as making text bold or changing its color, as well as creating links and inserting images.
A template may also define locations to render custom blocks of content. This is done using the <os:Render> tag and the content block is always identified by the @content attribute. The @content attribute names an immediate child node of the template instance or current repeater item if it is a DOM element. The contents of the designated node will be rendered in place of the <os:Render> tag. If multiple child elements match, the container MUST merge the results of all matches into one, concatenated element. If 2 or more <os:Render> elements have the same value for @content, then the resulting evaluation appears once per <os:Render> element. A container MUST ignore any XML elements or other content within the <os:Render> tag. The container MAY emit a diagnostic error to gadgets.log indicating the content being ignored. The container MUST ignore any namespace prefixes on the value of the @content attribute. @content="foo" will match "foo" elements in the same namespace as the template.
For example, consider the following template:
<script type="text/os-template" tag="myapp:BoxWithTitle"
xmlns:myapp="http://example.com/myapp" xmlns:os="http://opensocial.org/templates" >
<div class="box-title"><os:Render content="title"/></div>
<div class="box-content"><os:Render content="body"/></div>
</script>
The preceding example declares two os:Render elements: title and body. When evaluating a usage of this template, the container will look for two elements at the following paths, ignoring any XML namespace on the elements ( XPath) :
Because of the existing processing rules, the contents of the elements will have already been processed by the container. The results of that evaluation are copied into the template in place of the <os:Render> element. Returning to the previous example, a developer may write:
<script type="text/os-template"
xmlns:myapp="http://example.com/myapp" xmlns:os="http://opensocial.org/templates" >
<myapp:BoxWithTitle>
<myapp:title>This is the title</myapp:title>
<myapp:body>
<div style="font-size:40px">Boo!</div>
<div>from <os:Name person="${Top.Viewer}"/></div>
<myapp:body>
</myapp:BoxWithTitle>
</script>
When evaluating the above content, a container follows these steps:
Example: Resulting HTML DOM
<div class="box-title">This is the title</div> <div class="box-content"> <div style="font-size:40px">Boo!</div> <div>from <a href="http://www.example.com/profile/1234">Scott</a></div> </div>
The nature of this feature allows for templates to nest within os:Render tags. Given the evaluation rules, the myapp:BoxWithTitle example could also be used as this:
Template
<script type="text/os-template" tag="myapp:BoxWithTitle"
xmlns:myapp="http://example.com/myapp" xmlns:os="http://opensocial.org/templates">
<div class="box-title"><os:Render content="title"/></div>
<div class="box-content"><os:Render content="body"/></div>
<div>Hi {$My.parameter}<div>
</script>
Gadget Markup
<script type="text/os-template"
xmlns:myapp="http://example.com/myapp" xmlns:os="http://opensocial.org/templates">
<myapp:BoxWithTitle parameter="scott">
<myapp:title>This is the title</myapp:title>
<myapp:body>
<myapp:BoxWithTitle parameter="chris">
<myapp:title>Inner Title</myapp:title>
<myapp:body>This is goofy</myapp:body>
</myapp:BoxWithTitle>
</myapp:body>
</myapp:BoxWithTitle>
</script>
Rendered version
<div class="box-title">This is the title</div>
<div class="box-content">
<div class="box-title">Inner Title</div>
<div class="box-content">This is goofy
<div>Hi chris</div>
</div>
<div>Hi scott</div>
</div>
While inline templates can be useful for visualizing data, eventually you may want to create standalone, reusable templates. A template library can define one or more template custom tags, but all of them must be in a single namespace. Template libraries are packaged into a sandalone XML file of the following format:
<Templates xmlns:foo="http://foo.com/">
<Namespace prefix="foo" url="http://foo.com/"/>
<Style>
<!-- Set global CSS for your library here -->
.warning { color: red; }
</Style>
<JavaScript>
<!-- Define global functions for your library here -->
function usedByAllTemplates() { ... };
</JavaScript>
<!-- Simple declarative tag foo:bar -->
<Template tag="foo:bar">
<!-- Define markup for foo:bar here -->
</Template>
<!-- Complex tag foo:baz with local CSS and JavaScript -->
<TemplateDef tag="foo:baz">
<Template> <!-- Define markup for foo:baz here --> </Template>
<Style> <!-- Set CSS for foo:baz here --> </Style>
<JavaScript>
<!-- Define functions for the foo:baz template here -->
function usedByFooBaz() { ... };
</JavaScript>
</TemplateDef>
</Templates>
For example
<?xml version="1.0" encoding="UTF-8"?>
<Templates xmlns:os="http://opensocial.org/templates">
<Namespace prefix="os" url="http://opensocial.org/templates">
<Style>
large-font: {
font-size: 20px;
}
</Style>
<Template tag="os:HelloWorld">
<div style="large-font">Hello World!</div>
</Template>
<TemplateDef tag="os:ShowPerson">
<Style>
profile-image: {
padding-right: 5px;
width: 32px;
height: 32px;
}
</Style>
<Template>
<img if="${My.person.ThumbnailUrl}" src="${My.person.ThumbnailUrl}"
class="profile-image"/>
<a href="${My.person.ProfileUrl}" target="_top">${My.person.Name}</a>
</Template>
</TemplateDef>
</Templates>
Syntax:
Containers should load the <os:*> template tags by default, and it is not required that they be defined as a standalone XML file. Other tag libraries can be loaded by default in a container - for example, Example.com might have a set of <example:*> tags available.
If an application requires a template library to work, it can request the library be loaded before any template processing takes place. This can be done via a <Param name="requireLibrary"> tag placed inside the <Require feature="opensocial-templates"> tag:
<Require feature="opensocial-templates"> <Param name="requireLibrary">http://www.example.com/templates.xml</Param> </Require>
The Param content must be a URL pointing to a valid Template library XML file. Relative URLs are interpreted in relation to the location of the Gadget Spec XML file.
Multiple libraries may be requested by repeated occurrences of the requireLibrary Param:
<Require feature="opensocial-templates"> <Param name="requireLibrary">http://www.example.com/templates.xml</Param> <Param name="requireLibrary">http://www.example.com/moretemplates.xml</Param> </Require>
The container will trim all whitespace around each URL. For URLs that legitimately contain whitespace, it must be properly encoded.
NOTE: Implementing containers may disallow loading third party template libraries on some or all gadget Views. Additionally, containers may disallow template libraries to inject Javascript code on some or all of the Views.
Templates will have the ability to substitute localized text content on a per-language basis.
Gadgets already have a facility for defining localized messages. In the gadget prefs, you can specify the URL for localized message bundles on a per-language basis:
<ModulePrefs title="ListenToThis"> <Locale messages="http://www.listentostuff.com/messages.xml"/> <Locale lang="de" messages="http://www.listentostuff.com/messages-DE.xml"/> </ModulePrefs>
Each bundle is a list of <msg> elements with localized content inside:
For example
<messagebundle>
<msg name="PLAY_SONG">Click here to play ${song.title}</msg>
</messagebundle>
Also note that in OpenSocial API 0.9, you will be able to inline <msg> elements into the gadget directly without creating separate files for each locale.
Localized messages will be accessible via the ${Msg} variable:
For example
<a href="${song.url}">${Msg.PLAY_SONG}</a>
Any ${} markup in the message body will be honored - in the above example, the ${song.title} reference in the message will be evaluated at the time of template rendering. Repeaters and conditionals in messages will not be processed. Variable markup will be evaluated in the context in which the message is placed. (Note how the message in the example references the ${song} variable available at the point of message inclusion.)
It's important to realize that this sets ${Msg} apart from other variable inclusion markup - variable references will NOT be processed in any other output.
If a particular message is undefined for a locale and missing from the default bundle (prefs.getMsg(key) returns null in these cases), an error message should be rendered in its place for easy debugging.
Template-related Javascript API may be exposed by implementing containers for some or all views. Such API will allow developers to render templates programmatically.
Template-related functionality will be exposed via the opensocial.template namespace object.
<static> Type: {opensocial.template.Template} opensocial.template.getTemplate(tag)
Description: Returns the Template object (see below) registered with "tag", or null if it doesn't exist.
Parameters:
| Name | Type | Description |
|---|---|---|
| tag | String | The tag used to identify the template. |
Returns:
| Type | Description |
|---|---|
| opensocial.template.Template | The Template object registered with the specified tag, or null if no such template exists |
<static> Type: {void} opensocial.template.process()
Description: (Re)processes the application templates, rendering ones that are ready.
<static> Type: {void} opensocial.template.disableAutoProcessing()
Description: Prevent automatic template processing. Equivalent to setting the "disableAutoProcessing" Param. If processing has already happened, this will throw an exception. After automatic processing is disabled, the templates can be processed by calling opensocial.template.process() manually.
The result of calling opensocial.template.getTemplate(name) is a Template object that can be rendered programmatically.
Type: {Element} opensocial.template.Template.render(data)
Description: Renders the template with supplied JSON data, and returns the DOM Node containing the result.
Parameters:
| Name | Type | Description |
|---|---|---|
| data | Object | The JSON data to use for rendering. This becomes ${Top} in variable evaluation. If this is omitted, opensocial.data.DataContext will be used by default |
Returns:
| Type | Description |
|---|---|
| Element | The Element containing DOM created by rendering the template. |
Type: {void} opensocial.template.Template.renderInto(element, data)
Description: Renders the template with supplied JSON data and inserts the result into the specified DOM element, replacing any previous content
Parameters:
| Name | Type | Description |
|---|---|---|
| element | Element | The DOM element to host the render result. Any current content in this element will be cleared by this method |
| data | Object | The JSON data to use for rendering. This becomes ${Top} in variable evaluation. If this is omitted, opensocial.data.DataContext will be used by default |
Example of using Javascript API
<script type="text/os-template" tag="myapp:songs" xmlns:myapp="http://example.com/myapp">
<h1>Songs in ${playlist}</h1>
<ul>
<li repeat="${songs}" var="song">
${Context.Index + 1}: ${song.Title} by ${song.Artist} (${song.SongLength})
</li>
</ul>
</script>
<script type="text/javascript">
function showSongs(playlistName, songArray) {
var template = opensocial.template.getTemplate("myapp:songs");
var data = {
playlist: playlistName,
songs: songArray
}
var outputDiv = document.getElementById("songDiv");
template.renderInto(outputDiv, data);
}
. . .
showSongs("My Playlist", [
{ Title: "Yesterday", Artist: "Beatles", SongLength: "2:35" },
{ Title: "Thriller", Artist: "Michael Jackson", SongLength: "37:21" }
]);
</script>
| [RFC2119] | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels" , RFC 2119, March 1997. |
| [RFC2606] | Eastlake, D. and A. Panitz, "Reserved Top Level DNS Names" , RFC 2606, June 1999. |
| [JSPEL] | Chung, K., DeLisle, P., and M. Roth, "Java Server Pages Expression Language" , May 2006, <https://jsp.dev.java.net/spec/jsp-2_1-fr-spec-el.pdf>. |