0

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>';
    }
}
6
  • 1
    why dont u use angular js ? Commented Oct 13, 2014 at 12:21
  • @jQueryAngryBird Don't know what it is. Is angular js similar to Mustache and HandlebarsJS? I will investigate. Commented Oct 13, 2014 at 12:25
  • htmlspecialchars() does not escape anything. It converts characters to html entities. addslashes() or mysqli_escape_string() are what you would use to escape characters. Commented Oct 13, 2014 at 12:27
  • @Brian. Let me rephrase. I wish the client to prevent XSS. Commented Oct 13, 2014 at 12:30
  • @jQueryAngryBird AngularJS looks like a very powerful framework, and I will strongly consider using it on future projects. For now, however, I just want to better render some templates. Commented Oct 13, 2014 at 12:54

1 Answer 1

1

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"

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you Ammaroff, Is the call back for the phone typically handled client side? For instance, client converts JSON to object, and then overrides that property? Or does the server create the JS object with the callback directly.
Yes the callback is handled from client side. you can inject display_phone in the json after getting it from the server, I updated the solution above.
I updated the solution you can visit the updated link in my answer
the latest plunker link in my updated answer is showing how to get json from server

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.