5

Consider a HTML snippet such as this containing a series of placeholders (contained within single curly braces).

<div>
  { user.name }
  { user.username }
  { user.address.line1 }
  { user.address.line2 }
</div>

and a JavaScript object that looks like this:

var user = {
    name: 'Bob Foo',
    username: 'bobfoo',
    address : {
        line1: '10 Foo Street',
        line2: 'Footown'
    }
};

What's the best way to replace the placeholders with their equivalent variables? I appreciate this is a basic form of templating but i don't want a 3rd party dependency for handlebars or similar. I also don't want to add any specifics to the template other than the placeholders themselves. Changing the placeholder delimeter to something else would be fine if there was a specific need to do that such a clash with another library.

This is a snippet of JS from a larger file which we're using to parse the placeholders. It works fine but i'm not sure whether it's good practice, it's certainly not particularly elegant! It goes without saying we're wanting to do this without using eval() as the source of the data is a 3rd party.

      var template = $(self.options.templateId).html();

      for (var k in user) {
            if (!user.hasOwnProperty(k)) continue;
            if(k == 'address'){
                for (var k in user.address) {
                    if (!user.address.hasOwnProperty(k)) continue;
                    var needle = "{ user.address." + k + " }";
                    template = template.replace(needle, user.address[k]);   
                }
            }else{
                var needle = "{ user." + k + " }";
                template = template.replace(needle, user[k]);   
            }
        }

This is part of a jQuery plugin so any jQuery specific code is fine.

Thanks

1
  • You could check what underscore.js does under the hood, because its templating system is the most minimal [yet functional] I've ever seen. Commented Feb 5, 2014 at 10:59

4 Answers 4

3

Have a day off and what do I do? code something like this.
Tried to implement the template processing from scratch. It should perfectly fit your needs:
No Library used except jquery for adding the compiled template into DOM. Feel free to use it. Any1 is welcome to make this code better or smaller ;)

plunker

$(document).ready(function () {
  var tmpl = 
  ' <div>'+
  '   { user.name }'+
  '   { user.username }'+
  '   { user.address.line1 }'+
  '   { user.address.line2 }'+
  '</div>';

  var user = {
    name: 'Bob Foo',
    username: 'bobfoo',
    address : {
      line1: '10 Foo Street',
      line2: 'Footown'
    }
  };

  function compileTmpl(templateStr, data) {
    var tmpl = ''+templateStr;
    var tokens = tmpl.match(/\{(.[^{]+)\}/ig);
    for(var i=0; i<tokens.length; i++) {
      var t = tokens[i].replace(/([{}\s]+)/ig, '');
      if(t && t.length > 0) {
        var propChain = t.split('.');
        var val = data;
        for(var p=0; p<propChain.length; p++) {
          if(val && val.hasOwnProperty(propChain[p])) {
            val = val[propChain[p]];
          }
        }
        if(val.length > 0) {
           tmpl = tmpl.replace(new RegExp('{[ ]*'+t+'[ ]*}', 'ig'), val);
        }
      }
    }
    return tmpl;
  }

  var compiledTmpl = compileTmpl(tmpl, {user: user});
  $('body').append(compiledTmpl);

});

Output:

<div>   Bob Foo   bobfoo   10 Foo Street   Footown></div>
Sign up to request clarification or add additional context in comments.

Comments

0

If I had to do this, I have used AngularJS.

For data-binding to HTML you can use AngularJS.

For future: AngularJS use double brackets {{ }}, if you use single brackets critical, that you can change it in AngularJS script.

var sampleApp = angular.module('YourApp', [], function($interpolateProvider) {
    $interpolateProvider.startSymbol('{');
    $interpolateProvider.endSymbol('}');
});

1 Comment

This is part of a jQuery plugin and, as mentioned, I don't want to introduce a 3rd party dependency
0

you should use some Id's or classes for exampel

<div id="box1">
 <span class="name">{ user.name }</span>
 <span class="username">{ user.username }</span>
 <span class="line1">{ user.address.line1 }</span>
 <span class="line2">{ user.address.line2 }</span>
</div>

So u can access the html with jquery easiely, like this:

$('#box1 .name').html(user.name);

or

$('#box1 .name').text(user.name);

one of these should worke fine

2 Comments

The idea is that the template could be adapted for individual use-case's - the placeholders themselves should be the only requirement within the markup
you can make the placeholder like this: <span class="placeholder">{ user.name }</span> then interate over all placeholder's $('.placeholder').foreach ... at this function u search the text, do some string pasing stuff and write your values back
0

You better use the popular template plugin: http://skilldrick.co.uk/tmpl/#slide6

Instead of using custom code.

2 Comments

I did look into that but as far as I could tell the plugin is no longer under active development github.com/BorisMoore/jquery-tmpl It also appears overkill for this use
Attention of 44 users is no overkill? It was a official plugin, actually not because of bureaucracy.

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.