Whether or not you realize it, everyone who uses a repeat control in XPages development is actually using a server-side template. Let me demonstrate the concept….
We create an object through many different interactions with the XPages back end APIs and Server-Side JavaScript interactions. The object can be many different constructs. The XPages repeat control then iterates through each member within the object and repeats the same thing over and over based on the repeat control’s starting value object.
In the following example we create a repeat control from a JavaScript array control. It iterates over each object within the array allowing the repeat control to work as a template for creating HTML.
<xp:repeat id="repeat1" rows="30" var="myObj">
<xp:this.value><![CDATA[#{javascript:
var myArray=[
{
"@entryid":"1-431C28F894B0548185257C22000A8403",
"firstname":"Agnes C.",
"lastname":"Smith",
"address":"24256 Leisure Lane"
},
{
"@entryid":"2-4ED02366A420D23985257C4F000B0BD7",
"firstname":"Albert",
"lastname":"Scoggins",
"address":"3525 Koontz Lane, second"
},
{
"@entryid":"3-6D8120FA75B4BCCF85257C4F000B0B5D",
"firstname":"Alejandra",
"lastname":"Dodge",
"address":"3044 Simpson Avenue"
}
]
return myArray}]]>
</xp:this.value>
<p> Hello my is
<strong>
<xp:text escape="true"
id="f1" tagName="h4" disableTheme="true"
value="#{javascript:myObj.firstname +' '+ myObj.lastname}">
</xp:text>
</strong>
</p>
<br />
<p>
I live at
<xp:text escape="true"
id="f2" tagName="h4" disableTheme="true"
value="#{javascript:myObj.address}">
</xp:text>
</p>
<hr />
</xp:repeat>
The output from this repeat control is shown below

HTML Templating
Using the mustache.js library we are able to display a JavaScript object using an HTML repeat control in a directly analogous way to the XPages server-side method described above. The following code does pretty much the same as the server side example above.
What is interesting to note is the use of the SCRIPT tag in the following code. By giving it a type of “text/template” the browser does not execute the contents of the SCRIPT tag. But it also ignores the HTML within. We can access the contents of the script as it is a DOM object. This makes for the perfect storage container – we do not have to hide the template HTML with CSS.
The HTML
<!-- mustache uses AMD and as such will not work in R9 unles you add it this way *stupid dojo 1.8 issue*-->
<xp:this.resources>
<xp:headTag tagName="script">
<xp:this.attributes>
<xp:parameter name="type" value="text/javascript" />
<xp:parameter name="src" value="js/mustache.js" />
</xp:this.attributes>
</xp:headTag>
</xp:this.resources>
<script type="text/template" class="template">
{{#items}}
<br /><p> Hello my is
<strong>
{{firstname}} {{lastname}}
</strong>
</p>
<p>
I live at
{{address}}
</p>
<hr />
{{/items}}
</script>
<div class="templateHere"></div>
The JavaScript
$('document').ready(function(){
var myArray={
items:[
{
"@entryid":"1-431C28F894B0548185257C22000A8403",
"firstname":"Agnes C.",
"lastname":"Smith",
"address":"24256 Leisure Lane"
},
{
"@entryid":"2-4ED02366A420D23985257C4F000B0BD7",
"firstname":"Albert",
"lastname":"Scoggins",
"address":"3525 Koontz Lane, second"
},
{
"@entryid":"3-6D8120FA75B4BCCF85257C4F000B0B5D",
"firstname":"Alejandra",
"lastname":"Dodge",
"address":"3044 Simpson Avenue"
}]
}
var e, newStuff, template;
try {
template = $('.template').html(); //Get the HTML from within the SCRIPT tag with the template class
newStuff = Mustache.to_html(template, myArray) //Apply the myArray object to the template HTML
} catch (_error) {
e = _error;
newStuff = e.toString();
}
$('.templateHere').html(newStuff)
})
Here is the web page created

Below you can see a direct comparison between the repeat control code and the HTML template code

Implementing a REST service
The example above uses a typed JavaScript object to create the data for the template – and you have probably realized the example I used is the same format as a XPages REST service <xe:viewItemFileService> feed. So with a little bit of AJAX to put in the data object we are able to create the same output using REST data rather than typed object.
$('document').ready(function(){
var e, newStuff, json, template;
$.ajax({
url: 'xRestService.xsp/byFirstName'
}).done(function(data){
try {
template = $('.template').html();
newStuff = Mustache.to_html(template, data)
} catch (_error) {
e = _error;
newStuff = e.toString();
}
$('.templateHere').html(newStuff)
})
})
Except in this case we loaded *all* the names in the REST service into the page using the template – in 15 lines of code

Conclusion
While there may not, on the surface, seem to be much point in using HTML templating when we have server-side repeat control templating, if you want to take your web applications running on XPages into the future, this is the beginning…………More to come on this topic 🙂