Hugoware

The product of a web developer with a little too much caffeine

Simple External jQuery Templates – Part 2

with 4 comments

In my last blog post I wrote about an interesting way to work with server side templates and avoid using callbacks to work with the elements you created. I worked on the concept some more and added some simple templating capabilities along with the ability to apply inline or external data. I’m posting this plugin to the jQuery website for downloading (along with parts of this blog post)

If you remember in the last post, the main problem was having to define callback methods to handle making changes to your jQuery object after it had been created. Instead, we used method forwarding and method queueing to allow direct access to the final object even before it had been created.

So instead of using callbacks your jQuery would look something like…

//loads an external resource but returns a placeholder to
//capture additional jQuery commands
$.template("/resource.html")
    .css({ color: "#f00" })
    .animate({ height: 400 })
    .click(function() { alert('clicked'); });

Interesting concept but requires some more work…

Important: This plugin simply helps avoid using callbacks to keep track of external templates.

What Is New?

Activation and Replacement Commands
The previous method worked pretty well if you’re adding to a page but if you needed to replace something then you were back to using callbacks to handle removing content from the page. This version adds a couple extra new functions to work with the document after the template has finished loading

  • fill(selector): Empties the target and then fills the container with the current jQuery object. (accepts a string or a jQuery object as a selector)
  • replace(selector): Removes the target and then puts the current jQuery object in its place. (accepts a string or a jQuery object as a selector)
  • ready(delegate(element) { ... }): Simple way to perform any action that you want immediately following the external resources being loaded and processed.

All of these commands can be used along with the rest of the existing jQuery commands (like styles, animations, events, etc) because they follow the same queueing rules that the rest of the methods use. So for example, you could write the following command…

$.template("/resource.html")
    .ready(function() { $(document.body).css({ background: "#00f" }); })
    .fill("#placeholder")
    .fadeIn();

Templating Engine

Another thing that was missing from before was a quick, automated way to populate the template after it was loaded. This version introduces a simple engine that allows you to pass in an object or a URL to the source to JSON data you want to use and then populate the template automatically.

Here is a simple example of using a template with a data source…

[template.html]

<div class="customer-list">
	<a href="javascript:void(0);" class="refresh" >Refresh</a>
	<h2>%%title%%</h2>
	<p>%%description%%</p>
	<ul>
	    <li each="%%customers%%" class="%%odd:'alt-row'%%" >
	        <h4 class="%%first:'top-customer'%%" >%%name%%</h4>
	        <ul>
	            <li each="contacts" class="%%first:'preferred'%% %%odd:'alt'%% contact-%%type%%">%%value%%</li>
	        </ul>
	        <hr if="%%!last%%" />
	    </li>
	</ul>
</div>

[data.json]

{"title":"Customer List",
"description":"Customers and their contact methods.",
"customers":[
    { "name":"Mark", "contacts":[
        { "type":"email", "value":"mark@example.com" },
        { "type":"email", "value":"supermark@example.com" },
        { "type":"phone", "value":"555-1254" }
    ]},
    { "name":"Susan", "contacts":[
        { "type":"email", "value":"susan@example.com" },
        { "type":"phone", "value":"555-9811" }
    ]},
    { "name":"Jamie", "contacts":[
        { "type":"email", "value":"jamie@example.com" },
        { "type":"phone", "value":"555-4322" },
        { "type":"phone", "value":"555-1077" }
    ]}
]}

[script.js]

var list = $.template({
	template: "template.html",
	externalData: "data.json"
})
.ready(function() {
	$(document.body).css({ background: "#ffc" })
})
.appendTo("#target")
.find(".preferred")
	.css({ color: "#f00" })
	.end()
.find("h4")
	.css({ color: "#00f" });

The final rendered result would look like the following sample…

I suspect that a templating engine written in the duration it takes me to finish a Starbucks coffee isn’t going to be high enough quality for everyone so you can easily replace it with a custom one by using the following command.

$.template(function(params) {
    /* perform formatting in this block (or send it to another templating engine)
     * params.html: The text provided by the template from the server
     * params.data: The JSON data provided for rendering (if any)
     */

    //must return a jQuery object
    return $(params.html);
});

This will replace the template formatting method for the duration of the page, however you can replace the formatting on a per request basis (but I’ll explain that later)

How To Use

There are a few ways you can use the template command.

$.template(function(params) { ... });
Replaces the template formatting method with a custom method. The argument passed in contains a html property that contains the string of HTML to use for the template. The argument also contains a data property that contains the JSON data to populate the template with (if any). This should return a jQuery object when finished.

$.template("/path/to/template.html")
Simply downloads the HTML from an external path and then returns the jQuery object after it has finished loading. This option does not support templating.

$.template({ options })
Allows a lot more control over the request. The argument accepts the following properties.

  • template: The URL that points to the template file. You can optionally pass in an object that contains the same parameters as the $.ajax command so you can have full control over the request.
  • externalData [optional]: The URL that points to the JSON content for the template. You can optionally pass in an object that contains the same parameters as the $.ajax command so you can have full control over the request.
  • data [optional]: A JSON object with data to populate the template with.
  • complain [optional]: Determines if an exception should be thrown if the template and the data do not cooperate with each other (such as missing information).
  • error [optional]: A delegate that handles any connection errors. The first argument will tell where the error took place (external data or the template).
  • format [optional]: A delegate that performs formatting for a template. This won’t replace the default formatting. Requires the same delegate type as the example for replacing the default version.

Source Code

For now I’m simply uploading the code for downloading but I’m going to post it to the jQuery website shortly. I’d like to get some feedback and check for bugs before I save anything to the site.

Also — If anyone can come up with a clever, buzz-wordy sort of name of the plugin, please clue me in! I’m terrible at naming applications or plugins.

Download

Download template.js (full source code)

.

Advertisements

Written by hugoware

January 24, 2010 at 10:38 pm

4 Responses

Subscribe to comments with RSS.

  1. Great post. I’m finishing up a project and can’t to try this. How about “Templer” for a name?

    ActiveEngine Sensei

    January 25, 2010 at 5:35 pm

    • Cool – I used this in a project today and I felt it worked pretty well. It was weird being able to use an external template all in one jQuery chained command (or one or two lines down, outside of the command)

      I like the name idea – Sounds catchy.

      webdev_hb

      January 26, 2010 at 11:12 pm

  2. Good Idea! Thank you this is usefully and very nice.

    Atasözleri

    February 17, 2010 at 11:02 am

  3. thanks for share.

    jquery templates

    May 25, 2010 at 5:50 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: