Skip to content

Instantly share code, notes, and snippets.

@netroy
Created March 31, 2011 11:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save netroy/896192 to your computer and use it in GitHub Desktop.
Save netroy/896192 to your computer and use it in GitHub Desktop.
A small template rendering engine in JS ... uses Function constructor, unfortunately
function(b,c){return b.replace(/{[\w\.\(\)]+}/g,function(a){a=a.replace(/[\{\}]/g,"");try{with(c)return eval(a)}catch(b){return""}})};
goto http://jsfiddle.net/netroy/HA8es/ for a running example using this renderer
// Similar to the older version, without eval & with (sort-of)
function render(template, data) {
return template.replace(/\{[\w\.\-\(\)]+\}/g, function(match){
var token = match.replace(/[\{\}]/g,"");
try {
return (new Function("data", "return data." + token))(data);
} catch(e) {
return "";
}
});
}
// templates support object & function ... like "{abcd}" or "xyz.pqr" or "GL.package.class.init(arguments.toString())"
// data is an object with values that would be used for rendering .... like {abcd:"something",xyz:{pqr:123},arguments:[]}
function render(template, data){
return template.replace(/{[\w\.\-\(\)]+}/g, function(match){
var token = match.replace(/[\{\}]/g,"");
try {
with(data) {
return eval(token);
}
} catch(e) {
return "";
}
});
}
@jaseemabid
Copy link

Supplants can do this task

/* Supplant */
if(typeof String.prototype.supplant !== 'function') {
    String.prototype.supplant = function(o) {
        return this.replace(/{([^{}]*)}/g,
            function (a,b) {
                var r = o[b];
                return typeof r === 'string' ?
                    r : a;
            });
    };
}

You need a template and data

template = "this is {data}  "
data = {"data" : "value"}
result = template.supplant(data);

@netroy
Copy link
Author

netroy commented Oct 28, 2011

wouldn't work for nested objects like ...

template = "{user.name} is {user.age} years old"
data = {"user": {"name":"X", "age": 99}}

this was supposed to show that eval isn't all that unnecessary, if you understand the risks involved

@jaseemabid
Copy link

You can consider timeago plugin for awesome time stamps. Don't have to code yourself.

@jaseemabid
Copy link

Read through the fiddle sample. Nice :) Can we get rid of eval somehow? Will try to update supplants to handle this feature.

@netroy
Copy link
Author

netroy commented Oct 30, 2011

As of ES5, eval executes in a private scope, so its okay to use it if needed.
More important thing to remove is the with statement, but without that, i haven't figured out how to have function calls in templates.
for just namespaced objects, with can be replaced by a eval("data."+token)

@jaseemabid
Copy link

Will have to dig more into this. I got the above snippet from Crockford

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment