Category Archives: Client Templates

Using Google Closure Templates with ASP.NET MVC in Visual Studio 2010

Client-side templates have become a vital component of AJAX-driven websites. The web is undoubtedly trending towards sites that load content dynamically after the page loads, rather than all at once in the initial page request. This pattern allows web pages to become lighter and more responsive, which translates to a better experience for the user. However, the conventional server side templating and databinding techniques that web developers typically use aren’t as effective anymore. That is why there are so many JavaScript template solutions that have popped up in recent years:

Google’s Closure Templates is the new kid on the block, and the subject of this article. One might wonder: Why do we need yet another JavaScript templating solution? The main advantage that sets Closure Templates apart from the other libraries is the included compiler. Other templating solutions either parse a string of special template syntax, or traverse through actual html elements with special markup or extra classes. When making light use of client-side templates, these solutions can work very well. But, as you start to build applications with extremely large datasets and complex templating, then performance starts to become an issue. These scenarios are where Closure templates begin to shine. Instead of directly using the template that you write, you run it through the compiler to output JavaScript functions that you can use in your code. This process is advantageous on two levels; the first is that the JavaScript functions outputted from the compiler are going to be optimized and extremely fast. Secondly, the compiler can also create server side compatible templates as well, so that you can write your templates once and be able to use them either in JavaScript or in server-side code. Unfortunately, the current version of the compiler can only generate Java code, and there is no option for .NET languages such as C#. This is a bummer for .NET developers, but even without C# templates, there is still great value in lightning-fast, compiled JavaScript templates.

Creating your first Closure Template in Visual Studio 2010

Let’s start with a new ASP.NET MVC Project:

vs2010-new-mvc-project

You can create a Web Application project if you are more comfortable with that type of project structure. Because we will be dealing with just JavaScript, it shouldn’t matter.

After creating a project, download the compiler and JavaScript utility library. Extract the zip file, and copy both SoyToJsSrcCompiler.jar and soyutils.js to your templates directory:

soy-compiler

You will see in the screenshot above that I have changed the Build Action of SoyToJsSrcCompiler.jar to “None”, and Copy to Output Directory is set to “Do not copy”. This ensures that the compiler is not compiled into the dll, and the file is not copied to the output folder. The latter is especially useful when using Visual Studio’s publish feature, because the compiler is not necessary when deploying your website.

Now that we have the required files in place, let’s go ahead and create a soy template file, example.soy. This is the file that will contain one or more templates using Closure’s template syntax. After creating a template in this file, we will then use the compiler to generate a JavaScript representation of the template that we will reference in our html page. Every soy file should have the three following components, in the following order:

  • A namespace declaration.
  • One or more template definitions.
  • A newline at the end of the file.

Go ahead and enter the following example template in your example.soy file:

{namespace closure.examples}

/**
* Says hello to a person.
* @param name The name of the person to say hello to.
*/
{template .helloName}
Hello {$name}!
{/template}

Make sure that your soy file is encoded as ANSI, rather than UTF-8. Even though Google says UTF-8 should be supported, in Windows 7 x64 (and maybe other Windows operating systems and versions) this is currently not the case. And if you create a file within Visual Studio, it will encode the file as UTF-8 and you will get the following exception when compiling a template:

Exception in thread "main" com.google.template.soy.base.SoySyntaxException: In file example.soy: Tag 'namespace' not at start of line.

closure-compiler-encoding-exception

If you are unsure that your file is saved with the proper encoding, just open it up in notepad, and select File > Save As to see or change the encoding.

After we’ve included the necessary files in our project, it’s time to make compiling templates a little more user-friendly. The jar file is pretty annoying to call from the command line and manually change the parameters for each of your different soy files. Visual Studio has a perfect solution for this, and it’s called External Tools. This feature allows you to set up a VS menu item and seamlessly run commands from the IDE with just the press of a button. To do this, first click on Tools > External Tools from the menu:

external-tools

From here, you can create a new menu item with the following parameters:
Title: Compile Closure Template
Command: C:Program Files (x86)Javajre6binjava.exe
Arguments: -jar "$(ItemDir)SoyToJsSrcCompiler.jar" --outputPathFormat $(ItemFileName).js $(ItemFileName)$(ItemExt)
Initial Directory: $(ItemDir)

(Thanks to Tj Stewart for this tip)

Note that your Command entry may differ, depending on where your java installation resides on your computer. Here is what it looks like:

closure-template-tool

Once you have this setup, compiling your soy templates is as simple as selecting the soy file in solution explorer and pressing the “Compile Closure Template” button in the Tools menu:

invoke-closure-template-tool

When you attempt to compile a template, make sure to have your output window open. If there are any exceptions that occur during the compilation, this is where they will be displayed. If the compilation was successful, you should now have a new example.js file in the Templates directory. Note that it won’t be added to the project automatically, so you’ll have to add it yourself. Subsequent compiles for the same soy file will only require this step once.

Now let’s create a page to utilize the new template, and call it example.html. We could create an MVC view, but it really isn’t necessary since we are only dealing with JavaScript:

[sourcecode language="xml"]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="Scripts/Templates/soyutils.js"></script>
<script type="text/javascript" src="Scripts/Templates/example.js"></script>
<script type="text/javascript">
$(function () {
$(‘#wrapper’).html(closure.examples.helloName({ name: ‘Sam’ }));
});
</script>
</head>
<body>
<div id="wrapper"></div>
</body>
</html>

[/sourcecode]

I’m using a little jQuery to make my life easier here, and notice that I am passing JSON with the Closure template parameters as the properties of the object. Your result should look something like this:

closure-result

In summary, Google Closure Templates provide a scalable solution to client side templating by providing an understandable syntax in the form of soy files, with the ability to compile those templates into fast and efficient JavaScript functions that you can use in your pages. Even though there is no current support for reusing Closure templates in C#, there is still value in utilizing this solution in a Visual Studio project, especially when the External Tools feature makes compilations so easy and convenient.

I hope this article serves as a starting point to getting up and running in Visual Studio 2010. In future articles, I will be delving into more complex examples and explanations of Closure Templates in real-world scenarios.

Client side templates using ASP.NET, JQuery, Chain.js, and TaffyDB

For those that know me, it goes without saying that I’ve fallen head over heels for jQuery. It just makes working with javascript much easier and cleaner than ever before, and opens the door to so many new possibilities that were just to cumbersome even a few years ago. Of course, with new possibilities always comes new challenges. One of those important challenges is client side templating.

For me, there was an evolutionary process before getting to the point where I realized client side templating was important. It all started out in the olden days of using ASP.NET Web Controls. With Web Controls, the idea was pretty simple: You bind your control to a datasource, and any events you wanted to take action on in that control would require a postback to the server. These postbacks were hugely interruptive, especially when performing lots of different manipulations on a single page. So when “Atlas” and the UpdatePanel came along, it looked to be exactly what we needed. We build pages in the exact same way we always did, slap an UpdatePanel around the whole thing, and magically all our problems would go away. Well as we’ve all found out by now, it’s not that simple. The heaviness and waste of an entire page lifecycle on each async postback, combined with the limitations of the postback model itself made it useful only in certain situations (like removing the flicker from an existing website with heavy postbacks).

When I first started using jQuery, I quickly realized that I could circumvent the whole postback model in favor of ajax and REST services, but I still wasn’t ready to give up the WebControls like ListView and GridView that I’ve used for so long. That was when I had the idea of calling a service to render a UserControl on the server, and pass back the html to insert onto my page. After googling “render user control service”, I quickly found out that I wasn’t the only one thinking of this idea, and off I went to get it working.

After using it for a few scenarios, the drawbacks of this approach started to be more apparent. The first drawback was getting access to the actual data. Sure, you have rendered view, but what if you wanted to do more with a particular record in that view, like show it on a google map? Do you try and extract what you need from the rendered html, or do you have a separate ajax call to get just the data? Another challenging drawback was control state, like scroll location or pagination. For example, if you render a UserControl with a ListView and PagerControl on it, you get paging buttons that are absolutely useless. I got around this by using jQuery to intercept the click events of those page buttons to call the rendering service, but these issues had me feeling like I was hacking the solution just to get the control and accessibility I needed. Finally, there is the bloat factor. Yes, this solution is much much lighter than the UpdatePanel + postback model, but not nearly as light as just passing the data down as JSON and rendering that data on the client.

Which brings me to the second-to-last step in the journey to client templates: rendering the data yourself with jQuery. Rick Strahl has a good blog post of this technique, but I’ll give an example of my own. You simply start with a block of html on your page that will serve as your template, like the following markup:

client-template

After you pull your JSON data from the web service, you clone the html for each record and inject the appropriate data, adding event handlers as you go:

manual-databinding

This approach has a lot of things going for it — bandwidth efficiency, lightweight processing, and templates that are understandable. However, once you’ve coded a couple of these scenarios, two things become obvious. The first is that you are writing a hell of a lot of repetitive code just to match the correct element in the template with its value. The second thing is that you have to write lots more code if you want to do any kind of synchronization between two views that share the same data. How can we solve these two problems?

Enter Chain.js

Chain.js is a jQuery plugin that aims to solve the templating and data synchronization shortcomings that I mentioned above. My favorite demo synchronizes two lists together, which really shows the simplicity and power of Chain.js in both templating and synchronizing two views dynamically. You start with the following markup:

chain-template

We have two lists here, each with a template called “item”. The aim of the demo is to populate the “persons” list with a dataset, and then link the “filtered” list to show the items that have been filtered out of the first list. Here is the code that makes it all happen:

chain-databinding

In the above code, the items plugin is initialized on the persons list with some data, and then .chain() is called to automatically bind the data to the template inside of the persons list. The default Chain.js data binder looks for classNames that correspond to the property on the JSON element. Chain.js automatically looks for the first item inside of the parent element to use as the template, but you can configure precisely where your template is with the anchor option. Next, a handler is setup on input’s keyup event so that we can use filter function to filter the list of items on every keystroke. Finally, we take our second list and link it to the collection ‘hidden’ on our first list, and call chain to initiate the data binding.

You can see the final result on the Chain.js Demo Page.

Chain.js is a great concept and great code, and it works very well in these demos. But it is still a project in it’s infancy, and that is apparent when you try to scale up the amount of data you are binding to, and the amount of views that are linked to the data. The performance literally grinds to a halt, even on the fastest machines.

Solving the current limitations of Chain.js

When analyzing the source code for Chain.js, I realized I could do something fairly simple right off the bat to speed up data-binding: use innerHTML instead of jQuery’s clone() method to create each templated item. The internals of the binding function “$update” in Chain.js look something like this (as of version 0.1):

chain-mod1

Here is the modified code that uses innerHTML to create all the items ahead of time (without jQuery’s clone), and the loop picks each item out of the list for data binding:

chain-mod2-innerhtml

Just this change alone made data binding about twice as fast in my testing. But with large datasets, that wasn’t enough of an increase. So I dug some more and I identified another issue: when synchronizing a series of views, the collections that you subscribe to are filtered with jQuery. So therefore, your master view is always required to create a corresponding DOM element for each data item. This means that if you have a thousand data items, but you only want your views to render and show a subset of those thousand items, then you still have to create a master view, which in turn requires a DOM element for each data item. That is a ton of extra work! So I set out to modify the code so that a master object is created that doesn’t have any dom elements that correspond to the data. Then, all other views are a linked to this object. But without the DOM, how are we supposed to use jQuery to filter our collections? The answer is, we don’t.

Enter Taffy DB

Taffy DB is a lightweight javascript library that acts as a thin data layer on the client. This is exactly what is needed to quickly select the elements needed for the subscribing views. By circumventing the creation of dom elements and jQuery selectors to build the collections, performance increased approximately four-fold beyond the innerHTML modification! Unfortunately, the implementation of Taffy DB required changes in many areas of Chain.js, so I do not have any code samples. But if there is demand, I may either post my modified code, or coordinate with the author of Rizqi Ahmad, the creator of Chain.js, to implement some of these ideas.

Other Client Template Libraries

It is pretty obvious that many developers see client templating as important going forward. This is evident in the amount of Client Template Libraries that are cropping up. Just recently, Microsoft released a preview of ASP.NET AJAX 4.0, which includes client-side template rendering. This seems promising, but I haven’t had much time to play around with it. There’s also jTemplates, PURE, and LightningDOM, although they are more geared towards just client side templating, rather than trying to tackle synchronization (like Chain.js and ASP.NET AJAX 4.0). If I’ve missed any other libraries, please let me know!