Here's a quick ‘n’ dirty Javascript function I hacked together that provides Django-like template substitution.

function sformat(template, data)
{
    return template.replace(/{{(.*?)}}/g, function(m, n) {
        return eval('data.'+n);
        });
}

Used something like this:

sformat("Hello, {{ name }}!", {name:"World"});

Which returns the following string:

Hello, World!

Alas, it doesn't support anything other than substitution. If you need anything more advanced (loops etc), you should investigate Javascript template engines.

This blog post was posted to It's All Geek to Me on Sunday April 5th, 2009 at 4:43PM
 

9 Responses to "Django like templates in Javascript"

  • Christof
    April 5th, 2009, 6:54 p.m.

    I think eval is somehow evil (and slow). I guess a better substitute would be to simply use ``return data;``. Should be the same, although I have not tested it.

  • Christof
    April 5th, 2009, 6:55 p.m.

    Sorry, bbcode messed up my post, should have been:

    return data[n]
  • Fraser
    April 5th, 2009, 7:03 p.m.

    As Christof says, the use of eval in this case is inadvisable as it leaves you vulnerable to injection attacks. For example, the following would result in an alert dialog being shown:

    sformat(
    "Hello, {{ name; alert('Nasty code goes here') }}!",
    {name:"World"}
    );
  • eelco
    April 5th, 2009, 7:04 p.m.

    How about this one instead:

    http://dojotoolkit.org/book/dojo-book-0-9/part-5-dojox/dojox-dtl [dojotoolkit.org]

  • April 5th, 2009, 8:27 p.m.

    I'm not really sure why anybody would want to do this?

    Care to share a usecase?

  • April 5th, 2009, 9:03 p.m.

    Christof, the reason I went with eval is that it could handle nested objects. so something like “{{ post.body }}” would work.

    Fraser, granted, although if the template doesn't come from an external source like an AJAX request, it shouldn't be an issue.

    eelco, that's pretty neat.

    Dougal, its more elegant than string concatenation, IMHO.

    html = sformat("<h1>{{ post.header }}</h1><p>{{ post.body }}</p>", {post:post});

    Verus:

    html="<h1>" + post.header + "</h1><p>" + post.body + "</p>";
  • rgz
    April 5th, 2009, 11:09 p.m.

    Yay! So I'm not that crazy! I wrote this one for all my js applications, note that it doesn't affect the original string (the first version did), also note that unmatched fields are left in the result, this is to use it in further substitutions, i.e. for writing template templates.

    /**
    * Template format tf
    * @argument values {object} Completa la plantilla con un objeto tipo diccionario.
    */
    String.prototype.tf = function(values){
    var text = this.toString()
    for (var name in values){
    text = text.replace(new RegExp("{" + name + "}" , ['g']), values[name])
    }
    return text
    }
  • April 5th, 2009, 11:14 p.m.

    RGZ, great minds think alike or fools seldom differ? ;-)

  • m0n5t3r
    April 6th, 2009, 12:54 a.m.

    When I needed something like that, I went with python-style sprintf (named arguments) and wrote a jQuery plug-in [plugins.jquery.com] :)

    so my code would look like

    var s1 = $.sprintf('Hello, %(name)s!', {'name': 'world'});
    // or, simpler:
    var s2 = $.sprintf('Hello, %s!', 'world');

    the less typing, the better :D

Leave a Comment

You can use bbcode in the comment: e.g. [b]This is bold[/b], [url]http://www.willmcgugan.com[/url], [code python]import this[/code]
Preview Posting...
Previewing comment, please wait a moment...

My Tweets

Will McGugan

My name is Will McGugan. I am an unabashed geek, an author, a hacker and a Python expert – amongst other things!

Search for Posts
Possibly related posts
Tags
Popular Tags
 
Archives
2010
 
Recent Comments
This is very true, i believe that people need to be able to use a domain if they register it, ...
Hehe Thats a good tatoo idea ;) Have a nice day Joel
- Joel Shapiro on Powered by Ubuntu
Weirdly enough i am a junior dev on an internship. I am @ work and i was way too bored/out ...
I love the idea of locidesktop, and even more the minimal UI. Hope you'll keep it up!
Many thanks! I tried several solutions but the only one that worked was yours.
 
© 2008 Will McGugan.

A technoblog blog, design by Will McGugan