Monday, September 19, 2011

vkTemplate - jQuery Template Plugin

http://www.eslinstructor.net/vktemplate/
https://code.google.com/p/vktemplate/downloads/list

vkTemplate is a very small, simple and powerful template solution for web applications.
  • Small: Less then 1.5 k if minified
  • Simple: only one function with 2 mandatory and 2 optional parameters. No need to learn some funky template markup language or refer to list of API functions.
  • Power: well known and popular micro-template engin written by John Resig ( http://ejohn.org ) is used in this plugin as a core function. What's nice about this engine is that you can utilize any Javascript in the template and you're not limited to just a few commands.

16 comments:

  1. Great work thanks.

    I have a question. Can I use a global variable defined in javascript in the template and therefore not coming from the json oobject?

    I have tried with no luck.

    Thanks

    Nic

    ReplyDelete
  2. Yes, you can.

    But these vars must be global. Say, in your index page you can insert <script> var foo="Nic";</script> and use it inside your template:

    my name is <%=foo%>

    Global variable can also be defined at the top of you javascript file. But not inside function which calls template or inside template itself within <script></script> Template doesn't inherit context from function it is called from.

    Try it. Let me know if you still have problem and I will add example to my demo for you.

    ReplyDelete
  3. Hi Vadim

    I have the following issues:
    1) your http://www.eslinstructor.net/ is not available
    2) I get "not well formed" when I load a template from harddisk
    3) we can provide the JSON as an object. Would be great if we could do the same for the template - or simply dump it into a tag like Resig suggested

    Thanks

    ReplyDelete
    Replies
    1. Ok, found problem 2 - need to wrap the <%=...> in valid html

      Delete
    2. Hi mplungjan,

      thank you for using my plugin.

      1. if you're talking about eslinstructor's index page, I don't care of that. I don't use this server as a home for my website. It's just a simple way to publish some stuff. Plugin's pages work properly, at least I haven't found any problem there.

      2. OK

      3. Well, maybe I'll add this option some day. However this solution exists already. It is the original Resig's template engine, which this plugin is built on. That's why I'm not sure if it's needed here.

      Delete
  4. Hi Vadim,

    Thanks for developing this plugin! And answering my question on stackoverflow about it. I'm really starting to get the hang of it, but the one issue I'm continuing to have is debugging. It seems that all errors in my code make your code choke, thus chrome console always identifies some line in vmTemplate.js as having caused the error. This is obviously incorrect, but I don't have any idea where in my code to start searching and consequently have to pore of the whole .tmpl document to find a misplaced bracket or semicolon. Is there another way to debug that's ...less work? Thanks again!

    ReplyDelete
  5. Hi Thomas.
    Thank you for using my plugin.

    Well... I can't suggest you anything specific as I don't have your code. Based on my own experience: if I can't find a bug in my large template I try to isolate the issue. I simply delete everything and leave something very basic, just one line, to be sure that plugin works correctly and json data is received and correct. Then I add code chunk by chunk.
    I use notepad++ editor, which highlights syntax. It helps.

    If you give me a link to your application, I can briefly look at the code to see if there is any obvious bug.

    best regards,

    -Vadim

    ReplyDelete
    Replies
    1. Thank you. I really appreciate the offer, but I'm doing okay. Just slowly :P I only thought that there might be some eclipse program out there that is informed about <% ... %> closures and could debug through them.

      Thanks again for all your support!

      Delete
  6. Hello, Vadim, I have a question about appending. You allow to append the template, not erasing the contents, but consider this example: I have a table with dozens of TR's, I want to add few more lines, but I can't do so without wrapping them in some element(div or any other), just like you show in your example. It's pretty easy to unwrap if you parse only one element, but if it's a loop, I can't seem to find an easy way to unwrap them from this div. Could you please update and make it so this container element would not be necessary to append template? Thank you very much!

    ReplyDelete
  7. Hi Vlakarados.
    Thank you for using my plugin.

    I see a few ways to work around your problem.

    1. Modify your template.

    Suppose your template is
    <tr>
    <td><%=o.foo%></td>
    <td><%=o.bar%></td>
    </tr>
    and you append it to the <tbody> element. In my documentation I suggest to use <div> as a wrapper. In your case you can use "tr" as a wrapper.
    $('#my_tbody')
    .append('<tr>')
    .children(':last')
    .vkTemplate('tmpl/basic.tmpl','php/basic.php');

    2. Remove wrapper.

    You can use callback function to manipulate with wrapper element. Callback function has 3 arguments: elm, jsonObj, cntx. The first argument is the element your template is attached to. If you use recommended append technique, the wrapper is the first and only one child of the "elm".

    3. Customize plugin.

    Internally plugin makes a template's parent element empty before rendering html fragment it produces. You can prevent this by removing empty() function from the code. Take a look at the code
    https://github.com/vkiryukhin/vkTemplate/blob/master/vktemplate.js
    There are 3 lines which you need to edit: #94, #102, #117

    Please let me know if you still need help.
    Thank you,

    -Vadim

    ReplyDelete
  8. Hi Vadim,

    I'm trying to use your plugin on an ajax call i'm trying to tie into jquery deferred. When I call the function which does the ajax like this:

    $(document).ready(function(){

    //populate the dropdowns on page load
    $.when(populate_sector_dropdown('sector_dropdown_1')).done(function() {
    var new_sector_clone = $('#sector_1').clone();
    console.log(new_sector_clone);
    });

    });

    With ajax that looks like this:

    function populate_sector_dropdown(sectorDropdown) {

    return $.ajax({
    type: 'get',
    url: 'queries/sectors_dropdown.php',
    dataType: 'json',
    success: function(returnedData) {

    $('#' + sectorDropdown).vkTemplate('templates/sectors_dropdown_template.tmpl?', returnedData, function() {

    //console.log('template applied');
    });
    }
    });
    }​

    It is as though, the ajax call that your template is making (i guess this is what's happening) is in some way I can't understand preventing the line under the done() feature from firing after the ajax is complete. I can tell this because the clone that is made does not have the dropdown that is populated with the ajax content, ie. cloned before ajax is complete. Do you have a way to make the template play nicely with jquery deferred? Have I missed something obvious? Thank you very, very much!!

    ReplyDelete
  9. here is a fiddle
    http://jsfiddle.net/loren_hibbard/KDG4R/

    ReplyDelete
  10. Hi Thomas,

    At the first glance, I would simplify your example this way:
    (use http://jsbeautifier.org/ to beautify javascript code)

    $(document).ready(function () {

    $('#sector_dropdown_1').vkTemplate('templates/sectors_dropdown_template.tmpl?', //template
    'queries/sectors_dropdown.php', //data
    function () {//callback
    var new_sector_clone = $('#sector_1').clone();
    console.log(new_sector_clone);
    });

    });

    In fact, vkTemplate accepts both "template" and "data" as URLs. And callback function let you to process code, which is associated with rendered template.

    What about defer vkTemplate: in your case deferred object is populate_sector_dropdown(), which runs ajax, which in its callback runs vkTemplate, which, in turn, runs another ajax. So, it's nested ajax'es, or, in other words, ajax chain. I think, jQuery considers your "populate_sector_dropdown()" resolved after the first (master) ajax success. Again, it's not a queue, it's a chain.

    Hope this helps.
    And thank you for using my plugin.

    Best regards,
    -Vadim

    ReplyDelete
  11. so is there someway i can tell jquery that the ajax is not resolved until after vk's secondary ajax call? I don't really see what change you've made to the code. And yeah, haha, I didn't indent it properly when I posted it, but it doesn't look like that in my document. :)

    ReplyDelete
  12. You really don't see the difference? Well...
    If my suggestion doesn't work, I'm afraid, I can't help you, sorry.

    ReplyDelete