Throughout this chapter, we have explored how to work with templates that automatically render during gadget processing. Autorendering is an excellent method for building an extensible structure for your gadget when it first loads, but it does not cover the extent of functionality that you may require when working with templates.
The templating JavaScript API seeks to address this shortcoming, allowing developers to programmatically render a template into the HTML document of a gadget through the JavaScript layer, as needed. This functionality allows the developer to enjoy the rich functionality and feature set of OpenSocial templates while still maintaining a great amount of freedom in her development practices.
Before we dive into the individual methods of the JavaScript API, note that each example assumes you have the following template defined:
<script type="text/os-template" tag="gadget:restaurants" xmlns:gadget="http://www.mysite.com/gadget"> <h1>Local Restaurants</h1> <ul> <li repeat="${restaurants}"> <b>Name</b>: ${Cur.place}<br /> <b>Address</b>: ${Cur.address}<br /> <b>Website</b>: <a href="${Cur.href}"> ${Cur.href} </a> </li> </ul> </script>
As well as the following data source for the template:
var restaurants = [ { place: "Lovely Sweets & Snacks", address: "9 32 E El Camino Real, Sunnyvale CA", href: "http://local.yahoo.com/info-21337048-lovely- sweets-snacks-sunnyvale" }, { place: "Vitos Famous Pizza", address: "1155 Reed Ave, Sunnyvale CA" href: "http://local.yahoo.com/info-21332026-vitos- famous-pizza-sunnyvale" }, ] );
The opensocial.template
namespace object exposes a number of methods for obtaining and
processing templates defined in the gadget.
To work in a defined template or to apply a data source to the template, you must first obtain the template object. You do so by making a request to the following method:
opensocial.template.getTemplate(tag)
The getTemplate(...)
method
accepts one attribute to be passed, tag
, which is a string containing the
template tag name with qualifying XML namespace:
//obtain the defined gadget:restaurants template var template = opensocial.template.getTemplate("gadget:restaurants");
This method will return the template object registered with
tag
, or null
if the template does not
exist.
The opensocial.template.process()
method is
used to initially process or reprocess currently used
templates in a gadget. This method will initiate processing for
templates that are ready:
opensocial.template.process()
There is no return value for this method.
Should you wish to control when template processing occurs
(instead of allowing the gadget rendering to control it for you),
you can disable template autoprocessing
within the gadget. This is the same as setting the disable
AutoProcessing
attribute within a
template:
opensocial.template.disableAutoProcessing()
Once autoprocessing is disabled, you will need to manually
initiate template processing by calling the opensocial.template.process()
method:
//call process() method to begin template processing function processTemplates(){ opensocial.template.process(); } //disable auto-processing of templates opensocial.template.disableAutoProcessing(); //when required, call processTemplates() function to process templates processTemplates();
This method will throw an exception if the processing has already occurred.
There is no return value for this method.
Once you’ve obtained a template through the opensocial.template.getTemplate(...)
method,
you can control where in the gadget’s DOM structure the processed
template’s markup will render. Two methods are available to specify
this, as described next.
The opensocial.template.Template.render(...)
method renders an associated
template with the data source provided within the gadget markup at
the location where the method was called:
opensocial.template.Template.render(data)
If you do not include the data source, opensocial.data.DataContext
is used by
default:
//obtain the defined gadget:restaurants template var template = opensocial.template.getTemplate("gadget:restaurants"); //render the template with our JSON object var domNode = template.render(restaurants);
The return value of the render(...)
method contains the DOM
element into which the template markup was inserted.
Much like with the render()
method, opensocial.template.Template.renderInto(...)
is responsible for rendering template data into a
gadget’s HTML. The difference between the two functions is that
renderInto(...)
allows the
developer to set a location where the template markup will be
inserted, via a DOM node reference:
opensocial.template.Template.renderInto(element, data)
Using this method, you gain a great deal of control over where the markup generated from a template will go:
//obtain the defined gadget:restaurants template var template = opensocial.template.getTemplate("gadget:restaurants"); //capture the DOM node that will house the template markup var insertNode = document.getElementById("restaurantNode"); //render the template with our JSON object var domNode = template.renderInto(insertNode, restaurants);
The return value of the renderInto(...)
method contains the DOM
element into which the template markup was inserted.
Now that we understand how templates work with the JavaScript API, let’s explore how we can implement the API’s features in our own projects to control the template rendering functionality programmatically as needed, instead of autorendering on gadget load.
In our example, we have a series of world headlines that are to be built on the fly. We want to have a standard template UI to visualize the headline data. We’ll apply that template to the visual markup and then insert it within the gadget when ready.
Our first task in this process is to define the OpenSocial template custom tag that will be used to visualize the headlines data set:
<script type="text/os-template" tag="app:headlines" xmlns:app="http://www.mysite.com/app"> <h1>Current News Headlines</h1> <ul> <li repeat="${headlines}"> <b>Headline Rank</b>: ${Context.Index + 1}<br /> <a href="${Cur.href}"> ${Cur.title} </a> </li> </ul> </script>
As with our other custom tag template examples, we first start
with the os-template script
block.
Within the script
element, we
define the tag, app:headlines
, that
we’ll use to denote this template block. We then define the XML
namespace that we will use throughout the template process: app
.
Within the markup, we include a header, followed by an unordered
list to house all of the headlines. The <li>
element is set to repeat for each
headline. Within the <li>
, we
display the headline rank based on the order processed in the array,
and we show a linked headline title.
Now that our template is in place, we need to set up the JavaScript functionality that will take our raw data source, apply the template, and insert the template back into the gadget markup:
<script type="text/javascript"> //captures the headline template, applies data and inserts into DOM node function displayHeadlines(headlineObj, insertNode) { var template = opensocial.template.getTemplate("app:headlines"); var JSONObj = { headlines: headlineObj } var insertObj = document.getElementById(insertNode); template.renderInto(insertObj, JSONObj); }
The JavaScript functionality consists of a single function,
displayHeadlines(...)
. This
function requires two attributes to be passed:
headlineObj
The JSON object containing an array of headline objects
insertNode
A string representing the ID of the DOM node in which our newly built headline markup will be inserted
Our first task in the JavaScript layer is to capture the raw
template that we defined earlier into a variable using the opensocial.template.getTemplate(...)
method.
The attribute that we pass to this method is the tag
name for the template.
We then wrap the JSON in another object, associating the raw
headlines data source with its data set name, headlines
.
Once that data and the template information are stored in
variables, we then capture the DOM node into which we’ll insert the
content by using the ID passed in to the function; then, we render the
template into that node using the renderInto(...)
method.
Once the template rendering function is in place, we can begin
building both the gadget markup that will house the template and the
raw headlines
data source:
<div id="currentHeadlines"></div> //build headline JSON object var headlineObj = [ { title: "31 of 33 Chile miners released from hospital", href: "http://www.cnn.com/2010/WORLD/americas/10/15/ chile.miners.rescue/index.html" }, { title: "Yemen posts reward for al Qaeda suspects", href: "http://www.cnn.com /2010/WORLD/meast/10/15/ yemen.al.qaeda.reward/index.html" }, { title: "Rights group questions fairness of Cuban spy trial in U.S.", href: "http://www.cnn.com /2010/CRIME/10/15/ cuba.imprisoned.agents/index.html" }, ] ); //call function to render headlines into template displayHeadlines(headlineObj, "currentHeadlines"); </script>
We start our markup layer by defining a DOM node that will house the final template. Following that, we define the JSON object that will list off the headlines to be displayed. Our headline objects consist of a title and a link for each result.
Last, we call the rendering function, displayHeadlines(...)
, passing in the
headlines JSON object and the ID of the div
in which to insert the headline
content.
3.145.101.109