user1032531
user1032531

Reputation: 26331

Rendering JavaScript templates

I wish to display a popup when the user hovers over a particular link.

To do so, I first request the particular JSON data from the server via Ajax.

The server queries the DB, and escapes any data which happens to be user provided using htmlspecialchars(), and echos json_encode($data).

The client then assembles the HTML using the below template.

The client then displays the popup.

My question only relates to rendering the template.

Is there a better approach which will provide one or all of the following benefits?

  1. Templates are more readable.
  2. Templates are easier to maintain.
  3. Templates can be extended.
  4. Custom methods to display phone numbers, etc need not be created.
  5. Site is safer from an XSS respective.
  6. htmlspecialchars escaping is moved from the server to the client.
  7. Other benefits which I have not even thought of?

Thank you

function getTemplate(type,json) {
    switch(type) {
        case 'person':
            return '<dl><dt>Name:</dt><dd>'+((d.firstname&&json.lastname)?json.firstname+' '+json.lastname:((json.firstname)?json.firstname:json.lastname))+'</dd>'
            +'<dt>Account:</dt><dd>'+json.account_name+'</dd>'
            +((json.title)?'<dt>Title:</dt><dd>'+json.title+'</dd>':'')
            +'<dt>User Name:</dt><dd>'+json.username+'</dd>'
            +'<dt>Password:</dt><dd>'+json.password+'</dd>'
            +'<dt>Communication Method:</dt><dd>'+json.communication_method+'</dd>'
            +((json.email)?'<dt>Email:</dt><dd>'+json.email+'</dd>':'')
            +((json.account_phone)?'<dt>Account Phone:</dt><dd>'+ayb.display_phone(json.account_phone)+'</dd>':'')
            +((json.phone)?'<dt>Direct Phone:</dt><dd>'+ayb.display_phone(json.phone)+'</dd>':'')
            +((json.mobile_phone)?'<dt>Mobile Phone:</dt><dd>'+ayb.display_phone(json.mobile_phone)+'</dd>':'')
            +((json.account_fax)?'<dt>Account Fax:</dt><dd>'+ayb.display_phone(json.account_fax)+'</dd>':'')
            +((json.fax)?'<dt>Direct Fax:</dt><dd>'+ayb.display_phone(json.fax)+'</dd>':'')
            +((json.address || json.location)?'<dt>Address:</dt><dd>'+json.address+((json.address && json.location)?'<br>':'')+json.location+'</dd>':'')
            +'</dl>';
            break;
        case 'company':
            return 'bla bla bla';
            break;
        case 'somethingElse':
            return 'bla bla bla';
            break;
            return '<h1>Invalid Template</h1>';
    }
}

Upvotes: 0

Views: 88

Answers (1)

Ammaroff
Ammaroff

Reputation: 954

Here is one using mustache.js :

http://plnkr.co/m0NyrpTcKhIicTt0FD4N

html:

<dl><dt>Name:</dt><dd>{{firstname}} {{lastname}} </dd>
<dt>Account:</dt><dd>{{account_name}}</dd>
{{#title}}
    <dt>Title:</dt><dd>{{title}}</dd>
{{/title}}
<dt>User Name:</dt><dd>{{username}}</dd>
<dt>Password:</dt><dd>{{password}}</dd>
<dt>Communication Method:</dt><dd>{{communication_method}}</dd>
{{#email}}
    <dt>Email:</dt><dd>{{email}}</dd>
{{/email}}
{{#account_phone}}
    <dt>Account Phone:</dt><dd>{{#display_phone}}{{account_phone}}{{/display_phone}}</dd>
{{/account_phone}}
</script>

<script type="text/html" id="company">
bla bla
</script>
<script type="text/html" id="somethingElse">
somethingElse bla bla
</script>

json :

  var json = {
        "firstname": "Basha",
        "lastname": "tasha",
        "account_name":"presonal",
        "title":"MR",
        "username":"basha",
        "password":"******",
        "communication_method":"phone<b>xss safe</b>",
        "account_phone": "1231231234"
    };

js:

$(document).ready(function () {
var output = $("#output");
type = "person";
var template = $("#"+type).html();

if(template == undefined) template = "<h1>Invalid Template</h1>";

//you can inject client side callback for phone render before calling Mustache.render(template,json)

  json.display_phone= function () {
   return function (val, render) {
       var phone = render(val);
            return phone.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');

        }
    };
    var html = Mustache.render(template, json);

    output.append(html);

 });

It's XSS safe

Kindly note that custom method is sent in the json data "display_phone"

Upvotes: 1

Related Questions