jQote – client-side templating

PLEASE NOTE:

jQote2 has been released. Please consider upgrading now!!! Click here for a quick summary of what’s new and what’s changed.

jQote (pronounced like Star Trek’s Chakotey) is basically a rewrite of John Resig’s awesome JavaScript Micro-Templating utility. I took his code and ported it to jQuery, overhauled the parsing / conversion part and extended it’s functionality to minimize everyone’s coding efforts.

See the jQote API reference.

PLEASE NOTE:
Version 1.1.0 now gives you the possibility of changing the tag character to something else than <% and %>. Please referr to the jQote API reference to see how to do it.

So, let’s get started writing down a basic template:

<script type="text/html" id="template">
<![CDATA[
    <p class="greetings">
        Hello <%= this.name %>, how are you doing?
        May I offer you
        <% this.is_starving() ? %>
            some tasty peasant?
        <% : %>
            a refreshing Singha?
        <% ; %>
    </p>
]]>
</script>

This well-mannered code snippet – though it may not seem like much – shows some very special markup, namely <%= expression %> and <% statement %>, respectively (please notice the extra ‘=’ sign on the first one).

As you may have guessed already, the code in-between these tags is mere JavaScript. To simplify things you should use the <%= %> tag whenever you want to directly echo a variable’s value (you may as well call a function or use any other expression, as long as it returns a string).

Pretty self-explanatory so far, hu? But what’s with all that <script type="text/html"> and <![CDATA[ ... ]]> shmoo, you ask? Well let’s cite John Resig here:
“Embedding scripts in your page that have a unknown content-type (such is the case here – the browser doesn’t know how to execute a text/html script) are simply ignored by the browser – and by search engines and screenreaders. It’s a perfect cloaking device for sneaking templates into your page. [...]“

Good news, that is we will be able to put our template code right into our HMTL source files and it won’t show up anywhere but in the sources (btw. thanks to the usage of CDATA it’s perfectly valid markup).

Now for the final part of our little example we’ll need some basic scripting to induce the conversion:

<script type="text/javascript">
    var obj= {
        name: 'Jabberwocky',
        is_starving: function() {
            return Math.random() > 0.5;
        }
    };
    $('#template').jqote(obj).appendTo($('body'));
</script>

That’s it, there’s nothing more to it than calling jQote on our template and providing it with some data object to get things started. jQote really is fun to use and cuts down on the time spent trying to inject arbitrary data into your sites. You’ll learn to love it pretty fast, I promise! Give it a try.

One final word: I’d like to thank John Resig for bringing this up. You rock, dude.

comments

30 Responses to “jQote – client-side templating”

  1. Jimmy Z on August 26th, 2009

    Are you planning to put this on github or anything?

  2. Mike on September 29th, 2009

    Any thoughts on how to support single quotes?

    I tried to fix the inability to use single quotes in Qote templates, but no luck. Looks like you’re using single quote as reserved parse symbol.

  3. aefxx on October 28th, 2009

    @ JimmyZ

    Sorry for not answering that long:
    No, I do not plan to host this on github or anything, for now.

    @Mike

    Mike, you’re totally right, I wasn’t planing for single quotes within html markup in templates, as I usualy stick to double quotes.

    Nevertheless, I fixed the problem with the current release. Check it out :D

  4. chrismarx on November 16th, 2009

    works great, why not put this in the jquery plugins library, so people can find it more easily?

  5. aefxx on November 17th, 2009

    @chrismarx

    Hi Chris,

    maybe it’s just me but it’s already there:

    http://plugins.jquery.com/project/jqote

    cu

  6. Shimon on November 30th, 2009

    I have tried your plugin with jquery 1.3.2
    (this shouldn’t be relevant but I am working with mvc and I changed the
    tag to ‘~’ to make life easier).

    It seems that is working but the is not working – waiting for your comment ! Thanks!

    when I tried the example above I got invalid function – when trying to debug
    your file :-) – see theredundant ‘;’ in trenary expression (a ? b : c)

    var t=[]; t.push('\
        \
            Hello ', this.name ,'\
        May I offer you\
           ');  this.is_starving() ?  t.push('\
                some tasty peasant?\
            ');  :  t.push('\
                a refreshing Singha?\
            ');  ;  t.push('\
                    \
            \
        \
    '); return $(t.join(''));
    
  7. Shimon on November 30th, 2009

    I have a problem with posting here because of special characters disappeared
    so here my comment again

    http://drop.io/jquery_jqote

    Thanks!

  8. aefxx on December 9th, 2009

    @Shimon

    Sorry for not getting back to you that long.

    Well, it looks like the ternary operator – the way you want to use it – is not supported by jQote, yet. You would either have to do it like this (please make sure to have it all on a single line):

    <~= this.is_starving() ? ' some tasty peasant?' : ' a refreshing Singha?' ~>

    .. or stick to plain old if’s and else’s.

    I’m planning to do a complete rewrite of the code since there are a couple more issues to be solved. And ternary operator should definetly make it into the plugin.

    So long.
    aefxx

  9. David on December 11th, 2009

    I would like to add the transformed string
    to an element’s innerHtml.
    The way I have got it to work is shown below using the
    the jquery.toXML plugin.
    Is this the best way to do it?

    //build transformed html from template

    var out =  $('#tmpl').jqote({content: content, toggleLabel:toggleLabel});
    console.log("out: "+ $(out[0]).toXML());

    //attach transformed html to element’s innerHtml

    $(this.element).html($(out[0]).toXML());
  10. David on December 12th, 2009

    I notice jqote cannot transform a template that is not wellformed.
    For example a template that just contains a json string like this causes an error:

    {"first":"Ryan", "last":"Campbell"}
  11. aefxx on December 12th, 2009

    @David

    I’m not quite sure what you were trying to achieve but there generally is no such thing as “the best way”. You could argue about performance but this hardly ever carries weight.

    Please note some points, though:

    1. jQote actually returns a jQuery object – not a “transformed string”
    2. every member of this jQuery object again is a jQuery object itself
    3. templates with pure scripting and no (x)html whatsoever won’t generate any output at all

    So, as for you’re example, I would do it this way:

    $(this.element).html($('#tmpl').jqote(obj)[0]);
    
  12. David on December 14th, 2009

    hi,

    Thanks for your reply to my post.

    Just want to give a quick comment.
    Would it be possible to extend templating solution
    to generate more than just x(html)? For example a json string.

    For a templating solution in javascript, one of the things I would like to use it for is it to pass json data to a javascript object. What I am trying to do is similiar to what is outlined by this post:
    http://particletree.com/features/loading-content-with-json/

    And so define the json string in a template, and have the javascript object get the json string by using the templating framework.

    I wasn’t able to use jqote but I was able to use another template solution based on John Resig microtemplate code
    http://weblogs.asp.net/dwahlin/archive/2009/04/17/minimize-code-by-using-jquery-and-data-templates.aspx

    Anyways just some feedback for you.

    best regards,
    David

  13. anentropic on December 17th, 2009

    @David
    Having a template system for generating json in javascript seems a bit pointless?
    Just create the array structure you want in code and then pass it through the json serializer, no…?

  14. gazbond on February 20th, 2010

    Absolutely brilliant plug-in but whats up with the license?
    I know the original script was MIT Licensed by John Resig,

    From the license:

    1) ‘Version 2, December 2004′ – is this the date of the original John Resig script?

    2) ‘Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.’ – is this a bad translation or should I be I be replacing the name – Sam Hocevar, with another? John Resig perhaps?

    Also are their any plans to support double quotes in expressions and statements?

  15. Phil Oye on February 23rd, 2010

    I’ll second the request for putting it up on Github so we can track your changes to this library over time. Plus, more eyes might help with bugs/enhancements.

    But at the very least, can you add a version number to the releases? It sounds like you are making changes to it, but there’s no way to tell.

    Cheers,
    p.

  16. Eric on March 2nd, 2010

    Super cool. I’m curious if it would ever be possible to use HAML for the templates? Seems like a long shot, however worthy. Keep up the beautiful work!

  17. aefxx on March 2nd, 2010

    @gazbond

    I’ll be soon releasing jQote2 – a major overhaul and complete rewrite of jQote’s internals. This won’t use any of Resig’s code anymore, insofar there then shouldn’t be any licensing issues.

    jQote2’s license will be DO WHAT THE FUCK YOU WANT TO, as is.

    @Phil Oye

    With the upcoming release there’ll now be a git repository at Github.
    Regarding the versioning issue: I never thought that jQote would make a wave and therefore didn’t put much time into it – until recently. jQote2 will have proper versioning (though I’m not a big fan of the “jquery.jqote-x.x.x.js” naming convention).

  18. aefxx on March 2nd, 2010

    @Eric

    Glad you like it. I’ve never heard of HAML before but will have a look. BUT please don’t quote me on that :D

  19. Martin on March 9th, 2010

    I notice that the licence has already been changed to DWTFYWTPL.

    Does this mean the version 2 is released?

  20. aefxx on March 10th, 2010

    @Martin

    Hello, no jQote2 hasn’t been released, yet. Work just pretty much piles up right now and I won’t be able to release it until the end of the week. Please bear with me.

    Sorry for the delay.

  21. Michael on March 14th, 2010

    Hi,
    I was struggling with the problem of how to nest a template into another. my solution is now this:

    var container = $('<p>');
    $('#tmpl').jqote(data_collection).appendTo(container);
    

    you can now easily get the generated html by calling

    container.html()

    Since the parent elements html will not be included you can use whatever container tag you want. Of course this is a workaround but it works. It would be great to have some kind of parameter for the jqote function to tell if you want to have the result to be a jquery object or just the plain generated html…

    Or have you done this already for jqote2?

    Keep on rocking!

  22. diyism on April 16th, 2010

    Give a try to the real “jquery micro template”, it need no seperate template container:
    plugins.jquery.com/project/micro_template

    <div id="test1" class="users">
         <!for (var i=0;i<users.length;++i)
               {!>
    <div onMouseOver="/*=users[i].color?'this.style.color=\''+users[i].color+'\';':''*/" id="user_<!=i!>" class='user'>Name:<a href="<!=users[i].name!>"><!=users[i].name!></a></div>
               <!}
         !>
    <pre>'somthing'
    else ...</pre>
    </div>
    
    <script>
    var data1={users:[{name:'name1.1'},
                      {name:'name1.2', color:'yellow'}
                     ]
              };
    $('#test1').drink(data1);
    </script>
    
  23. aefxx on April 16th, 2010

    @diyism

    Glad you made it here. Hello.

    Your plugin works without any “containers” you say.
    But isn’t <div id="test1"... a “container” for your template and wouldn’t that expose the HTML markup within your template to your viewers?

    Besides that you’ve build your plugin upon John Resig’s micro templating code which has flaws and shortcomings when it comes to code that spans over multiple lines and the correct escaping of quotes.

    Regards,
    aefxx

  24. David Wainwright on August 25th, 2010

    Firstly, thanks for developing jqote – it’s excellent.

    I want to add the selected=’selected’ attribute to an option at runtime within the template. I have the following code (I am using the older version of jqote but haven’t the time to upgrade just yet):

    <option value='’ <#= == this.SubjectId ? “selected=’selected’” : “” #> >

    But this is not being templated at all (the code inside the block is being rendered as is).

    What gives?

  25. David Wainwright on August 25th, 2010

    UPDATE: I have also tried:

    but this behaves in the same way

  26. volkan on February 13th, 2011

    Can we leave a bug report here? The example above does not work. I get “appendTo is not a function” error. Probably because jqote does not return jQuery object, which is how appendTo can work.

    I got around this by assigning to a variable and inserting that into the document.

  27. aefxx on February 13th, 2011

    @volkan

    Hi! You’re right, the jqote method does not return a jQuery object, anymore (this was changed with the release of jQote2). Please refer to jQote2’s API that offers convenience methods to help you with DOM manipulation.

    Regards,
    aefxx

  28. Daniel on April 1st, 2011

    This utility saved my life… Beautiful work, aefxx!

  29. Marc on November 3rd, 2012

    The example provided doesn’t work:
    $(‘#template’).jqote(obj).appendTo($(‘body’));
    Reason: $(‘#template’).jqote(obj) returns a string and not a jQuery element.

  30. Marc on November 3rd, 2012

    OK, so the API changed. So with the latest version of jqote2.js it would be.
    $(‘body’).append($(‘#template’).jqote(obj));

    Can anyone show me a template that handles an array (i.e. one which loops)?

Leave a Reply




  • About me

    Hello my friend, please call me aefxx.
    I'm a 31 year old software engineer and web developer. Born in Munich, Germany I am currently located at Freiburg im Breisgau.

  • Contact me

    I am available as a freelancer, so feel free to get in touch with me.

    email ... sam@aefxx.com
    icq ... 179630229 // ae.fxx

copyright © 2009 once upon my code • powered by WordPress • modified Whitespace theme by Brian Gardner