Asynchronous Template Loading With tmpload jQuery Plugin and Backbone.js

I prefer keeping my “views” on the frontend side when building a Single Page Application. I use templates to update data on a certain portion of my interface. Using templates gives you the advantage to isolate your logical Javascript code from your presentational part. So, instead of inserting text data into the DOM directly from your View clases like this:

  $('#main').html('<p>Ugly mixed text with code.</p><div>Hello!</div>')

You load a template that you defined earlier and assigned an id to it:

<script type="text/template" id="my-template">
  <p>Ugly mixed text with code.</p>
  <div>Hello {name}!</div>
</script>

Later then, you grab the template and display it:

  $('#main').html($('#my-template').html().replace('{name}', 'Dumitru'));

You can even use a template engine like jQuery Template, Mustache or Underscore.js to pull some variables in your templates and make them more useful. I prefer working with Underscore.js that implements the John Resig’s Microtemplate engine and it plays well with Backbone.js. For that I adjust my template syntax to the Underscore API:

<script type="text/template" id="my-underscore-template">
  <p>Ugly mixed text with code.</p>
  <div>Hello <%=name %>!</div>
</script>

And load my template with the _.template function:

  var compiled = _.template($('#my-underscore-template').html());
  $('#main').html(compiled({name : 'Dumitru'}));

The technic, sounds really nice – you keep the template in your DOM structure and only pick it up when you need it and load you content. The only problem is that when you have a lot of templates, your DOM structure keeps growing and growing and becomes ugly, heavy and hard to maintain. Another problem is that you keep a couple of templates in your DOM that probably the user won’t use them (i.e. templates for editing user details). Wouldn’t it be better to keep the templates in separate files and load them only when you need them? That’s exactly what the jQuery tmpload plugin does for you.

Usually I keep my templates in separate .html files in the public path:

  /public
    /templates
      /users
        login.html
        register.html
        edit.html
      /posts
        view.html
        comment.html
        edit.html

Basically you organize your templates however suits you most. After you created your template and dropped the HTML structure inside, you can load it with tmpload and reuse it:

  $.tmpload({
    url: '/templates/posts/view.html',
    tplWrapper: _.template,
    onLoad: function (compiledTpl) {
      $('#main').html(compiledTpl({name : 'Dumitru'}));
    }
  });

In the example above I load my template from a certain URL and also pass my template engine object to it. This way my plugin will compile the template automatically and send me back the template object that I can use in my onLoad callback. Executing the code in the onLoad callback assures you that the template is there.

Another important thing to notice is that the plugin caches the template so next time when you load the same template it doesn’t do a request to the server to grab it, it keeps it into a variable $.tmpload.templates.

You can still keep you template in your DOM structure and load it with the plugin. This way you don’t even need to execute your code in a callback because you don’t have asynchronous stuff going on:

  var compiledTpl = $.tmpload({
    id: 'my-underscore-template',
    tplWrapper: _.template
  });
  $('#main').html(compiledTpl({name : 'Dumitru'}));

When the template is in the DOM, it loads instantly and gets returned by the plugin. But I recommend using it with the onLoad callback, because it’s easier to refactor it latter when you switch to remote templates.

You also have the ability to set some default options to the plugin, so you don’t specify them latter:

  // somewhere in your app bootstrap
  $.tmpload.defaults.tplWrapper = _.template;

  // then in your code you don't have to specify the template engine anymore
  var compiledTpl = $.tmpload({
    id: 'my-underscore-template'
  });
  $('#main').html(compiledTpl({name : 'Dumitru'}));

Bellow is an example about how I use the templates in my Backbone Views (it’s CoffeeScript code):

  # somewhere in my bootstrap.js file
  $.tmpload.defaults.tplWrapper = _.template

  # then in my View
  class UserView extends Backbone.View
    tplUrl: '/templates/posts/view.html'

    render: ()->
      $el = $(@el)
      userModel = @model
      $.tmpload
        url: @tplUrl
        onLoad: (compiledTpl)->
          htmlData = compiledTpl({user: userModel})
          $el.html(htmlData)

  # after this I instantiate the view in my router
  userView = new UserView()
  userView.render()

If you want to load some templates from the DOM, you can tweak your view like this:

  # then in my View
  class UserView extends Backbone.View
    tplId: 'my-underscore-template'

    render: ()->
      $el = $(@el)
      compiledTpl = $.tmpload
        id: @tplId
      htmlData = compiledTpl({user: @model})
      $el.html(htmlData)

tmpload is a powerful plugin to use along with your SPA. I hope you’ll enjoy it.

Impressions From Full Frontal Javascript Conference 2011

Differently from other Javascript conferences, Full Frontal is supposed to be a one day conference that everyone can afford to go to. It happened in Brighton, a beautiful, small city in the South of the UK.

Remy Sharp is the one who managed the big crowd of over 300 geeks that met that Friday. He received a lot of help from his wife @Julieanne who supports his great geeky ideas.

The conference opened it’s doors at 9:30 in the morning which was a bit harsh for me, dealing with the previous night hangover. Lucky for me I stayed in a nearby Travelodge hotel that was at a 5 minutes distance from the venue.

There was a big crowd at Duke Of York’s already when I arrived at the registration. Everyone was happy to meet familiar faces once again and to share stories about their projects, weird code, ninjas and Web.

In a couple of minutes we proceeded to the main room where all the talks were held. It was a big cinema room with confortable chairs which everyone was really happy about :)

Remy opened the conference, explaining what everyone should do and not do and also announced the speakers. He also brought the sad news that there is no internet at the conference :(

The first speaker was Jeremy Ashkenas, the father of CoffeScript and Backbone.js. As a new version of CoffeeScript was coming soon, he presented the new goodies that this amazing language is providing. I was happy to see that a lot of people in the room were already using it (including me :p ). His conclusion was that languages that compile in Javascript make your life a lot easier as a developer and you should not be afraid to use it.

After a 15 minutes break, Phil Hawksworth told us about Excessive Enhancement and how we can get overloaded today with all the fancy tools around us on the Web and use them wrongly.

Marijn Haverbeke, an awesome guy from Amsterdam, presented his well-known project – CodeMirror. He is also the author of the Eloquent Javascript book – a very good one. The unique part of CodeMirror IDE is that it has an API that you can use everywhere. You can grab the slides from here.

After a break, Nicholas Zakas, who worked at Yahoo! and has a couple of books on Javascript, told us how to structure a Scalable application with Javascript. After his talk I started to have some doubts about my previous frontend apps architecture. :)

Around 14:00 all the geeks went to eat. We found some crappy food with average, expensive English beer in a pub nearby. But the point was to meet new people and discover more about their Web toys, right?…

Rik Arends, the CTO of Cloud9 IDE, shared his knowledge about the massive architecture of the IDE. His advice on how to scale Node apps and how they deal with a massive amount of requests and data were extremely welcome. Cloud9IDE is growing fast and I was surprised to see that a lot of people in the room were already using it (including me :p ).

Glenn Jones presented his amazing projects and how to play with drag and drop between browsers (even IE). Browsers are not totally prepared yet for exchanging data on drag, but it’s worth to give it a try.

Brendan Dawes is a creative director that came to the dev conference to open our eyes and pay attention to things around us, beyond our geeky, cyber life. He explains how weird and unordered things inspire and challenge him.

An amazing talk by Marcin Wichary closed the conference. He is the guy who stands behind the Google Doodles development. It’s very challenging to make those little scripts that should run fine in all browsers and load very fast. Usually there is no elegant solution to do it, so you should do what you gotta do – use hacks to fight the browsers. The most popular Doodle is Pac-Man.

After the conference everyone went to a party where there was a lot of alcohol, with the aim of sharing the impressions about Full Frontal 2011 and, once again, the stories about their projects, weird code, ninjas and Web…

Ah, yes, and here is a picture of the famous Brighton Pier:

Brighton Pier

Brighton Pier

Test parent function calls with Jasmine for Backbone.js and write getters with CoffeeScript

I spent about half an hour figuring out how to test a parent function call with Jasmine on code written with CoffeeScript. And, as usual, it was a stupid mistake.

So, my intension was to rewrite the “get” method of a Backbone Model class that will return a custom attribute. The code in CoffeeScript looks like this:

class Person extends Backbone.Model
  default:
    name:    null
    surname: null

  get: (attribute)->
    switch attribute
      when 'fullname' then @getFullname()
      else super attribute

  getFullname: ()->
    "#{@get('name')} #{@get('surname')}"

The model’s core “get” is rewritten here and checks the attribute calls. If the attribute equals “fullname” – the code will return the result of the “getFullname” method of the class. This method will glue the name and surname of the person that are stored as object’s attributes. In all other cases the parent “get” function will be called.

The specs for this code is pretty simple. The ambiguous thing is to spec the CoffeeScript “super” call on “get” method. In CoffeeScript the “super” keyword accesses the prototype of the class. The easiest way to test it is like this:

describe "Person", ()->
  person = undefined

  beforeEach ()->
    person = new window.Person()

  describe "get", ()->
    describe "when the full name is requested", ()->
      it "gets the full name", ()->
        spyOn(person, 'getFullname')
        person.get('fullname')
        expect(person.getFullname).toHaveBeenCalled()

    describe "when another attribute is requested", ()->
      it "calls super", ()->
        spyOn(window.Backbone.Model.prototype, 'get')
        person.get('fakeAttribute')
        expect(window.Backbone.Model.prototype.get)
        .toHaveBeenCalledWith('fakeAttribute')

  describe "getFullname", ()->
    ...

In the second describe block we check if the the call arrives to the parent class. That’s a pretty easy but sometimes confusing thing to do. The confusion comes from CoffeeScript that makes you forget that the “super” keyword translates as a prototype call :)

Single page application with Backbone.js on Rails

If you want to start a single page application (SPA) with a heavy front-end interface and you don’t have time to build your own Javascript MVC – you should definitely choose Backbone.js.

We are currently building a SPA that talks to an API written on Ruby on Rails. Choosing the right MVC Javascript framework from start was a crucial thing. From all frameworks released in the wild the most suitable ones for me seem to be Sammy.js and Backbone.js.

Judging by the features of the framework I could have chosen Sammy.js. It has a nice API and useful functions that Backbone.js is lacking. The multiple template type support for Sammy is also a plus.

On the other hand, Backbone.js seemed to be pretty wild and small compared to Sammy. The default templating system is Underscore.js that seemed to be pretty simple, based on micro templates.

After some testing I went with Backbone.js. The fact that it’s light and integrates beautifully with Ruby on Rails accentuated the choice. The missing features can be easily added by some extra programming. The micro templates are faster compared to HAML or Mustache. The only ugly thing is the pour readability of the templates but the new Rails has a cure for this, providing the integration of Jammit templates that are automatically compiled to micro templates on the first app run with the help of the jammit gem. Same thing with the CoffeScript files that are automatically compiled to javascript and glued on the first run.

A very important thing is to keep an intuitive app structure on front-end (which I didn’t do in the beginning). Keep all the models, collections, routers and views in separate files and folders. The most suitable structure for our team was this one:

/assets
    /javascripts
        /app
            /models
                user.coffee
                profile.coffee
                comment.coffee
            /collections
                users.coffee
                comments.coffee
            /routers
                main.coffee
            /views
                /users
                    add.coffee
                    list.coffee
                    search.coffee
                /profiles
                    edit.coffee
                    list.coffee
                /comments
                    add.coffee
                    list.coffee
            app.coffee
            index.js

The app.coffee has the main router initialization and also the templates manager configuration and loading. index.js has a list of all the files that have to be loaded and converted to raw javascript.

As for the templates loading and caching I used my custom jQuery plugin that I forked from markdagleish on GitHub and adjusted so it integrates smoothly with Undercore.js.

Backbone.js didn’t disappoint me so far. Seems to be simple, easy, light and fun. Tried it with Rails and NodeJS. Integrates very well with jQuery and Zepto.js. Use it with no fear :)

jQuery Doom Windows Plugin – Simple Javascript Dialogs

Looking for a tiny modal dialogs library? Then this one is for you.

Doom Windows is easy to style, configure and extend. It also has a couple of shortcut functions that make it easy to use.

Display modal dialogs, confirm windows and alerts in one line of code: dAlert(‘Error!’), dConfirm(‘Are you sure?’), dWindow(‘<p>Text</p>’).

I created this plugin because I wanted to get rid of jQuery UI in my projects as it was too big and slow.

Easy steps to include the plugin:

  1. Include the doom_windows_style.css style
  2. Include the jquery.doomWindows.js file
  3. Make windows: dWindow(‘<img src=”http://maps.google.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=14&size=400×400&sensor=false” alt=”Google Maps” width=”400″ height=”400″ />’)

Implementation examples

Display Google Maps in a separate dialog:

$('#view-map-bt').click(function () {
	dWindow('<img src="http://maps.google.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=14&size=400x400&sensor=false"
 alt="Google Maps" width="400" height="400" />');
});

//or:

$('#view-map-bt').click(function () {
	$('<img src="http://maps.google.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=14&size=400x400&sensor=false"
 alt="Google Maps" width="400" height="400" />').doomWindows({buttons:false, buttonClick: function (btType, win) {btType === 'close' && win.close();}});
});

Confirm modal box:

$('#view-map-bt').click(function () {
	dConfirm('Are you sure you want to delete this item?', function (btType, win) {
		(btType === 'no' || btType === 'close') && win.close();
		if (btType === 'yes') {
			// some ajax to delete item here
			win.close();
			dAlert('Item deleted!');
		}
	});
});

Alert modal:

$('#alert-bt').click(function () {
	dAlert('Omg! A fake error occured! Do not panic!');
});

Load remote content with Ajax:

$('#remote-bt').click(function () {
	dWindow(false, {
		ajaxUrl: $(this).attr('href'),
		cacheAjaxResult: true,
		wrapperId: 'log-in-window',
		minHeight: 317,
		minWidth: 430
	});
	return false;
});

Please check out for more examples on the DEMO page.

Advanced options that can be set:

styles ({position: ‘absolute’, ‘z-index’: 999, top: false, left: false}):
Window default styles.
width (‘auto’):
Set up a custom width of the window.
height (‘auto’):
Set up a custom height of the window.
minWidth (‘auto’):
Set up a custom min-width style.
minHeight (‘auto’):
Set up a custom min-height style.
overlay: (true):
Show or hide window overlay.
wrapp: (true):
Buy default the content is wrapped in a div of ‘doom-win’ class.
wrapperClass (‘doom-win’):
Set the deafult wrapper class.
wrapperId (false):
Give a unique id to your window so it’s easier to style it.
wrapperHtml (‘<div><div class=”doom-win-content”></div></div>’):
Set up a custom html window wrapper.
buttons ({ok:’Ok’}):
Bottom buttons and button text.
headerButtons ({close:’Close’}):
Header buttons and button text.
buttonsTranslate ([]):
Text translate for buttons.
buttonsTranslate (‘<div class=”doom-win-bt-cnt-header”><ul class=”doom-win-bt-list”>{buttons}</ul></div>’):
Header buttons html wrapper structure.
buttonsWrapperHtml (‘<div class=”doom-win-bt-cnt”><ul class=”doom-win-bt-list”>{buttons}</ul></div>’):
Bottom buttons html wrapper structure.
buttonHtml (‘<li class=”doom-win-bt-{buttonType}”><button data-type=”{buttonType}”><span>{buttonText}</span></button></li>’):
Message button HTML structure.
buttonClick (null):
A callback function when for all the buttons. Get the buttons key (ok, close, yes, no) and the window object as args. I.e.: function (btType, win) {btType === ‘close’ && win.close();}
closeOnEsc (true):
Close window on Escape keyboard button click.
ajaxUrl (null):
Set the ajax url if you want to load content remotely.
afterAjax (null):
After ajax callback function. Gets the ajax response as arg.
ajaxData (null):
Set some custome request query params for ajax.
cacheAjaxResult (false):
Set this if you want the ajax content to be cached in the browser.
onShow (null):
Callback function after the window is created and displayed.
Please support this free plugin developement and

Switch to our mobile site