jQuery Template Plugin

I have recently published my first jQuery plugin (jQuery template plugin). This was born out of a project I undertook on a hack day at my work (I encourage all developers to promote hack days in their work place). My project was a single page blog, utilizing the power of the client to cache and build the layout, and sending JSON messages from the server to the client for the required data. The idea was to have a light load on the server using the lightweight JSON messages, and providing a good user experience by utilizing caching and smooth transitions between pages with JavaScript.

A side effect of this was I required a solution for handling templates with JavaScript. I wanted to be able to load a template once from the server, cache it client side, and populate it with data when required. The same template could then be used many times without having to re-request from the server, for different posts, populating the required data.

I recently was asked if I knew any templating solutions in jQuery, and after a quick google search didn’t show anything concrete, I thought I would adapt my previous solution to create a jQuery plugin. A few hours work, and I’d produced a plugin. This plugin was designed to be versatile and easy to use. Templates can either be defined and loaded from separate html files, or from the same document using a jQuery selector. Simply passing in the selector, and the data to populate the template is all that is required:

The postData is a simple JavaScript object similar to the following:

The templates are also very simple, using data- attributes to tell the template engine what is populated:

Several different properties can be bound. The template engine also supports formatters to format content (dates etc) if the data may not be in the correct format. For more information, see the github page for the jQuery Template project.

I welcome any help in this project. It is my first open source project and I believe it has great potential and many potential uses in modern web applications, so any contributions are very welcome.

The jQuery plugin for download: http://plugins.jquery.com/loadTemplate/

36 thoughts on “jQuery Template Plugin

  1. Hi Paul,

    we are considering to use your jQuery plugin in one of your projects. There is however, one issue for which we would like to have a solution for before we integrate it. We are not sure in which way an array containing several entries can be rendered elegantly.

    Example:

    var data = {
    “status”: “NOK”,
    “details”: [“Main”, “Home”, “About”]
    };

    Can a template be defined in a way that one … tag is redered for each array element? I might see a possibility using the formatter feature your plugin supports. However, I am wondering how you intended users of your plugin to handle such a case.

    The output should be something like:

    <a href=”#” rel=”nofollow”>status: NOK</a>

    Main
    Home
    About

    I would greatly appreciate some hint on this regard. Thanks in advance.

    Cheers,

    Diego

    • This isn’t properly supported yet, but it is a good point and I will raise an issue on github around this (though the nested template issue does relate as well).

      The way I would currently do this is using the formatter feature. I would define a formatter that takes an array and outputs the html you want (possibly using the template plugin and another template, though I haven’t tested that).

      The solution would be something like the following:

      function ArrayToList(values) {
      return “<ul><li>” + values.join(“</li><li>”) + “</li></ul>”;
      }

      then you would add the function to the possible formatters by $.addTemplateFormatter({arrayToList: ArrayToList});

      nested templates would probably be overkill for this, but if your data was an array of objects (such as “details”: [{value: “Main”}, {value: “Home”}, {value: “About”}]) you could simply (I think):

      template:

      <li data-content=”value”><li>

      javascript

      function ArrayToList(values) {
      var $ul = $(“<ul/>”).loadTemplate(template, values);
      }

      I haven’t tested either solution so let me know if you experience issues and I will come back to you.

    • This should now be far easier to do in version 1.3.0. I have just provided a default formatter as part of the plugin to ease nesting templates. I have yet to provide the documentation on this, but it would be simple to use in your scenario.

      You can now bind to “this” meaning the object itself, rather than a property on an object, so providing an array of strings is also perfectly acceptable.

      To do what you want the template would be something like:

      <div data-content=”details” data-format=”nestedTemplateFormatter” data-format-options=”#listTemplate”></div>

      and the list template format

      <script type=”text/html” id=”listTemplate”>
      <div data-content=”this”></div>
      </script>

      I hope that helps you. If you do use it on the project, please do let me know, especially if you happy for me to promote it as a use case of the plugin. I’m always interested to see how others make use of it, and if you come across any other issues, please let me know.

      Kind Regards

      Paul

  2. Hi Paul,

    thanks a lot for such quick feedback and for the added feature. I will try it out, and let you know how it goes.

    Cheers,

    Diego

  3. Hello Paul,

    Im trying to use your plugin to format this data into a table and I would really appreciate your advice.

    JSON DATA:

    [
    {
    ‘data1’: ‘some1’,
    ‘data2’: ‘some2’,
    ‘data3’: ‘some3’,
    ‘data4’: ‘some4’,
    },
    {
    ‘data1’: ‘some1’,
    ‘data2’: ‘some2’,
    ‘data3’: ‘some3’,
    ‘data4’: ‘some4’,
    },
    {
    ‘data1’: ‘some1’,
    ‘data2’: ‘some2’,
    ‘data3’: ‘some3’,
    ‘data4’: ‘some4’,
    }
    ]

    FORMAT EXPECTED:
    ———————————————-
    | ANY-1 | ANY-2 | ANY-3 | ANY-4 |
    ———————————————-
    | some1 | some2 | some3 | some4 |
    ———————————————-
    | some1 | some2 | some3 | some4 |
    ———————————————-
    | some1 | some2 | some3 | some4 |
    ———————————————-

    I tried one way only using but it repeats the whole table and I get something like this.

    ———————————————-
    | ANY-1 | ANY-2 | ANY-3 | ANY-4 |
    ———————————————-
    | some1 | some2 | some3 | some4 |
    ———————————————-
    ———————————————-
    | ANY-1 | ANY-2 | ANY-3 | ANY-4 |
    ———————————————-
    | some1 | some2 | some3 | some4 |
    ———————————————-
    ———————————————-
    | ANY-1 | ANY-2 | ANY-3 | ANY-4 |
    ———————————————-
    | some1 | some2 | some3 | some4 |
    ———————————————-

    Thanks.

  4. Hi Paul,

    I tried out the nestedTemplateFormatter. I have have not been successful though. I created a fiddle with a simple use case: http://jsfiddle.net/FxYE6/4/

    Probably I am not fully understanding the binding to “this” in the nested template. It would be great If you could have a look and give me a hint on how to solve this. I think other people might be interested in having a working example of the nestedTemplateFormatter and an array as data.

    Thanks in advance.

    Cheers,

    Diego

    PS: thanks for putting the plugin in the CDN!

    • There were two issues. It appears the handling just a direct string in the options was lost somewhere along the line, so for now you have to pass an object here. Secondly it appears some of your quotes in your fiddle had copied oddly, so it wasn’t recognizing the attribute values correctly. I’ve got a working fiddle for you here, and I will look to correct the other issue for you in a new version.

      Fiddle: http://jsfiddle.net/FxYE6/5/

  5. Hi Paul,

    I know it’s been a while, but I wanted to let you know that we are using the nested template feature successfully. It is very usefull. Thanks a lot for implementing it!

    Cheers,

    Diego

  6. Hi paul,

    I have issues to generate the code below :

    text1

    Field1: value1
    Fild2: value2
    ………………………
    Fildn: value n

    ………..
    ………..

    text2

    Field1: value1
    Fild2: value2
    ………………………
    Fildn: value n

    I could not generate the id attribute and also the list of Fields . The fields are a keypair values.

    Can you make a quick sample with the data object and the template?

    Thanks

    • oops. this is the HTML I want to generate:

      • Hi Karim

        I would see the following example for an introduction to how it should work, and have a play around from there. It’s fairly similar to your example. You start targeting things like id with the more advance data-template-bind syntax. I would recommend look at the examples that come with the plugin to see how this syntax works.

        http://jsfiddle.net/eq2Fc/

  7. Hi Paul,

    I have another question for you. We have some situations, were some parts of the templates should be ignored if the data is not available. We have not found an elegant solution to this yet. I have created a fiddle to exemplify this:

    http://jsfiddle.net/amEtV/

    As you can see, ‘subtitle’ will be ‘null’ in the second case. In the third case, ‘subtitle’ is undefined. Nonetheless, the tag is rendered in both cases.

    One idea we had so far, is using a formatter that can check for the value of the data passed to it. However, for this you always need a wrapper element (correct me if I am wrong). Another thing you can do, is use a afterInsert or beforeInsert handler to clean up the code to markup.

    I don’t now if you intended your plugin to handle these cases. Nonetheless, if you see a more elegant solution to handle undefined or ‘null’ values I would gladly appreciate your thoughts on it.

    Once more, thanks for your time.

    Cheers,

    Diego

  8. Hello Paul,

    I noticed that loading templates from external files (e.g. $(“#templateTarget”).loadTemplate(“Templates/MyTemplate.html”, postData);) is not working on Mozilla and Firefox. Error: “There was an error loading the template.” I noticed this doing some examples myself and also running the examples available in library archive. I noticed though, that external files template loading works well in InternetExplorer.

    Can you please help me find a solution for this issue?

    Thank you,
    Eugen

      • Hello Paul,

        I’m using Firefox v: 28.0 with AdblockPlus addon, but I don’t think there is a problem with it being installed. Template loading works fine if i’m using inline templates. The problem is reflected only for external files. All other jQuery aspects are running on Firefox so I don’t think there is an issue with this addon. For example in Opera 12 doesn’t display anything generated with templates, and there is no addon for blocking javaScript or adds installed on it

        For tests I’m running Basic examples from 1.4.3

        Thank you.

        Best regards,
        Eugen

    • It depends what you want to do. There are a few built in things you can do such as hiding a field if it is null or empty, or your could supply a formatter to do more advanced logic.

  9. Hi Paul,

    i am new at this.
    i have tried to use your “nestedTemplateFormatter”, but i can’t quite use it for my problem.
    I am loading an external Template and i have data like these->

    var ehmX= {
    header1: ‘data1’,
    header2: ‘data2’,
    header3: ‘data3’
    }
    var boxData = {
    text1: ‘blabla’,
    text2 : ‘blabla2’,
    details: [ ehmX, ehmX, ehmX,…]
    }

    and then i want to load boxData multiple times.

    To be exact I’d like to generate this template:
    //BoxData

    Header1
    Header2
    Header3

    (want to loop this part again to create a table/ rows) // I’m stuck here

    data1
    data2
    data3

    I hope you can understand my problem.
    Thank you.

    Best Regards,

    Erdem

    • I cannot edit my comment and the html tags are gone.
      I need to loop a div box with a table (loop seperately rows) in it.

      To be exact I’d like to generate this template:
      -div-//BoxData

      -thead-
      -th- Header1
      -th- Header2
      -th- Header3
      -thead-

      (want to loop this part again to create a table/ rows) // I’m stuck here

      -tbody-
      -tr-
      -td- data1
      -td- data2
      -td- data3
      -tr-
      -tbody-

      -div-

  10. Hello Paul, i have problem with addTemplateFormatter
    “Formatters must be added before they are used else a template will not be able to access them.”
    Seems like in my simple example the template don’t see the formatters.
    But i don’t understand why the output is:
    xxx
    John
    John

    And not:
    xxx
    John
    JOHN

    $(document).ready(function () {
    json = {“name”: “John”,”nick”:”nick”};
    $.addTemplateFormatter({
    sameCaseFormatter: function (value, template) {
    alert(“!”);
    if (template == “upper”) {
    return value.toUpperCase();
    } else {
    return value.toLowerCase();
    }
    }
    });
    $(“#listLastReview”).loadTemplate($(“#rowLastReview”), json);
    });

    xxx

  11. Thank you so much. And sorry for the double comment.
    Now i have to try do a double template cause i have to show a list of comments inside a list of message.
    I hope i will do it without too many problems.

    Just a thing in the example above:
    “”
    is data-format, not data-template..right?

  12. Hi, great template engine. I have a problem getting a select working using the data-template-bind and options.

    Could you provide me with an example.
    1. Multiple Options
    2. One Option selected

    Thanks and keep up the great work
    Mark

    • You should just be able to write templates for this. You could provide a template for an option, and pass in an array of data. See http://codepb.github.io/jquery-template/Examples/index.html for an example of binding. To set an option to selected, you’d again have to pass this data in and bind it.

      An example data format could be [{value:1, text:”First Option”, selected:false}, {value:2, text:”Second Option”, selected:true}, …]

      And then you would just bind the appropriate attributes to the appropriate properties.

  13. I’have working something with templateloader but I run into a problem, i have a data ex: {x:0,y:3,z:4} and i need to have a complicated output ex:
    mydataformat = function(data)
    {
    if (data.x>1) {return y*z;}
    else
    if (y=1) {return z+x}
    else {return(x)}
    }

    in other words it is a calculated value from provided data, is there a way to for formatter function to access all the data provided to the loader, or to have multiple input parameters?

Leave a Reply