Simple and robust browser side template processing for Ajax based web applications

Steffen Meschkat, Google

WWW 2008, April 21-25, Beijing, China

Why another template processing idiom?

Template processing is the staple pattern for separation of data and presentation in web applications.
Works on one page at a time — inadequate for incremental, asynchronous page updates typical of Ajax applications. Therefore:
Fix other undesirable properties of standard template processing:
And, of course:

Template processing input

template
<div id="t">
  <div jsselect="items" jscontent="$this"></div>
</div>
data
var input = {
  items: ['A', 'B', 'C']
};
API
var output = jstGetTemplate('t');
jstProcess(new JsExprContext(input), output);

Template processing output

output
<div>
  <div jsinstance="0"
       jsselect="items" jscontent="$this">A</div>
  <div jsinstance="1"
       jsselect="items" jscontent="$this">B</div>
  <div jsinstance="*2"
       jsselect="items" jscontent="$this">C</div>
</div>

Differential processing

data
var input = {
  items: ['A', 'BC']
};
output
<div>
  <div jsinstance="0"
       jsselect="items" jscontent="$this">A</div>
  <div jsinstance="*1"
       jsselect="items" jscontent="$this">BC</div>
</div>

Differential processing, again

data
var input = {
  items: []
};
output
<div>
  <div jsinstance="*0" jsselect="items"
       style="display: none" jscontent="$this">A</div>
</div>

Template composition

template
<div id="zebralist">
  <div jsselect="items">
    <div jsdisplay="$index % 2 == 0"
         style="background-color:#f0fff0"
         jscontent="$this"></div>
    <div jsdisplay="$index % 2 != 0"
         style="background-color:#ffffff"
         jscontent="$this"></div>
  </div>
</div>
template
<div id="t1">
  <div transclude="zebralist"></div>
</div>
process reprocess

Attributes summary

Target summary

Selecting which values to set in current context:

Expression summary

API summary

Inspiration & alternatives

Content

ctemplate
<b>{{ATTACHMENT_NAME_ESCAPED}}</b> -
{{ATTACHMENT_SIZE_ESCAPED}}
{{ATTACHMENT_NAME_ESCAPED}} - {{ATTACHMENT_SIZE_ESCAPED}}
clearsilver
<b><?cs var:html_escape(attachment.name)?></b> -
<?cs var:html_escape(attachment.size)?>
-
jstemplate
<b jscontent="attachment.name">attachment.html</b> -
<span jscontent="attachment.size">100k</span>
attachment.html - 100k

Iteration

ctemplate
<ul>
  {{#ITEM_SECTION}}<li>{{ITEM}}</li>{{/ITEM_SECTION}}
<ul>
clearsilver
<ul>
  <?cs each:item = items?><li><?cs var:item?></li><?cs /each?>
</ul>
jstemplate
<ul>
  <li jsselect="items" jscontent="$this"></li>
</ul>

Attribute values

ctemplate
<a href="{{URL}}">here</a>
clearsilver
<a href="<?cs var:url ?>">here</a>
jstemplate
<a href="#example" jsvalues="href:url">here</a>
XSLT
<a>
  <xsl:text>here</xsl:text>
  <xsl:attribute name="href">
    <xsl:value-of select="@url"/>
  </xsl:attribute>
</a>
XSLT
<a href="{@url}">here</a>

Leverage

Reuses existing concepts and their implementations:
Just adds concepts, doesn't replace:

Invariants and Guarantees

Robustness:
Security:
Simplicity:

Conclusion

Yes. It works in practice.
Yes. It works in theory.
Specifically, reuse and leverage: