Thoughts, ideas, and discussion about Knockout.js

Using External jQuery Template Files With KnockoutJS

Update: another good solution for this topic is to use the external template engine found here.

A question recently came up on the Knockout forums about how to get better design time support in Visual Studio when working with jQuery templates and how to incorporate external template files into Knockout projects. Here are three different takes on solving both of these problems that each build on the previous idea.

Level One – Load individual template files

Store each template in a .html file without the script tags. You could use a different extension, but using .html or .htm will ensure that both the IDE will treat it properly and that the web server will serve it up without further configuration.

Make an AJAX request for each template file that you need and inject it into the document inside of a script tag.

Use a convention that the filename without the extension is the ID of the template (id attribute of the script tag).

Make sure that all of the template files have been loaded prior to calling ko.applyBindings

Example

First we store our templates in individual .html files. For example, suppose I have templates for a read-only view and for an editable view of an item. My read-only template might be stored in a file called Templates/itemTmpl.html and look like:

The ensureTemplates function will load each template that is required using our convention that the name of the file matches the id of the script. We inject the script tag into the document, as if it had been there the whole time. We keep track of how many have been loaded and in the success callback of the last one to load we call ko.applyBindings.

Note: We probably should consider some additional error handling here to make sure that we either retry loading any templates that fail or at least present the user with an error message if all of the templates fail to load.

Pros

Gives each page the flexibility to load only the templates that it needs

Gives good Intellisense and syntax highlighting in Visual Studio

No further configuration necessary

Cons

The requests are a bit chatty, as it makes individual requests for each file.

Level Two – Load a single file generated at build time

As in Level One, store each template in a .html file.

At build time, generate a single html file that includes all of your template files and wraps them in their script tags. Without being wrapped in their script tags or at least some identifiable container, we would not be able to easily understand where the templates start and end.

Make an AJAX request for the single .html file and call ko.applyBindings in the success callback of that request.

Example

We would store our templates in the same manner, but then during our build we would produce a single file that contains all of our templates. Here is one way to produce such a file using MSBUILD for a .NET Web Application project.

Open your Web Application’s .csproj file. At the end of the file uncomment the AfterBuild task and make it look something like:

On each build, we first delete our composite file that I named all.html. Then, we call a target named PrepareOneTemplate for each of our template files. The PrepareOneTemplate target simply builds a string that wraps the template file contents in an appropriate script tag and writes it to the composite file. The end result is a single file that contains all of the script tags for our templates.

There certainly are many ways that this file could be generated. I’m sure that most people could find a way to generate it as part of their build process, even by just calling some shell commands.

Pros

A single AJAX request is made for the templates.

Gives good Intellisense and syntax highlighting in Visual Studio, as you would still be always editing the individual .html template files.

Final project does not even need to include the individual .html files. If someone accidentally browsed to the composite .html file they would not see anything visible.

Cons

If we need to load different subsets of templates on each page, then we might have to do some work in the build to properly generate a variety of composite files.

We again wrap the template file contents in a script tag. Then we replace all quotes with \” and strip any carriage returns or line feeds. Finally, we put in the JavaScript statement that injects the text into our document.

Again, I am sure that there are many ways that this file could be generated as well, possibly by processing the files with regular expressions.

Pros

No need to add code for making an AJAX request, as the script tag would handle it naturally.

Gives good Intellisense and syntax highlighting in Visual Studio, as you would still be always editing the individual .html template files.

Could pull templates cross-domain, although doubtful that it would be a normal scenario.

Final project does not even need to include the individual .html files.

Cons

If we need to load different subsets of templates on each page, then we might have to do some work in the build to properly generate several scripts.

Final Thoughts

So far, I am happiest with the Level Three method. All three methods give you a decent experience in the IDE, but the last one is easy to use on a page and the build process takes care of the work. Any other ideas/thoughts/methods for including external templates while getting a good design-time experience?