<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Notes to myself</title><link>https://weblogs.asp.net:443/alexeigorkov/</link><description>ASP.NET MVC, JavaScript, CSS, HTML</description><item><title>Looking for ko.utils.cloneNodes - knockout debug vs release versions</title><link>https://weblogs.asp.net:443/alexeigorkov/looking-for-ko-utils-clonenodes-knockout-debug-vs-release-versions</link><description>&lt;p&gt;Completely my fault. I used knockout.js uility method ko.utils.cloneNodes despite the fact that it is not exported using ko.exportSymbol in the source code of the library.&lt;/p&gt;
&lt;p&gt;Result? The mehtod name is obfuscated and is not accessible in minified version of the library. And I got a script error complaining of undefined method. Luckily it is just a development environment.&lt;/p&gt;
&lt;p&gt;Must be more careful to not repeat the same error again. And there is even a special note regarding exactly the issue I stumbled upon on the knockout download page at http://knockoutjs.com/downloads/: "....&lt;span style="color: #808080; font-family: arial; font-size: 13.0900001525879px; line-height: 17.0170001983643px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080; font-family: arial; font-size: 13.0900001525879px; line-height: 17.0170001983643px;"&gt;Don't use it for normal application development, because it exposes additional unsupported private APIs." &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #808080; font-family: arial; font-size: 13.0900001525879px; line-height: 17.0170001983643px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</description><pubDate>Mon, 16 Mar 2015 21:19:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/looking-for-ko-utils-clonenodes-knockout-debug-vs-release-versions</guid><category>knockoutjs</category></item><item><title>Visual Studio 2008 “Format Document/Selection” command and a function named “assert” in JavaScript code</title><link>https://weblogs.asp.net:443/alexeigorkov/visual-studio-2008-format-document-selection-command-and-a-function-named-assert-in-javascript-code</link><description>&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Just have found some funny behavior of the Visual Studio 2008 editor.&amp;nbsp; Sorry if it is already well known bug.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;If you happened to have a JavaScript function named “assert” in your code (and there is pretty high likelihood in my opinion), for example something like:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; assert(x, message) {
    &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (x) console.log(message);
}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;then when either Format Document (Ctrl + K, Ctrl + D) or Format Selection (Ctrl + K, Ctrl + F) command is applied to the document/block containing the function, the result of the formatting will be:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;functionassert(x, message) {
    &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (x) console.log(message);
}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;That’s it. &lt;STRONG&gt;function&lt;/STRONG&gt; and &lt;STRONG&gt;assert&lt;/STRONG&gt; are now joined into one solid word.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;So be aware of the fact in case you suddenly start receiving&amp;nbsp; strange exception in your JavaScript code: &lt;/FONT&gt;missing ; before statement &lt;A&gt;functionassert(x, message)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;And no, it is not an April Fool's joke. Just try for yourself.&lt;/FONT&gt;&lt;/P&gt;</description><pubDate>Thu, 01 Apr 2010 09:32:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/visual-studio-2008-format-document-selection-command-and-a-function-named-assert-in-javascript-code</guid><category>JavaScript</category><category>Visual Studio</category></item><item><title>jQuery Templates Proposal – dissecting plugin code</title><link>https://weblogs.asp.net:443/alexeigorkov/jquery-templates-proposal-dissecting-plugin-code</link><description>&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As you’ve probably heard, it was announced during the second-day MIX keynote that Microsoft is going to contribute to jQuery project. As a part of the contribution &lt;A href="http://wiki.github.com/nje/jquery/jquery-templates-proposal" target=_blank mce_href="http://wiki.github.com/nje/jquery/jquery-templates-proposal"&gt;templating proposal&lt;/A&gt; was written and experimental &lt;A href="http://github.com/nje/jquery-tmpl" target=_blank mce_href="http://github.com/nje/jquery-tmpl"&gt;plugin&lt;/A&gt; code is already available.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Having spent some time playing with the plugin, I will try in this post to dissect its code and look at how it works internally.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But why would you need to understand how it works in the first place?&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Let me present my own motives (unfortunately I do not have any others): &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;1) Just from pure curiosity. It is a great opportunity to learn at least one templating solution from the ground up while it is simple and extremely small in its infancy. You have a rare ability to have your own pet templating plugin to bring up. Of course it is jQuery and Microsoft teams who will actually feed it, but the pleasure to see it growing and maturing will be all yours. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;2) In my opinion, if you do not understand how some JavaScript framework or tool works - you must be very brave person to use it in any application that &lt;FONT face=geo&gt;has a chance to be released to production some day. And this plugin looks like very promising templating solution to employ.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Convinced? &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Then, just for starters let’s articulate &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;the ultimate goal of the code which we are going to digest. According to the proposal we must be able to define HTML markup on our page interspersed with inline expressions and code blocks using following syntax:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE class=template&gt;    &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;script&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;"template"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;"text/html"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;	    
	&amp;lt;div&amp;gt; 
	    Title: &amp;lt;span &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #a31515"&gt;'title'&lt;/SPAN&gt;&amp;gt;{%= title %}&amp;lt;/span&amp;gt;
    	    &amp;lt;hr /&amp;gt;
		{%= &lt;SPAN style="COLOR: #a31515"&gt;'Pages: '&lt;/SPAN&gt; + pages + &lt;SPAN style="COLOR: #a31515"&gt;'; Year: '&lt;/SPAN&gt; + year %}
	    &amp;lt;div &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #a31515"&gt;'price'&lt;/SPAN&gt;&amp;gt;
		price: {%= price %}
	    &amp;lt;/div&amp;gt;
	    Reviews: 
	    &amp;lt;ul&amp;gt;
		{% &lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; i=0,review; review=reviews[i++];) { %}
		    &amp;lt;li &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #a31515"&gt;'review'&lt;/SPAN&gt;&amp;gt;
			{%= review %}
		    &amp;lt;/li&amp;gt;
		{% } %}
	    &amp;lt;/ul&amp;gt;
	&amp;lt;/div&amp;gt; 
    &lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;script&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;We should be able to bind either single data object or collection (JavaScript array instance) to the template and have it rendered whenever we like in any container we will specify.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;I will use following sample data for the examples shown in this post:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE class=data&gt;    &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; books = [
	  { title: &lt;SPAN style="COLOR: #a31515"&gt;"JavaScript the Bad Parts"&lt;/SPAN&gt;, year: 2010, pages: 1760, price: 77.99,
	      reviews: [&lt;SPAN style="COLOR: #a31515"&gt;"Awesome"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Fantastic"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Always knew there were no good parts"&lt;/SPAN&gt;]
	  },
          { title: &lt;SPAN style="COLOR: #a31515"&gt;"jQuery for plumbers"&lt;/SPAN&gt;, year: 2010, pages: 150, price: 10.75,
              reviews: [&lt;SPAN style="COLOR: #a31515"&gt;"The missing manual I looked for for years"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Many thanks"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"What the ...!?"&lt;/SPAN&gt;]
          },
	  { title: &lt;SPAN style="COLOR: #a31515"&gt;"jQuery Templates 4.0 Reference Guide"&lt;/SPAN&gt;,
	      year: 2012, pages: 1540, price: 40.99, reviews: []
	  }
        ];&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;With the template markup defined and data available we can use following command to render the template and&amp;nbsp; insert generated HTML into the DOM tree:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;jQuery(&lt;SPAN style="COLOR: #a31515"&gt;".container"&lt;/SPAN&gt;).append(&lt;SPAN style="COLOR: #a31515"&gt;"#template"&lt;/SPAN&gt;, books);&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;or as one of the available alternatives:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;jQuery(&lt;SPAN style="COLOR: #a31515"&gt;"#template"&lt;/SPAN&gt;).render(books).appendTo(&lt;SPAN style="COLOR: #a31515"&gt;".container"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;STYLE type=text/css&gt;
.container .title { 
    font-weight: bold;
}

.container ul { margin-top: 0; }
a.render-btn { outline: none; }
&lt;/STYLE&gt;

&lt;P class=render&gt;&lt;FONT size=3 face=Georgia&gt;You can click &lt;A class=render-btn href="javascript:void(0);"&gt;here&lt;/A&gt; to see the results of template rendering.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="DISPLAY: none" class=container mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Now, we are ready to look at the plugin code. It is available at &lt;A href="http://github.com/nje/jquery-tmpl" mce_href="http://github.com/nje/jquery-tmpl"&gt;http://github.com/nje/jquery-tmpl&lt;/A&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Let’s define terminology that will be used throughout the post. I will use the term &lt;EM&gt;jQuery wrapped set&lt;/EM&gt; or just &lt;EM&gt;wrapped set&lt;/EM&gt; to refer to the set of elements selected using jQuery function and upon which we can operate using jQuery commands. Otherwise when &lt;EM&gt;jQuery function&lt;/EM&gt; or &lt;EM&gt;jQuery object&lt;/EM&gt; terms are used – jQuery function itself is meant, that is the object containing static utility methods like jQuery.trim(). Ok? Great.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;I am going to decompose the plugin into smaller distinctive parts to digest them bit by bit. The general outline, on which we will elaborate till the end of the post, looks like the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;(&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;(jQuery) {
	&lt;SPAN style="COLOR: green"&gt;// 1) prepare environment&lt;/SPAN&gt;

	&lt;SPAN style="COLOR: green"&gt;// 2)extend wrapped element set methods&lt;/SPAN&gt;
	jQuery.fn.extend({
		&lt;SPAN style="COLOR: green"&gt;// new/overridden wrapped set methods&lt;/SPAN&gt;
	});

	&lt;SPAN style="COLOR: green"&gt;// 3) extend static utility members&lt;/SPAN&gt;
	jQuery.extend({
		&lt;SPAN style="COLOR: green"&gt;// additional utility members needed&lt;/SPAN&gt;
		&lt;SPAN style="COLOR: green"&gt;// for the templating functionality&lt;/SPAN&gt;
	});
})(jQuery);&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;It is not at all that scary so far. Following jQuery guidelines, plugin implementation is wrapped in anonymous function. The function is executed immediately and its only parameter is the jQuery function itself.&amp;nbsp; The name of the parameter is also jQuery so we do not take advantage of the ability to define custom alias for the jQuery method – one of the purposes with which such anonymous function is usually used:&lt;/FONT&gt; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;(&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; ($) {
    &lt;SPAN style="COLOR: green"&gt;// here we can safely use $ alias in place of jQuery&lt;/SPAN&gt;
})(jQuery);&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But, even without the benefit of a shorter alias, having such function helps us to prevent polluting global namespace with our local variables defined within plugin body. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The code of the function can be separated into three major parts: &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;1) common variables’ declarations; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;2) extending jQuery.fn object (i.e. prototype object for jQuery wrapped element set) with plugin-specific methods; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;3) extending jQuery function itself with static utility members specific to the templating functionality&lt;/FONT&gt;&lt;/P&gt;
&lt;H2&gt;&lt;FONT size=3 face=Georgia&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/H2&gt;
&lt;H2&gt;&lt;FONT size=3 face=Georgia&gt;&lt;STRONG&gt;Prepare environment&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/H2&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The first section, which I designated as "prepare environment", is actually just a declaration of two variables: oldManip and htmlExpr:&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	&lt;SPAN style="COLOR: green"&gt;// Override the DOM manipulation function&lt;/SPAN&gt;
	&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; oldManip = jQuery.fn.domManip,
	htmlExpr = /^[^&amp;lt;]*(&amp;lt;[\w\W]+&amp;gt;)[^&amp;gt;]*$/;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;STRONG&gt;oldManip&lt;/STRONG&gt; variable serves as a backup for original jQuery wrapped set method named domManip(). We will talk about the method later. For now it is sufficient to say that within the plugin implementation the method will be overridden, but we still need to call its original version. So we have to store the reference to the original domManip() implementation in the variable named oldManip.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;STRONG&gt;htmlExpr&lt;/STRONG&gt; variable is a regular expression instance which serves as a test whether the string contains HTML markup or not:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;htmlExpr = /^[^&amp;lt;]*(&amp;lt;[\w\W]+&amp;gt;)[^&amp;gt;]*$/&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Maybe the expression is not entirely bullet proof, but hey, if it is ok for John Resig we will use it without a moment's hesitation.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;These simple steps complete our environment initialization. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Now we can move on to the second section of the template. It is where we are going to extend jQuery wrapped element set with our own methods. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;H2&gt;&lt;FONT size=3 face=Georgia&gt;&lt;STRONG&gt;Extending jQuery wrapped set&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/H2&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The only new method the API introduces named render(). Here we need to clarify what our instance of jQuery wrapped set refers to when the render() method is called. Is it a set of templates or a set of containers where the template will be rendered? That is who is the subject of the render() method? It is an important point and may not be immediately clear.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The syntax defined in the proposal is:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	jQuery(&lt;SPAN style="COLOR: #a31515"&gt;"#template"&lt;/SPAN&gt;).render(data, options);&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;That is, according to the API, it is the template that we are rendering and the wrapped set refers to the set of templates (or, in most cases, just a single one) that we need to render using specified data and options. Later we can add the rendered template to the container were we want the resulting HTML to come to rest.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The render() method is defined as following:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	render: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;( data, options ) {
		&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.map(&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;(i, tmpl){
			&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; jQuery.render( tmpl, data, options );
		});
	},&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;We do not have a chance at this point to dive into internals of the template rendering. It turned out, that all the actual logic is delegated to the new static utility method which is also named render(). But I promise to get to the bottom of it in due course.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;For now, just take into account, that when the set of templates is rendered, each template is passed to the static utility method jQuery.render() along with the given data and options.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;There is another jQuery wrapped set method which is introduced in this section of the plugin. The one we’ve touched briefly earlier. The method is named domManip() and method with such name already exists. In order to understand why we need to override it, we have to understand what its original version does.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The domManip() is a generic helper method which is used internally by several DOM manipulation methods, namely append(), prepend(), before() and after(). Majority of the work these methods need to perform before the DOM tree can actually be modified is the same regardless of the particular DOM action:&lt;/FONT&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;FONT size=3 face=Georgia&gt;Generate document fragment node (nodeType == 11) which will contain all the nodes that should be inserted into the DOM.&lt;/FONT&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;FONT size=3 face=Georgia&gt;Calculate valid container for the fragment. For example if we use append() method to add a &amp;lt;tr /&amp;gt; element to a table, then we have to use &amp;lt;tbody /&amp;gt; element of this table as a container for the row. Also, if we have a set of containers, then we also need to clone the fragment to stamp its content into each and every container of the set. &lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT size=3 face=Georgia&gt;Take care of browsers’ bugs related to cloning the document fragment (ok, it is finally WebKit instead of long-suffering IE which is to blame in this case).&lt;/FONT&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;This chunk of common code is extracted into separate method named domManip(). It takes a callback method as its third parameter to carry out DOM modifications specific to the particular public method of a wrapped set.&amp;nbsp; As always it is easier just to look into the code. For example, the append() method definition looks like the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	append: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;() {
		&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.domManip(arguments, &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;( elem ) {
			&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.nodeType === 1 ) {
				&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.appendChild( elem );
			}
		});
	},&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As you can see, the method internally just calls the domManip() method with anonymous function passed as its third argument. The function is a callback method which domManip() invokes to actually perform required DOM action after the document fragment was generated and proper container for the action selected. In this case the action is as simple as appendChild.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Now we know what domManip() method does. But it still is not clear why we need to override it? The answer is - for the sake of convenience that templating API provides to the end user. The authors of the jQuery templates proposal decided that it may be useful if we could revert the point of view when we want to render the template and start our query not from the template but from the container of the resulting HTML. Thus, if we have a wrapped set of container element(s) and we need to render template somewhere within, before or after the element we can write something like:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;          jQuery(&lt;SPAN style="COLOR: #a31515"&gt;".myContainer"&lt;/SPAN&gt;).append(&lt;SPAN style="COLOR: #a31515"&gt;"#template"&lt;/SPAN&gt;, data, options); &lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Voila. The template specified by “#tempate” selector is appended to&amp;nbsp; the containers specified by “.myConainer” selector using the data and options passed as second and third arguments respectively. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The same is true for the three other methods which consume domManip() internally: prepend(), before() and after().&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;To make this magic happen we need to hook up to the domManip() method and following code does just that:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;    &lt;SPAN style="COLOR: green"&gt;// This will allow us to do: .append( "template", dataObject )&lt;/SPAN&gt;
    domManip: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;( args ) {
	    &lt;SPAN style="COLOR: green"&gt;// This appears to be a bug in the appendTo, etc. implementation&lt;/SPAN&gt;
	    &lt;SPAN style="COLOR: green"&gt;// it should be doing .call() instead of .apply(). See #6227&lt;/SPAN&gt;
	    &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( args.length &amp;gt; 1 &amp;amp;&amp;amp; args[0].nodeType ) {
		    arguments[0] = [ jQuery.makeArray(args) ];
	    }

	    &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( args.length &amp;gt;= 2 &amp;amp;&amp;amp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt; args[0] === &lt;SPAN style="COLOR: #a31515"&gt;"string"&lt;/SPAN&gt; &amp;amp;&amp;amp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt; args[1] !== &lt;SPAN style="COLOR: #a31515"&gt;"string"&lt;/SPAN&gt; ) {
		    arguments[0] = [ jQuery.render( args[0], args[1], args[2] ) ];
	    }
    	
	    &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; oldManip.apply( &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, arguments );
    }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The first three lines of code have no direct relation to the plugin functionality. It just so happened that at the time when the plugin has been written the &lt;A href="http://dev.jquery.com/ticket/6227" target=_blank mce_href="http://dev.jquery.com/ticket/6227"&gt;bug&lt;/A&gt; which affects domManip() method was discovered and fixed.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;These three lines of code in our new domManip() method is just a temporary patch for the bug which is already fixed in jQuery repository.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;If you are curious, what bug the code fixes, then we need to look at the definition of the following set of jQuery commands: appendTo, prependTo, insertBefore, insertAfter. They are all defined using exactly the same code (parameterized using method name) mapped to the so called “original” methods. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Just look at the following mappings:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;{
	appendTo: &lt;SPAN style="COLOR: #a31515"&gt;"append"&lt;/SPAN&gt;,
	prependTo: &lt;SPAN style="COLOR: #a31515"&gt;"prepend"&lt;/SPAN&gt;,
	insertBefore: &lt;SPAN style="COLOR: #a31515"&gt;"before"&lt;/SPAN&gt;,
	insertAfter: &lt;SPAN style="COLOR: #a31515"&gt;"after"&lt;/SPAN&gt;,
	replaceAll: &lt;SPAN style="COLOR: #a31515"&gt;"replaceWith"&lt;/SPAN&gt;
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;“Oiginal” methods’ names (in terms of the code) are values of the properties. When, for example, appendTo() method is called, some intermediate code just replaces the subject of the action with the object of the action (the wrapped set which should be appended with the the wrapped set which is appended to) and then the original method (append() in this case) is invoked.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;That is instead of &lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;jQuery(&lt;SPAN style="COLOR: #a31515"&gt;".myElements"&lt;/SPAN&gt;).appendTo(&lt;SPAN style="COLOR: #a31515"&gt;".myContainer"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;we will have&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;jQuery(&lt;SPAN style="COLOR: #a31515"&gt;".myContainer"&lt;/SPAN&gt;).append(jQuery(&lt;SPAN style="COLOR: #a31515"&gt;".myElements"&lt;/SPAN&gt;));&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Isn’t it clever? Without writing a single line of code we can introduce a whole bunch of new methods. Ok, it is not entirely true. There actually are several lines of code to wrap this functionality. One of them, the one that performs the call looks like the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;jQuery.fn[ original ].apply( jQuery(insert[i]), elems );&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;And it is where the bug was hidden. Since the apply() method is used here, the array of elements passed as a parameter to the original method will be scattered across separate arguments . That is the append() method, for example, will be called as&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;append(elem1, elem2, elem3, …, elemN)&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;while it should be &lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;append([elem1, elem2, elem3, …, elemN]);&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;To fix the issue, the first three lines of the overridden domManip() method just gather all the scattered arguments back into one array wrapped in another array:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;    &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( args.length &amp;gt; 1 &amp;amp;&amp;amp; args[0].nodeType ) {
	    arguments[0] = [ jQuery.makeArray(args) ];
    }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The outer array is needed because at the end of the new domManip() method, the array is consumed by apply() method once the original version of domManip() is called:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; oldManip.apply( &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, arguments );&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But, as I said, this fix does not have any relation to the code of the plugin. &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;Just wanted to&amp;nbsp; ensure that you understand the mechanics under the hood (even if it is just a bug fix).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Now, eventually, lets concentrate on the code within the domManip() which enables templating API:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( args.length &amp;gt;= 2 &amp;amp;&amp;amp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt; args[0] === &lt;SPAN style="COLOR: #a31515"&gt;"string"&lt;/SPAN&gt; &amp;amp;&amp;amp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt; args[1] !== &lt;SPAN style="COLOR: #a31515"&gt;"string"&lt;/SPAN&gt; ) {
    arguments[0] = [ jQuery.render( args[0], args[1], args[2] ) ];
}&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As you can see it is really straightforward. Since the domManip() receives all the arguments passed to one of the methods in question (append, prepend, before or after), then we can deduce that template rendering was intended by the number of the arguments (&amp;gt;=2) and their respective types. The first one should be either selector or HTML template string, and the second one must be a data object -&lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt; array or object but definitely not a string.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Once again, as in the code of the instance render() method for a wrapped set, we see that the template rendering is performed using static utility method of jQuery function:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;arguments[0] = [ jQuery.render( args[0], args[1], args[2] ) ];&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;and then, as I showed earlier, original version of oldManip() is called which now receives already rendered template:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; oldManip.apply( &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, arguments );&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;That’s all for the second part of our journey through the plugin code.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;I hope you are not tired yet, since now begins the part of the template that actually does something. And it is the joy of analyzing this part I wanted to share with you when started writing this post.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;STRONG&gt;Extending jQuery function&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Since this section of the code is relatively verbose (though still under 150 lines) we are going to dissect it the same way we did for the code of the entire plugin:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	jQuery.extend({
		render: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;( tmpl, data, options ) {
			&lt;SPAN style="COLOR: green"&gt;// instantiate template if it does not exist&lt;/SPAN&gt;
			&lt;SPAN style="COLOR: green"&gt;// and render it&lt;/SPAN&gt;
		},
		
		&lt;SPAN style="COLOR: green"&gt;// pre-built template functions' cache&lt;/SPAN&gt;
		templates: {},

		&lt;SPAN style="COLOR: green"&gt;// helper methods for template rendering &lt;/SPAN&gt;
		tmplFn: {
			html: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;() { &lt;SPAN style="COLOR: green"&gt;/* ... */&lt;/SPAN&gt; },
			text: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;() { &lt;SPAN style="COLOR: green"&gt;/* ... */&lt;/SPAN&gt; },
		},

		_: &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, &lt;SPAN style="COLOR: green"&gt;// string builder &lt;/SPAN&gt;
		
		&lt;SPAN style="COLOR: green"&gt;// generate template function&lt;/SPAN&gt;
		tmpl: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; tmpl(str, data, i, options) {
			&lt;SPAN style="COLOR: green"&gt;// ...&lt;/SPAN&gt;
		}
	});&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;First, let’s define what “template” and “rendering” terms mean when used in the code and comments. If you still remember, our goal is to parse HTML markup that represents our template. The result of the parsing should be suitable for data binding. It would be better if we could reuse the template later without overhead of parsing initial HTML markup of the template again and again.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The template solves this task by generating (we will also use terms “compiling” or “building”) JavaScript function&amp;nbsp; from the provided HTML markup. The function takes jQuery method and &lt;STRONG&gt;context&lt;/STRONG&gt; object as its parameters and returns an array of DOM elements.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The &lt;A href="http://wiki.github.com/nje/jquery/jquery-templates-proposal#context" target=_blank mce_href="http://wiki.github.com/nje/jquery/jquery-templates-proposal#context"&gt;context&lt;/A&gt; object has the following properties: data, dataItem, index and options: &lt;STRONG&gt;data&lt;/STRONG&gt; is just that – data passed to the template rendering function; &lt;STRONG&gt;dataItem&lt;/STRONG&gt; –&amp;nbsp; item of the data collection which is currently being rendered; &lt;STRONG&gt;index&lt;/STRONG&gt; – the index of the current data item; &lt;STRONG&gt;options&lt;/STRONG&gt; – object containing custom parameters passed to the template. By default two events can be specified using the &lt;STRONG&gt;options&lt;/STRONG&gt; object: &lt;STRONG&gt;rendering&lt;/STRONG&gt; and &lt;STRONG&gt;rendered&lt;/STRONG&gt;. We will look at the code that makes this happen later. For now it is important to note that data object can be either an array or a single object. In case single object is passed to the template rendering function, then &lt;STRONG&gt;data&lt;/STRONG&gt; and &lt;STRONG&gt;dataItem&lt;/STRONG&gt; properties of the context will reference the same object. &lt;STRONG&gt;index&lt;/STRONG&gt; property in this case contains 0.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Plugin extends jQuery function with utility method named &lt;STRONG&gt;tmpl()&lt;/STRONG&gt; for the purpose of generating reusable function (pre-built template). The code of the function is shown below:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;    tmpl: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; tmpl(str, data, i, options) {
	    &lt;SPAN style="COLOR: green"&gt;// Generate a reusable function that will serve as a template&lt;/SPAN&gt;
	    &lt;SPAN style="COLOR: green"&gt;// generator (and which will be cached).&lt;/SPAN&gt;

	    &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fn = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; Function(&lt;SPAN style="COLOR: #a31515"&gt;"jQuery"&lt;/SPAN&gt;,&lt;SPAN style="COLOR: #a31515"&gt;"$context"&lt;/SPAN&gt;,
		    &lt;SPAN style="COLOR: #a31515"&gt;"var $=jQuery,$data=$context.dataItem,$i=$context.index,_=$._=[];_.context=$context;"&lt;/SPAN&gt; +

		    &lt;SPAN style="COLOR: green"&gt;// Introduce the data as local variables using with(){}&lt;/SPAN&gt;
		    &lt;SPAN style="COLOR: #a31515"&gt;"with($.tmplFn){with($data){_.push('"&lt;/SPAN&gt; +

		    &lt;SPAN style="COLOR: green"&gt;// Convert the template into pure JavaScript&lt;/SPAN&gt;
		    str.replace(/[\r\t\n]/g, &lt;SPAN style="COLOR: #a31515"&gt;" "&lt;/SPAN&gt;)
			    &lt;SPAN style="COLOR: green"&gt;// protect single quotes that are within expressions&lt;/SPAN&gt;
			    .replace(/'(?=[^%]*%})/g,&lt;SPAN style="COLOR: #a31515"&gt;"\t"&lt;/SPAN&gt;)
			    &lt;SPAN style="COLOR: green"&gt;// escape other single quotes&lt;/SPAN&gt;
			    .split(&lt;SPAN style="COLOR: #a31515"&gt;"'"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"\\'"&lt;/SPAN&gt;)
			    &lt;SPAN style="COLOR: green"&gt;// put back protected quotes&lt;/SPAN&gt;
			    .split(&lt;SPAN style="COLOR: #a31515"&gt;"\t"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"'"&lt;/SPAN&gt;)
			    &lt;SPAN style="COLOR: green"&gt;// convert inline expressions into inline parameters&lt;/SPAN&gt;
			    .replace(/{%=(.+?)%}/g, &lt;SPAN style="COLOR: #a31515"&gt;"',($1),'"&lt;/SPAN&gt;)
			    &lt;SPAN style="COLOR: green"&gt;// convert start of code blocks into end of push()&lt;/SPAN&gt;
			    .split(&lt;SPAN style="COLOR: #a31515"&gt;"{%"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"');"&lt;/SPAN&gt;)
			    &lt;SPAN style="COLOR: green"&gt;// and end of code blocks into start of push()&lt;/SPAN&gt;
			    .split(&lt;SPAN style="COLOR: #a31515"&gt;"%}"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"_.push('"&lt;/SPAN&gt;)

		    + &lt;SPAN style="COLOR: #a31515"&gt;"');}}return $(_.join('')).get();"&lt;/SPAN&gt;);

	    &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; data ? fn( jQuery, { data: &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, dataItem: data, index: i, options: options } ) : fn;
    }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Are you scared? You should not be. All we need is to debug the method using the example template and data presented at the beginning of the post.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As you can see, the method creates JavaScript function by means of Function() constructor. When the tmpl() method is called, its first argument contains string with HTML markup. All the other arguments are provided for “currying”. If you are not familiar with the term then &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;do not worry, we will talk about it later.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Now we are interested only in the first parameter – &lt;STRONG&gt;str&lt;/STRONG&gt; which contains markup of the template and&lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt; is used to compose the body of the compiled template (anonymous function).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;To begin with, let’s see how the function would look without any markup specified:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fn = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; Function(&lt;SPAN style="COLOR: #a31515"&gt;"jQuery"&lt;/SPAN&gt;,&lt;SPAN style="COLOR: #a31515"&gt;"$context"&lt;/SPAN&gt;,
		&lt;SPAN style="COLOR: #a31515"&gt;"var $=jQuery,$data=$context.dataItem,$i=$context.index,_=$._=[];_.context=$context;"&lt;/SPAN&gt; +
		&lt;SPAN style="COLOR: green"&gt;// Introduce the data as local variables using with(){}&lt;/SPAN&gt;
		&lt;SPAN style="COLOR: #a31515"&gt;"with($.tmplFn){with($data){_.push('"&lt;/SPAN&gt; +
			&lt;SPAN style="COLOR: green"&gt;/// parsed markup goes here ...&lt;/SPAN&gt;
		&lt;SPAN style="COLOR: #a31515"&gt;"');}}return $(_.join('')).get();"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;It is not particularly intuitive, but the code actually results in the following simple function definition:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fn = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;(jQuery, $context) {
				&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; $ = jQuery, 
					$data = $context.dataItem,
					$i = $context.index,
					_ = $._ =[]; 
					_.context = $context;
				
				&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($.tmplFn) { 
					&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($data) {
						_.push(&lt;SPAN style="COLOR: #a31515"&gt;''&lt;/SPAN&gt;);
					}
				}
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; $(_.join(&lt;SPAN style="COLOR: #a31515"&gt;''&lt;/SPAN&gt;)).get();
			}&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Much better, and nobody is frightened. But several comments are still necessary. The function takes jQuery and &lt;STRONG&gt;context&lt;/STRONG&gt; objects as its parameters. jQuery is stored in variable $. &lt;STRONG&gt;context&lt;/STRONG&gt; object properties are distributed into variables $data and $i. Another important variable is the one named _ (underscore). It is initialized with an instance of array and copied to the property of jQuery object of the same name _(underscore). It is this array that will accumulate parts of HTML markup we are about to parse.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The second important part of the method is the two successive &lt;STRONG&gt;with&lt;/STRONG&gt; statements. As a result of these statements objects jQuery.tmplFn and $data are added to the front of the scope chain and, since identifiers are resolved against the scope chain, we can address the members of jQuery.tmplFn and $data objects as if they were just local variables.&amp;nbsp; If, for example, our data item had property named &lt;STRONG&gt;title&lt;/STRONG&gt; then we could simply write:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;				&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($.tmplFn) { 
					&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($data) {
						html(title);
					}
				}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;html() method is defined on jQuery.tmplFn object which is also on the scope chain.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;If you are still with me, my congratulations, since we’ve approached the culmination of our research and going to decipher how it is possible to get reusable templating function from HTML string.&amp;nbsp; We’ve just learned that parts of the resulting template will be stored in the array named _ (underscore). Let’s track how it is being filled. &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;This part of code (with comments removed for brevity) is shown below:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;				str.replace(/[\r\t\n]/g, &lt;SPAN style="COLOR: #a31515"&gt;" "&lt;/SPAN&gt;)
					.replace(/'(?=[^%]*%})/g, &lt;SPAN style="COLOR: #a31515"&gt;"\t"&lt;/SPAN&gt;)
					.split(&lt;SPAN style="COLOR: #a31515"&gt;"'"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"\\'"&lt;/SPAN&gt;)
					.split(&lt;SPAN style="COLOR: #a31515"&gt;"\t"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"'"&lt;/SPAN&gt;)
					.replace(/{%=(.+?)%}/g, &lt;SPAN style="COLOR: #a31515"&gt;"',($1),'"&lt;/SPAN&gt;)
					.split(&lt;SPAN style="COLOR: #a31515"&gt;"{%"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"');"&lt;/SPAN&gt;)
					.split(&lt;SPAN style="COLOR: #a31515"&gt;"%}"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"_.push('"&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;We are going to replace HTML string &lt;STRONG&gt;str&lt;/STRONG&gt; with a sequence of _.push() calls. What is actually pushed in the array depends on the type of the markup we are dealing with. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;a) If it is plain HTML markup, then we just take the text as is, enclosed within single quotes, and put it into the array. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;b) If it is an inline expression marked with {%= %} characters, then we take the content of the expression as is – it is not a string any more, but executable code that should result in some HTML markup.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;c) If it is a code block delimited with {% %} characters, then we do not push anything explicitly. We just finish previous push() call and start another. It is the code within the code block which will decide whether it needs something to be rendered in this part of the template or not. It can contain inner inline expression or call helper methods (text() or html()) explicitly to modify content of the templating array being built.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;I know, it is not very clear so far, but once you see the algorithm in action you’ll get it at once (or slightly later).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Several preparatory tasks are needed though. First we are going to replace each of the following special characters&amp;nbsp; \r\t\n with spaces. They are insignificant, besides, we will use the \t character later for our own needs. This replacement&amp;nbsp; is what the first line of the code does.&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	str.replace(/[\r\t\n]/g, &lt;SPAN style="COLOR: #a31515"&gt;" "&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;And then, &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;since we chose single quotes to delimit our string literals, we need to escape single quotes that may be present within our markup. There is just one subtlety. If the single quote is within inline expression or code block, it does not deserve any special treatment and should be left unescaped. To do this, we perform following sequence of steps:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;1) Replace all single quotes that happen to be within inline expression or code blocks with \t character;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;2) Escape all outstanding single quotes;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;3) Get those single quotes within expressions back – replace \t with quote&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As you can see, these preparatory steps occupy more than a half of the entire replacement sequence:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;				str.replace(/[\r\t\n]/g, &lt;SPAN style="COLOR: #a31515"&gt;" "&lt;/SPAN&gt;)
					.replace(/'(?=[^%]*%})/g, &lt;SPAN style="COLOR: #a31515"&gt;"\t"&lt;/SPAN&gt;)
					.split(&lt;SPAN style="COLOR: #a31515"&gt;"'"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"\\'"&lt;/SPAN&gt;)
					.split(&lt;SPAN style="COLOR: #a31515"&gt;"\t"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"'"&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But wait, at this point you may be wondering why I am talking about replacements and escaping while there are actually just strange chain of split() and join() calls? No? Great! Because I assume that your knowledge of JavaScript is sufficient to understand that using split() + join() sequentially we’ll get an equivalent of replace() method when it used with static content (string literal) as a pattern to replace. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But it is still valid question why in the same block of code we use replace() in some cases and split()/join() in others. See below the answer provided by the author of the code (John Resig):&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P style="MARGIN-LEFT: 20px"&gt;&lt;FONT size=3 face=Georgia&gt;"... If you're searching and replacing through a string with a static search and a static replace it's faster to perform the action with &lt;CODE&gt;.split("match").join("replace")&lt;/CODE&gt; - which seems counter-intuitive but it manages to work that way in most modern browsers. (There are changes going in place to grossly improve the performance of &lt;CODE&gt;.replace(/match/g, "replace")&lt;/CODE&gt; in the next version of Firefox - so the previous statement won't be the case for long.)"&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;You can find this answer in the following post: &lt;A href="http://ejohn.org/blog/javascript-micro-templating/" mce_href="http://ejohn.org/blog/javascript-micro-templating/"&gt;http://ejohn.org/blog/javascript-micro-templating/&lt;/A&gt;. If you read through the post you can also find out where the actual roots of this “experimental plugin” are concealed (surprise, surprise).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But back to our code. &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;As always it all becomes clearer with one simple example. Let’s use the first thee lines of the HTML template presented at the beginning of the post:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	    title: &amp;lt;span &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #a31515"&gt;'title'&lt;/SPAN&gt;&amp;gt;{%= title %}&amp;lt;/span&amp;gt;
    	    &amp;lt;hr /&amp;gt;
		{%= &lt;SPAN style="COLOR: #a31515"&gt;'pages: '&lt;/SPAN&gt; + pages + &lt;SPAN style="COLOR: #a31515"&gt;'; year:'&lt;/SPAN&gt; + year %}
&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;and execute the lines of code we already understand using this template. The resulting string is &lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #a31515"&gt;Title: &amp;lt;span class=\'title\'&amp;gt;{%= title %}&amp;lt;/span&amp;gt;           &amp;lt;hr /&amp;gt;    {%= 'Pages: ' + pages + '; Year:' + year %}&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;No magic so far. We now have a string with some single quotes escaped and some (the ones within expressions) left as is. But we are ready for the real things and can take care of the inline expressions:&lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;PRE&gt;					.replace(/{%=(.+?)%}/g, &lt;SPAN style="COLOR: #a31515"&gt;"',($1),'"&lt;/SPAN&gt;)&lt;/PRE&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As a result of this additional replacement, our sample string starts resembling JavaScript code that we can push in array:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #a31515"&gt;'Title: &amp;lt;span class=\'&lt;/SPAN&gt;title\&lt;SPAN style="COLOR: #a31515"&gt;'&amp;gt;'&lt;/SPAN&gt;,( title ),&lt;SPAN style="COLOR: #a31515"&gt;'&amp;lt;/span&amp;gt;           &amp;lt;hr /&amp;gt;    '&lt;/SPAN&gt;,( &lt;SPAN style="COLOR: #a31515"&gt;'Pages: '&lt;/SPAN&gt; + pages + &lt;SPAN style="COLOR: #a31515"&gt;'; Year:'&lt;/SPAN&gt; + year ),&lt;SPAN style="COLOR: #a31515"&gt;'  '&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;and if we combine it with the rest of the code of our compiled template the result will be:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fn = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;(jQuery, $context) {
				&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; $ = jQuery, 
					$data = $context.dataItem,
					$i = $context.index,
					_ = $._ =[]; 
					_.context = $context;
				
				&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($.tmplFn) { 
					&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($data) {
						_.push(&lt;SPAN style="COLOR: #a31515"&gt;'Title: &amp;lt;span class=\'&lt;/SPAN&gt;title\&lt;SPAN style="COLOR: #a31515"&gt;'&amp;gt;'&lt;/SPAN&gt;,
						( title ),
						&lt;SPAN style="COLOR: #a31515"&gt;'&amp;lt;/span&amp;gt;           &amp;lt;hr /&amp;gt;    '&lt;/SPAN&gt;,
						( &lt;SPAN style="COLOR: #a31515"&gt;'Pages: '&lt;/SPAN&gt; + pages + &lt;SPAN style="COLOR: #a31515"&gt;'; Year:'&lt;/SPAN&gt; + year ),
						&lt;SPAN style="COLOR: #a31515"&gt;'  '&lt;/SPAN&gt;);
					}
				}
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; $(_.join(&lt;SPAN style="COLOR: #a31515"&gt;''&lt;/SPAN&gt;)).get();
			}&lt;/PRE&gt;&lt;/DIV&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;It makes sense in the end. HTML markup is stored in the array as is, and expressions are calculated using properties of our data item and also pushed into the array.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The last step in the process of generating our pre-built templating function is to deal with code blocks delimited by {% %} characters. It is the last two replacement patterns that achieve the goal:&lt;/FONT&gt;&lt;/P&gt;&lt;PRE&gt;					.split(&lt;SPAN style="COLOR: #a31515"&gt;"{%"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"');"&lt;/SPAN&gt;)
					.split(&lt;SPAN style="COLOR: #a31515"&gt;"%}"&lt;/SPAN&gt;).join(&lt;SPAN style="COLOR: #a31515"&gt;"_.push('"&lt;/SPAN&gt;)&lt;/PRE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The code first closes previous push() statement using "');" sequence once the opening characters of the code block {%&amp;nbsp; are encountered. We always have this previous push() statement in place even if the template begins with the code block. It is because the first push() is hardcoded in the function body right after the inner &lt;STRONG&gt;with&lt;/STRONG&gt; statment:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #a31515"&gt;"with($.tmplFn){with($data){_.push('"&lt;/SPAN&gt; +&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;And then we start another push statement using&amp;nbsp; "_.push('" sequence when closing characters of the code block %} are encountered. Again, we do not need to worry that some push() statement might stay open since our template generation code closes the last push() explicitly: &lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;+ &lt;SPAN style="COLOR: #a31515"&gt;"');}}return $(_.join('')).get();"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Because the whole generation code is now revealed, we are ready to process the entire template with it. If you remember, our original version of the template was:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;    &amp;lt;script id=&lt;SPAN style="COLOR: #a31515"&gt;"template"&lt;/SPAN&gt; type=&lt;SPAN style="COLOR: #a31515"&gt;"text/html"&lt;/SPAN&gt;&amp;gt;	    
	&amp;lt;div&amp;gt; 
	    Title: &amp;lt;span &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #a31515"&gt;'title'&lt;/SPAN&gt;&amp;gt;{%= title %}&amp;lt;/span&amp;gt;
    	    &amp;lt;hr /&amp;gt;
		{%= &lt;SPAN style="COLOR: #a31515"&gt;'Pages: '&lt;/SPAN&gt; + pages + &lt;SPAN style="COLOR: #a31515"&gt;'; Year:'&lt;/SPAN&gt; + year %}
	    &amp;lt;div &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #a31515"&gt;'price'&lt;/SPAN&gt;&amp;gt;
		price: {%= price %}
	    &amp;lt;/div&amp;gt;
	    Reviews: 
	    &amp;lt;ul&amp;gt;
		{% &lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; i=0,review; review=reviews[i++];) { %}
		    &amp;lt;li &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #a31515"&gt;'review'&lt;/SPAN&gt;&amp;gt;
			{%= review %}
		    &amp;lt;/li&amp;gt;
		{% } %}
	    &amp;lt;/ul&amp;gt;
	&amp;lt;/div&amp;gt; 
    &amp;lt;/script&amp;gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;It contains HTML markup, inline expressions and code blocks. As a result of compiling this template we will have pre-built template rendering function ready to use:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;    &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fn = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;(jQuery, $context) {
		    &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; $ = jQuery, 
			    $data = $context.dataItem,
			    $i = $context.index,
			    _ = $._ =[]; 
			    _.context = $context;
		    
		    &lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($.tmplFn) { 
			    &lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($data) {
				    &lt;SPAN style="COLOR: #a31515"&gt;'_.push('&lt;/SPAN&gt;          &amp;lt;div&amp;gt;        Title: &amp;lt;span &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;=\&lt;SPAN style="COLOR: #a31515"&gt;'title\'&lt;/SPAN&gt;&amp;gt;',
				    ( title ),
				    &lt;SPAN style="COLOR: #a31515"&gt;'&amp;lt;/span&amp;gt;           &amp;lt;hr /&amp;gt;    '&lt;/SPAN&gt;,
				    ( &lt;SPAN style="COLOR: #a31515"&gt;'Pages: '&lt;/SPAN&gt; + pages + &lt;SPAN style="COLOR: #a31515"&gt;'; Year:'&lt;/SPAN&gt; + year ),
				    &lt;SPAN style="COLOR: #a31515"&gt;'       &amp;lt;div class=\'&lt;/SPAN&gt;price\&lt;SPAN style="COLOR: #a31515"&gt;'&amp;gt;    Price: '&lt;/SPAN&gt;,
				    ( price ),
				    &lt;SPAN style="COLOR: #a31515"&gt;'       &amp;lt;/div&amp;gt;       Reviews:        &amp;lt;ul&amp;gt;    '&lt;/SPAN&gt;); 
				    
					&lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; i=0,review; review=reviews[i++];) { 
					    _.push(&lt;SPAN style="COLOR: #a31515"&gt;'        &amp;lt;li class=\'&lt;/SPAN&gt;review\&lt;SPAN style="COLOR: #a31515"&gt;'&amp;gt;     '&lt;/SPAN&gt;,
					    ( review ),
					    &lt;SPAN style="COLOR: #a31515"&gt;'        &amp;lt;/li&amp;gt;    '&lt;/SPAN&gt;); 
				       } 
				    _.push(&lt;SPAN style="COLOR: #a31515"&gt;'       &amp;lt;/ul&amp;gt;   &amp;lt;/div&amp;gt;       '&lt;/SPAN&gt;);
			    }
		    }
		    &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; $(_.join(&lt;SPAN style="COLOR: #a31515"&gt;''&lt;/SPAN&gt;)).get();
	    }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Isn’t it beautiful?! &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But we still have the last line of our tmpl() function to talk about. It is where the term “currying” comes into existence:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;            &lt;SPAN style="COLOR: green"&gt;// Provide some basic currying to the user&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; data ? fn(jQuery, { data: &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, dataItem: data, index: i, options: options }) : fn;	    &lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As you can see, the tmpl() function can either return the generated template function, or - in case data parameter is provided - the result of the template function execution using the following context object:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;{ data: &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, dataItem: data, index: i, options: options }&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The comment for the line states that the code provides “…some basic currying to the user”.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The term “currying”&amp;nbsp; basically means that we want to bind some arguments to a function and have a new function as a result which we can call later. The technique is achieved using closures. &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;If you’ve ever used Function.prototype.bind() method of the prototype.js framework with more than one arguments applied, then you should know what I am talking about. Otherwise I will be better off to refer to the best minds of Generation JavaScript. Please use the source you are more comfortable with:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://ejohn.org/blog/partial-functions-in-javascript/" mce_href="http://ejohn.org/blog/partial-functions-in-javascript/"&gt;&lt;FONT size=3 face=Georgia&gt;http://ejohn.org/blog/partial-functions-in-javascript/&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.dustindiaz.com/javascript-curry/" mce_href="http://www.dustindiaz.com/javascript-curry/"&gt;&lt;FONT size=3 face=Georgia&gt;http://www.dustindiaz.com/javascript-curry/&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yuiblog.com/assets/pdf/zakas-projs-2ed-ch18.pdf" mce_href="http://yuiblog.com/assets/pdf/zakas-projs-2ed-ch18.pdf"&gt;&lt;FONT size=3 face=Georgia&gt;http://yuiblog.com/assets/pdf/zakas-projs-2ed-ch18.pdf&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Frankly speaking this last line of tmpl() method code is not entirely clear to me. The reason for my doubts is that we do not actually have partially applied (curried) function in case these additional arguments are provided. We have the &lt;STRONG&gt;result &lt;/STRONG&gt;of the function execution returned – the set of DOM elements. Such behavior – different &lt;STRONG&gt;types&lt;/STRONG&gt; of results returned from the same method does not look accurate to me. But maybe I just did not get the higher motives of the code.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Now you should have complete understanding of how the heart of the jQuery templating plugin operates. I can only add that the best way to play with the template generation procedure is to feed different HTML templates to the jQuery.tmpl() function using Firebug console. Just start with something as simple as&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;jQuery.tmpl(&lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;div&amp;gt;{%=title%}&amp;lt;/div&amp;gt;"&lt;/SPAN&gt;).toString()&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;and, thanks to the toString() method, you’ll get complete picture of what your compiled template really is.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The last part of our journey will not require any additional mental efforts from your side. We have only one static utility method of jQuery function to talk about: jQuery.render(). On the other hand, it is the most important method from the API point of view. The code of the method is shown below:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;		render: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;( tmpl, data, options ) {
			&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fn, node;
 
			&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt; tmpl === &lt;SPAN style="COLOR: #a31515"&gt;"string"&lt;/SPAN&gt; ) {
				&lt;SPAN style="COLOR: green"&gt;// Use a pre-defined template, if available&lt;/SPAN&gt;
				fn = jQuery.templates[ tmpl ];
				&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( !fn &amp;amp;&amp;amp; !htmlExpr.test( tmpl ) ) {
					&lt;SPAN style="COLOR: green"&gt;// it is a selector&lt;/SPAN&gt;
					node = jQuery( tmpl ).get( 0 );
				}
			} &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( tmpl &lt;SPAN style="COLOR: blue"&gt;instanceof&lt;/SPAN&gt; jQuery ) {
				node = tmpl.get( 0 );
			} &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( tmpl.nodeType ) {
				node = tmpl;
			}
 
			&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( !fn &amp;amp;&amp;amp; node ) {
				&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; elemData = jQuery.data( node );
				fn = elemData.tmpl || (elemData.tmpl = jQuery.tmpl( node.innerHTML ));
			}
 
			&lt;SPAN style="COLOR: green"&gt;// We assume that if the template string is being passed directly&lt;/SPAN&gt;
			&lt;SPAN style="COLOR: green"&gt;// in the user doesn't want it cached. They can stick it in&lt;/SPAN&gt;
			&lt;SPAN style="COLOR: green"&gt;// jQuery.templates to cache it.&lt;/SPAN&gt;
 
			fn = fn || jQuery.tmpl( tmpl );
 
			&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; rendering,
				rendered,
				context = {
					data: data,
					index: 0,
					dataItem: data,
					options: options || {}
				};
			&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( options ) {
				rendering = options.rendering;
				rendered = options.rendered;
			}
 
			&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; renderItem() {
				&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; dom = &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;;
				&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( !rendering || rendering( context ) !== &lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;) {
					&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; dom = fn( jQuery, context );
					&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( rendered ) 
						rendered( context, dom );
				}
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; dom;
			}
 
			&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( jQuery.isArray( data ) ) {
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; jQuery.map( data, &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;( data, i ) {
					context.index = i;
					context.dataItem = data;
					&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; renderItem( );
				});
 
			} &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; {
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; renderItem( );
			}
		}&lt;/PRE&gt;&lt;/DIV&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The first part of the code handles various possible types of the &lt;STRONG&gt;tmpl&lt;/STRONG&gt; parameter:&lt;/FONT&gt;&lt;/P&gt;&lt;PRE&gt;			&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt; tmpl === &lt;SPAN style="COLOR: #a31515"&gt;"string"&lt;/SPAN&gt; ) {
				&lt;SPAN style="COLOR: green"&gt;// Use a pre-defined template, if available&lt;/SPAN&gt;
				fn = jQuery.templates[ tmpl ];
				&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( !fn &amp;amp;&amp;amp; !htmlExpr.test( tmpl ) ) {
					&lt;SPAN style="COLOR: green"&gt;// it is a selector&lt;/SPAN&gt;
					node = jQuery( tmpl ).get( 0 );
				}
			} &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( tmpl &lt;SPAN style="COLOR: blue"&gt;instanceof&lt;/SPAN&gt; jQuery ) {
				node = tmpl.get( 0 );
			} &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( tmpl.nodeType ) {
				node = tmpl;
			}&lt;/PRE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;This parameter can be interpreted in several different ways. If the argument is of string type, then we first assume that it is a key for the templates’ cache that can be found in new static member of jQuery object -&amp;nbsp; jQuery.templates. You can manually precompile a template and cache it using&amp;nbsp; jQuery.template property for future use:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;jQuery.templates[&lt;SPAN style="COLOR: #a31515"&gt;"books"&lt;/SPAN&gt;] = jQuery.tmpl(jQuery(&lt;SPAN style="COLOR: #a31515"&gt;"#template"&lt;/SPAN&gt;).html());&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Now the template “books” can be consumed by jQuery.render() method like this:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;jQuery(&lt;SPAN style="COLOR: #a31515"&gt;".titles"&lt;/SPAN&gt;).append(jQuery.render(&lt;SPAN style="COLOR: #a31515"&gt;"books"&lt;/SPAN&gt;, books))&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But let’s return to jQuery.render() method code. If &lt;STRONG&gt;tmpl&lt;/STRONG&gt; argument is a string and jQuery.template object does not contain the property of the same name then &lt;STRONG&gt;htmlExpr&lt;/STRONG&gt; regular expression is used to check whether the string contains HTML markup or not. If no traces of HTML is detected within the string then the string must contain valid selector which points to the node containing desired template markup:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;node = jQuery( tmpl ).get( 0 );&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;If &lt;STRONG&gt;tmpl&lt;/STRONG&gt; argument is not a string then we need to check whether it is an instance of jQuery wrapped element set. In such a case we just get the first element of the set as a potential container of the HTML markup:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;node = tmpl.get( 0 );&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Otherwise we check if &lt;STRONG&gt;tmpl&lt;/STRONG&gt; references DOM element or not. If so, then again, it must be the required template container:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;    } &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( tmpl.nodeType ) {
	    node = tmpl;
    }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;In case precompiled template was not found within jQuery.templates cache and we succeeded in interpreting &lt;STRONG&gt;tmpl&lt;/STRONG&gt; argument as a DOM node we will try to build and cache the template using following code:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;    &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( !fn &amp;amp;&amp;amp; node ) {
	    &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; elemData = jQuery.data( node );
	    fn = elemData.tmpl || (elemData.tmpl = jQuery.tmpl( node.innerHTML ));
    }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Here the code retrieves data storage object associated with the given DOM element. If the storage already contains precompiled template (&lt;STRONG&gt;tmpl&lt;/STRONG&gt; property of the data object), then this precompiled template will be used. Otherwise we generate the templating function by means of jQuery.tmpl() method using inner HTML of the template container node. In the latter case the generated template is cached in &lt;STRONG&gt;tmpl&lt;/STRONG&gt; property of the data storage object associated with the DOM element for future use.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;But there is still one missing case when &lt;STRONG&gt;tmpl&lt;/STRONG&gt; argument passed to jQuery.render() method is a string, but it does contain HTML markup directly. The case is handled by the following line of code:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;		fn = fn || jQuery.tmpl( tmpl );&lt;/PRE&gt;&lt;/DIV&gt;&lt;FONT size=3 face=Georgia&gt;The template is compiled from the HTML markup using jQuery.tmpl() method. In this case we do not cache the generated templating function since, according to comments, we assume that user does not want it cached.&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The rest of the code is used to prepare &lt;STRONG&gt;context&lt;/STRONG&gt; object, populate &lt;STRONG&gt;rendering&lt;/STRONG&gt; and &lt;STRONG&gt;rendered&lt;/STRONG&gt; variables with handler functions that can be supplied using &lt;STRONG&gt;options&lt;/STRONG&gt; argument and finally render the template. Inner function renderItem() is defined to form a closure. It makes it possible for the function to gain access to the &lt;STRONG&gt;context&lt;/STRONG&gt;, &lt;STRONG&gt;rendering&lt;/STRONG&gt; and &lt;STRONG&gt;rendered&lt;/STRONG&gt; variables when it runs:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;			&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; renderItem() {
				&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; dom = &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;;
				&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( !rendering || rendering( context ) !== &lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;) {
					&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; dom = fn( jQuery, context );
					&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( rendered ) 
						rendered( context, dom );
				}
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; dom;
			}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;There is almost nothing to comment regarding the renderItem() function itself. It fires &lt;STRONG&gt;rendering&lt;/STRONG&gt; and &lt;STRONG&gt;rendered&lt;/STRONG&gt; events in due course. But it is &lt;/FONT&gt;&lt;FONT size=3 face=Georgia&gt;still important to note that it is possible to cancel the rendering phase completely in case the&lt;STRONG&gt; rendering&lt;/STRONG&gt; handler explicitly returns &lt;STRONG&gt;false&lt;/STRONG&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Finally the renderItem() function is executed either for each data item in the &lt;STRONG&gt;data&lt;/STRONG&gt; collection (in case data object is an instance of Array) or only once otherwise:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;			&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ( jQuery.isArray( data ) ) {
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; jQuery.map( data, &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;( data, i ) {
					context.index = i;
					context.dataItem = data;
					&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; renderItem( );
				});
 
			} &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; {
				&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; renderItem( );
			}&lt;/PRE&gt;&lt;/DIV&gt;&lt;FONT size=3 face=Georgia&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;In the former case the context object is adjusted to contain correct &lt;STRONG&gt;dataItem&lt;/STRONG&gt; and &lt;STRONG&gt;index&lt;/STRONG&gt; prior to each iteration.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;We are almost done. The only member we left untouched is &lt;STRONG&gt;tmplFn&lt;/STRONG&gt; object containing pre-built functions which are available within our compiled templating function. The reason why the members of &lt;STRONG&gt;tempFn&lt;/STRONG&gt; object are available within the context of generated template is the same why properties of data item can be accessed directly. By virtue of &lt;STRONG&gt;with&lt;/STRONG&gt; statement. Do you remember such line in the body of the compiled template?&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;				&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; ($.tmplFn) { &lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;It is the line that does the trick. There are currently two pre-built functions available: html() and text(). Both of them serve as a means to modify resulting templating string - push() method is called on the instance of the templating string storage:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;jQuery._.push.apply( jQuery._, arguments );&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;In case you do not remember, we stored the reference to &lt;STRONG&gt;jQuery._&lt;/STRONG&gt; array at the beginning of the code of our generated templating function:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;	&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fn = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;(jQuery, $context) {
				&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; $ = jQuery, 
					$data = $context.dataItem,
					$i = $context.index,
					&lt;FONT color=#ff0000&gt;&lt;STRONG&gt;_ = $._ =[]; 
					_.context = $context;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;We can also access the &lt;STRONG&gt;context&lt;/STRONG&gt; object within our pre-built helper functions using &lt;STRONG&gt;jQuery._.context&lt;/STRONG&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;The only difference between html() and text() functions is that the text() was meant to provide encoding of HTML entities:&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: white; COLOR: black"&gt;&lt;PRE&gt;			text: &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;() {
				jQuery._.push.apply( jQuery._, jQuery.map(arguments, &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;(str) {
					&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; document.createTextNode(str).nodeValue;
				}) );
			}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;At the moment of this writing it does not serve its purpose because obviously &lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;document.createTextNode(str).nodeValue&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;returns exactly the same text as &lt;STRONG&gt;str&lt;/STRONG&gt; argument had initially. It still is not encoded.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;As far as I know, plugin authors are aware of this bug.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;For the time being, before some really efficient encoding algorithm is suggested we can always resort to the plain old:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; jQuery(&lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;div&amp;gt;"&lt;/SPAN&gt;).text(str).html();&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;That’s all. Nothing to add. Well, actually there is but this post already exceeded all reasonable limits.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Hope this helps, &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3 face=Georgia&gt;Alexei&lt;/FONT&gt;&lt;/P&gt;
&lt;SCRIPT type=text/javascript&gt;
(function(jQuery){var oldManip=jQuery.fn.domManip,htmlExpr=/^[^&lt;]*(&lt;[\w\W]+&gt;)[^&gt;]*$/;jQuery.fn.extend({render:function(data,options){return this.map(function(i,tmpl){return jQuery.render(tmpl,data,options)})},domManip:function(args){if(args.length&gt;1&amp;&amp;args[0].nodeType){arguments[0]=[jQuery.makeArray(args)]}if(args.length&gt;=2&amp;&amp;typeof args[0]==="string"&amp;&amp;typeof args[1]!=="string"){arguments[0]=[jQuery.render(args[0],args[1],args[2])]}return oldManip.apply(this,arguments)}});jQuery.extend({render:function(tmpl,data,options){var fn,node;if(typeof tmpl==="string"){fn=jQuery.templates[tmpl];if(!fn&amp;&amp;!htmlExpr.test(tmpl)){node=jQuery(tmpl).get(0)}}else if(tmpl instanceof jQuery){node=tmpl.get(0)}else if(tmpl.nodeType){node=tmpl}if(!fn&amp;&amp;node){var elemData=jQuery.data(node);fn=elemData.tmpl||(elemData.tmpl=jQuery.tmpl(node.innerHTML))}fn=fn||jQuery.tmpl(tmpl);var rendering,rendered,context={data:data,index:0,dataItem:data,options:options||{}};if(options){rendering=options.rendering;rendered=options.rendered}function renderItem(){var dom=null;if(!rendering||rendering(context)!==false){var dom=fn(jQuery,context);if(rendered)rendered(context,dom)}return dom}if(jQuery.isArray(data)){return jQuery.map(data,function(data,i){context.index=i;context.dataItem=data;return renderItem()})}else{return renderItem()}},templates:{},tmplFn:{html:function(){jQuery._.push.apply(jQuery._,arguments)},text:function(){jQuery._.push.apply(jQuery._,jQuery.map(arguments,function(str){return document.createTextNode(str).nodeValue}))}},_:null,tmpl:function tmpl(str,data,i,options){var fn=new Function("jQuery","$context","var $=jQuery,$data=$context.dataItem,$i=$context.index,_=$._=[];_.context=$context;"+"with($.tmplFn){with($data){_.push('"+str.replace(/[\r\t\n]/g," ").replace(/'(?=[^%]*%})/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/{%=(.+?)%}/g,"',($1),'").split("{%").join("');").split("%}").join("_.push('")+"');}}return $(_.join('')).get();");return data?fn(jQuery,{data:null,dataItem:data,index:i,options:options}):fn}})})(jQuery);

jQuery.templates["books"] = jQuery.tmpl(jQuery(".template").text().replace(/&lt;\/?script[^&gt;]*&gt;/g,""));
jQuery.globalEval(jQuery(".data").text());
jQuery(function() {
var isRendered = false;

    jQuery(".render-btn").click(
	function() {

	    if (!isRendered) {
		jQuery(".container").html("").hide().append("books", books).css({backgroundColor: "#FFFFCC", padding: "10px 20px"}).fadeIn();
		isRendered = true;
		jQuery(".render").remove();
	    }
	}	
    );    
});
&lt;/SCRIPT&gt;</description><pubDate>Sat, 20 Mar 2010 12:59:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/jquery-templates-proposal-dissecting-plugin-code</guid><category>AJAX</category><category>ASP.NET MVC</category><category>JavaScript</category><category>jQuery</category></item><item><title>Lazy HTML attributes wrapping in Internet Explorer</title><link>https://weblogs.asp.net:443/alexeigorkov/lazy-html-attributes-wrapping-in-internet-explorer</link><description>&lt;P&gt;Having encountered this Internet Explorer (all versions) behavior several times previously, I eventually decided to share this most probably useless knowledge. Excuse my lengthy explanations because I am going to show the behavior along with a very simple case when one can come across it inadvertently. &lt;/P&gt;
&lt;P&gt;Let's say I want to implement some simple templating solution in JavaScript. I wrote an HTML template with an intention to bind data to it on the client side: &lt;/P&gt;
&lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/alexeigorkov/ie_attr_template_4FDE05B3.png" mce_href="https://aspblogs.blob.core.windows.net/media/alexeigorkov/Media/ie_attr_template_4FDE05B3.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="HTML template" border=0 alt="HTML template" src="http://weblogs.asp.net/blogs/alexeigorkov/ie_attr_template_thumb_064EB7B6.png" width=605 height=88 mce_src="https://aspblogs.blob.core.windows.net/media/alexeigorkov/Media/ie_attr_template_thumb_064EB7B6.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Please note, that name of the “sys-template” class is just a coincidence. I do not use any ASP.NET AJAX code in this simple example.&lt;/P&gt;
&lt;P&gt;As you can see we need to replace placeholders (property name wrapped with curly braces) with actual data. Also, as you can see, many of the placeholders are situated within attribute values and it is where the danger lies.&lt;/P&gt;
&lt;P&gt;I am going to use &amp;lt;a /&amp;gt; element HTML as a template and replace each placeholder pattern with respective properties’ values with a little bit of jQuery like this:&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://weblogs.asp.net/blogs/alexeigorkov/ie_attr_replacement_0A5B9639.png" mce_href="https://aspblogs.blob.core.windows.net/media/alexeigorkov/Media/ie_attr_replacement_0A5B9639.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=ie_attr_replacement border=0 alt=ie_attr_replacement src="http://weblogs.asp.net/blogs/alexeigorkov/ie_attr_replacement_thumb_29A0CDBD.png" width=651 height=168 mce_src="https://aspblogs.blob.core.windows.net/media/alexeigorkov/Media/ie_attr_replacement_thumb_29A0CDBD.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;You can find complete code along with the contextFormat() method definition at the end of the post.&lt;/P&gt;
&lt;P&gt;Let’s assume that value for the &lt;STRONG&gt;name &lt;/STRONG&gt;property (that we want to put in the &lt;STRONG&gt;title&lt;/STRONG&gt; attribute) of the first data item is “first tooltip”. So it consists of two words. When the replacement occurred, title attribute should contain the “first tooltip” text which we are going to see as a tooltip for the &amp;lt;a /&amp;gt; element.&lt;/P&gt;
&lt;P&gt;But let’s run the sample code in Internet Explorer and check it out. What you’ll see is that only the first word of the supposed “title” attribute’s content is shown. So, were is the rest of my attribute and what happened?&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://weblogs.asp.net/blogs/alexeigorkov/ie_attr_tooltip_6DE3C5BA.png" mce_href="https://aspblogs.blob.core.windows.net/media/alexeigorkov/Media/ie_attr_tooltip_6DE3C5BA.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=ie_attr_tooltip border=0 alt=ie_attr_tooltip src="http://weblogs.asp.net/blogs/alexeigorkov/ie_attr_tooltip_thumb_48E60541.png" width=165 height=82 mce_src="https://aspblogs.blob.core.windows.net/media/alexeigorkov/Media/ie_attr_tooltip_thumb_48E60541.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The answer is obvious once you see the result of jQuery(“.sys-template”).html() line for the given HTML markup. In IE you’ll get the following &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;A id={id} class={cssClass} title={name} href="{source}" myAttr="{attr}"&amp;gt;Link to {source}&amp;lt;/A&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;See any difference between this HTML and the one shown earlier? No? Then look carefully. While the original HTML of the &amp;lt;a /&amp;gt; element is well-formed and all the attributes are correctly quoted, when you take the same HTML back in Internet Explorer (it doesn’t matter whether you use html() method from jQuery library or IE’s innerHTML directly), you &lt;STRONG&gt;lose attributes’ quotes for some of the attributes&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Then, after replacement, we’ll get following HTML for our first data item. I marked the attribute value in question with italic: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;A id=1 class=first &lt;EM&gt;title&lt;STRONG&gt;=first tooltip&lt;/STRONG&gt;&lt;/EM&gt; href="first.html" myAttr="firstAttr"&amp;gt;Link to first.html&amp;lt;/A&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now you can easily imagine for yourself what happens when this HTML is inserted into the document and why we do not see the second (and any subsequent words if any) of our &lt;STRONG&gt;title&lt;/STRONG&gt; attribute in the tooltip.&lt;/P&gt;
&lt;P&gt;There are still two important things to note. &lt;/P&gt;
&lt;P&gt;The first one (and it actually the reason why I named the post “lazy wrapping” is that if value of the HTML attribute does contains spaces in the original HTML, then &lt;STRONG&gt;it WILL be wrapped with quotation marks&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;For example, if I wrote following on my page (note the trailing space for the &lt;STRONG&gt;title&lt;/STRONG&gt; attribute value) &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;a href="{source}" title="{name}&amp;nbsp; " id="{id}" myAttr="{attr}" class="{cssClass}"&amp;gt;Link to {source}&amp;lt;/a&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;then I would have my placeholder quoted correctly and the result of the replacement would render as expected:&lt;/P&gt;
&lt;P&gt;The second important thing to note is that there are exceptions to the lazy attributes wrapping rule in IE. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;As you can see href attribute value did not contain spaces exactly as all the other attributes with placeholders, but it &lt;STRONG&gt;was still returned correctly quoted&lt;/STRONG&gt; &lt;/LI&gt;
&lt;LI&gt;Custom attribute myAttr is also quoted correctly when returned back from document, though its placeholder value does not contain spaces either. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Now, on account of the highly unlikely probability that you found this information useful and need a solution to the problem the aforementioned behavior introduces for Internet Explorer browser, I can suggest a simple workaround – manually quote the mischievous attributes prior the placeholder pattern is replaced. Using the code of contextFormat() method shown below, you would need to add following line right before the &lt;STRONG&gt;return&lt;/STRONG&gt; statement:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;result = result.replace(/=({([^}]+)})/g, '="$1"');&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Below please find original sample code:&lt;/P&gt;
&lt;P&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" &lt;BR&gt;&amp;nbsp;"&lt;A href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&lt;/A&gt;"&amp;gt;&lt;BR&gt;&amp;lt;html xmlns="&lt;A href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/A&gt;"&amp;gt;&lt;BR&gt;&amp;lt;head&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Lazy attributes wrapping&amp;lt;/title&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;style type="text/css"&amp;gt;&amp;nbsp;.sys-template { display: none; } &amp;lt;/style&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript" src="jquery-1.4.2.js"&amp;gt;&amp;lt;/script&amp;gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;lt;script type="text/javascript"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;String.prototype.contextFormat = function(context) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var result = this.valueOf(), reParam = /{([^}]+)}/g;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// result = result.replace(/=({([^}]+)})/g, '="$1"'); // fix&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = result.replace(reParam, function(match, prop) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return context.hasOwnProperty(prop) ? context[prop] : match;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;BR&gt;&amp;nbsp;&amp;nbsp;};&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;var data = [ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ source: "first.html", name: "first tooltip", id: 1, attr: "firstAttr", cssClass: "first" },&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ source: "second.html", name: "second tooltip", id: 2, attr: "secondAttr", cssClass: "second" },&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ source: "third.html", name: "third tooltip", id: 3, attr: "thirdAttr", cssClass: "third" }&lt;BR&gt;&amp;nbsp;&amp;nbsp;];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;jQuery(document).ready(function() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;var list = jQuery("&amp;lt;ul /&amp;gt;").appendTo(document.body),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;html = jQuery(".sys-template").html();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;jQuery.each(data, function(index) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;jQuery("&amp;lt;li /&amp;gt;").html(html.contextFormat(this)).appendTo(list);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;});&lt;BR&gt;&amp;nbsp;&amp;lt;/script&amp;gt;&lt;BR&gt;&amp;lt;/head&amp;gt;&lt;BR&gt;&amp;lt;body&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;div class="sys-template"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;lt;a href="{source}" title="{name}" id="{id}" myAttr="{attr}" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;class="{cssClass}"&amp;gt;Link to {source}&amp;lt;/a&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;BR&gt;&amp;lt;/body&amp;gt;&lt;BR&gt;&amp;lt;/html&amp;gt;&lt;/P&gt;</description><pubDate>Tue, 16 Mar 2010 13:42:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/lazy-html-attributes-wrapping-in-internet-explorer</guid><category>AJAX</category><category>JavaScript</category></item><item><title>Hook up to arbitrary HttpModule event in global.asax</title><link>https://weblogs.asp.net:443/alexeigorkov/hook-up-to-arbitrary-httpmodule-event-in-global-asax</link><description>&lt;P mce_keep="true"&gt;First of all, if you are already aware of the technique you can use to bind an&amp;nbsp;event handler to the arbitrary event of the arbitrary HttpModule registered within your application using global.asax file, then, I am terribly sorry -&amp;nbsp;there is most probably nothing new in this post for you (while still you may find subtleties you did not know previously).&lt;/P&gt;
&lt;P mce_keep="true"&gt;Otherwise, if you are like me and from time to time you stumble upon the task when you want to handle some event of some HttpModule and can't easily find a way to do it, then read on.&lt;/P&gt;
&lt;P mce_keep="true"&gt;So,&amp;nbsp;you need to handle an event (let's name it&amp;nbsp;MyEvent) of&amp;nbsp;some HttpModule (let's name it MyModule). Let's also assume that the event takes event arguments instance of custom type MyEventArgs.&lt;/P&gt;
&lt;P mce_keep="true"&gt;You may find&amp;nbsp;that one of the solutions suggested for the task (for example in "Pro ASP.NET 3.5 in C# 2008" book from Apress) is to register event handler within an Init() method of another HttpModule:&lt;/P&gt;
&lt;P mce_keep="true"&gt;public void Init(HttpApplication httpApp)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;MyModule module = httpApp.Modules["MyModule"];&lt;BR&gt;&amp;nbsp;module.MyEvent += MyEventHandler;&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;But there is another&amp;nbsp;approach I'd like to share with you. &lt;/P&gt;
&lt;P mce_keep="true"&gt;Of course you already know that you may handle HttpApplication instance's events using global.asax file. For example you may use Application_Start method within the file to handle Start event of HttpApplication instance.&lt;/P&gt;
&lt;P mce_keep="true"&gt;What you might&amp;nbsp;not be aware of is that using the same syntax you may handle ANY event of ANY HttpModule registered for your application. In our case it is enough to write following code in global.asax to handle event named&amp;nbsp;MyEvent of HttpModule named&amp;nbsp;MyModule:&lt;/P&gt;
&lt;P mce_keep="true"&gt;protected void MyModule_MyEvent(object sender, MyEventArgs e) {&lt;BR&gt;&amp;nbsp;// handler implementation&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;There&amp;nbsp; are&amp;nbsp;several subtleties to note:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;MyModule is not the name of the HttpModule class. It is the name under which the&amp;nbsp;HttpModule is registered in configuration file (web.config);&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Name of the module is not case sensitive within the name of the method;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Second part of the method name (name of the event - MyEvent) is&amp;nbsp;not case sensitive either;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;You may, if you wish, add "on" prefix (also is not case sensitive) to event name within the method name.&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;Let me illustrate the three last statements with examples. All the following are perfectly valid declarations for such method:&lt;/P&gt;
&lt;P mce_keep="true"&gt;protected void MyMODULE_MyEvent(object sender, MyEventArgs e) {&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;protected void MyModule_myEvent(object sender, MyEventArgs e) {&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;protected void MyModule_OnMyEvent(object sender, MyEventArgs e) {&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;protected void mymodule_onmyevent(object sender, MyEventArgs e) {&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;And the last&amp;nbsp;piece of information I wanted to share is what actually makes this magic possible. All the related logic can be found within following methods: HttpApplicationFactory.&lt;STRONG&gt;ReflectOnMethodInfoIfItLooksLikeEventHandler&lt;/STRONG&gt; and HttpApplication.&lt;STRONG&gt;HookupEventHandlersForApplicationAndModules. &lt;/STRONG&gt;Names of the classes and methods are self-explanatory. &lt;/P&gt;
&lt;P mce_keep="true"&gt;Hope this helps.&lt;/P&gt;</description><pubDate>Wed, 03 Mar 2010 16:59:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/hook-up-to-arbitrary-httpmodule-event-in-global-asax</guid><category>ASP.NET</category></item><item><title>Where is my Microsoft Ajax 3.5 library standalone download?</title><link>https://weblogs.asp.net:443/alexeigorkov/where-is-my-microsoft-ajax-3-5-library-standalone-download</link><description>&lt;P mce_keep="true"&gt;Today I visited &lt;A href="http://www.asp.net/ajax/downloads/"&gt;http://www.asp.net/ajax/downloads/&lt;/A&gt; page to download standalone version of Microsoft Ajax 3.5 client library and used "Download the AJAX Library" button as I surely did many times previously. The landing page contained only the following: "This page has been removed. Please visit the ASP.NET Developer Center &lt;A id=ctl00_mainContentContainer_ctl01 onclick="javascript:Track('ctl00_mainContentContainer_ctl00|ctl00_mainContentContainer_ctl01',this);" href="http://msdn.microsoft.com/asp.net"&gt;home page&lt;/A&gt; for further information." But I could not find any relevant "further information" on the ASP.NET Developer Center &lt;A id=ctl00_mainContentContainer_ctl01 onclick="javascript:Track('ctl00_mainContentContainer_ctl00|ctl00_mainContentContainer_ctl01',this);" href="http://msdn.microsoft.com/asp.net"&gt;home page&lt;/A&gt;. Only a link to the same &lt;A href="http://www.asp.net/ajax/downloads/"&gt;http://www.asp.net/ajax/downloads/&lt;/A&gt;&amp;nbsp;page I&amp;nbsp;came from. Could someone explain me what happened to this download?&lt;/P&gt;</description><pubDate>Sat, 26 Sep 2009 10:31:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/where-is-my-microsoft-ajax-3-5-library-standalone-download</guid><category>AJAX</category><category>ASP.NET</category></item><item><title>Firefox 3. XSLT Processing Engine bug?</title><link>https://weblogs.asp.net:443/alexeigorkov/firefox-3-xslt-processing-engine-bug</link><description>&lt;p&gt;I stumbled upon really strange issue while researching unexpected behavior of existing web application under Firefox 3.&lt;/p&gt;&lt;p&gt;So, there are ultimately simplified steps to reproduce:&lt;/p&gt;&lt;p&gt;1. XML document:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br&gt;&amp;lt;items&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;item&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/item&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;item&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id&amp;gt;2&amp;lt;/id&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/item&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;item&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id&amp;gt;3&amp;lt;/id&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/item&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;lt;/items&amp;gt; &lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;2. XSL stylesheet:&lt;/p&gt;&lt;p&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br&gt;&amp;lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:output method="html" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:template match="item"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr id="{id}"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:value-of select="id" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;br&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/p&gt;&lt;p&gt;3. Load these XML and XSL documents to Document instances.&lt;/p&gt;&lt;p&gt;4. Transform this XML document using given XSL stylesheet with the following code:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; var processor = new XSLTProcessor();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; processor.importStylesheet(xsl);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; var doc = processor.transformToDocument(xml);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p&gt;In Firefox 2 we would get following document as a result of this utterly ordinary code:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;transformiix:result xmlns:transformiix="http://www.mozilla.org/TransforMiix"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;TR id="1"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;TD&amp;gt;1&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/TR&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;TR id="2"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;TD&amp;gt;2&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/TR&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;TR id="3"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;TD&amp;gt;3&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/TR&amp;gt;&lt;br&gt;&amp;lt;/transformiix:result&amp;gt;&lt;/p&gt;&lt;p&gt;Since we used &lt;b&gt;transformToDocument &lt;/b&gt;and there is no root node in the resulting XML fragment then we have wrapping &lt;b&gt;&amp;lt;transformiix:result /&amp;gt;&lt;/b&gt; document element node.&lt;/p&gt;&lt;p&gt;But, as I said, in Firefox 3 result differs. I got following document:&lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;lt;transformiix:result xmlns:transformiix="http://www.mozilla.org/TransforMiix"&amp;gt;&lt;/b&gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;transformiix:result&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TR id="1"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TD&amp;gt;1&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/TR&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TR id="2"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TD&amp;gt;2&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/TR&amp;gt;&lt;br&gt;&amp;nbsp;&lt;b&gt;&amp;nbsp; &amp;nbsp;&amp;lt;/transformiix:result&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;TR id="3"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TD&amp;gt;3&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/TR&amp;gt;&lt;br&gt;&lt;b&gt;&amp;lt;/transformiix:result&amp;gt;&lt;/b&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Do you see the difference? There is unexpected (at least to me) &lt;b&gt;&amp;lt;transformiix:result /&amp;gt;&lt;/b&gt; element wrapping first two &amp;lt;tr /&amp;gt; elements in the resulting document.&lt;/p&gt;&lt;p&gt;And it gets event more interesting with an increase of the number of items in the original document. For example with four items we would get:&lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;lt;transformiix:result xmlns:transformiix="http://www.mozilla.org/TransforMiix"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;transformiix:result&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;transformiix:result&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TR id="1"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TD&amp;gt;1&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/TR&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TR id="2"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TD&amp;gt;2&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/TR&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/transformiix:result&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TR id="3"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TD&amp;gt;3&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/TR&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/transformiix:result&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TR id="4"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TD&amp;gt;4&amp;lt;/TD&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/TR&amp;gt;&lt;br&gt;&lt;b&gt;&amp;lt;/transformiix:result&amp;gt;&lt;/b&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;And so on...&lt;/p&gt;&lt;p&gt;This behavior starts when the number of elements is equal to or grater than 3.&lt;/p&gt;&lt;p&gt;&amp;nbsp;Any thoughts? &lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Fri, 20 Jun 2008 21:21:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/firefox-3-xslt-processing-engine-bug</guid><category>JavaScript</category></item><item><title>.NET Framework 1.1 Service Pack 1 and Page.RegisterStartupScript</title><link>https://weblogs.asp.net:443/alexeigorkov/net-1-1-service-pack-1-and-page-registerstartupscript</link><description>&lt;p&gt;First, if you are are developing exclusively ASP.NET 2.0+ applications, sorry, there is nothing interesting for you in this post.&lt;/p&gt;&lt;p&gt;Second, if you are involved in some ASP.NET 1.1 projects and have no plans to install new development environment, then, sorry again, there is probably no reason for you to read on either. Ok, I've done all I could to warn you against reading it. Don't blame me for wasting you time, because I am going to start from the very beginning.&lt;/p&gt;&lt;p&gt;One of my current projects is ASP.NET 1.1 Web Application. It is already released and rather stable. And yesterday I got new development machine on my workplace and migrated all my data to it. .NET Frameworks 1.1, 2.0, 3.0, 3.5 were preinstalled before I first logged in (thanks to our system administrators). I installed VS 2003 and SP1 for it, VS 2008, SVN client, some other necessary utilities and components. Then, updated sources from source control for the mentioned ASP.NET 1.1 Web Application and started it. Bang! Script error - some variable is undefined.&lt;/p&gt;&lt;p&gt;Actually there were a bunch of such errors on the page. As I intentionally mentioned earlier, the application is stable. And this particular page was not changed for quite some time. &lt;/p&gt;&lt;p&gt;Brief research of the generated HTML source, code-behind class and respective web controls revealed the cause of the exception: there was a sequence of similar Page.RegisterStartupScript statements which went in pairs. The first one in a pair registered some JavaScript object, and the second one - used the object in another declaration.&lt;br&gt;&lt;/p&gt;&lt;p&gt;First I checked source control's log - no related changes. Then, the next suspect - application configuration changes that could cause such behavior. But no, all the related controls' declarations on the page are static.&lt;/p&gt;&lt;p&gt;Ok, code was not changed, application is working fine on QA environment. So, something is wrong with my new machine. But what?&amp;nbsp;&lt;/p&gt;&lt;p&gt;I had a dim recollection that there is something wrong with the sequence of script registration in ASP.NET 1.1. But common sense told me that if something wrong could happen then it would had happened long ago.&lt;/p&gt;&lt;p&gt;Still, I opened Reflector and found such code inside RegisterScriptBlock method of System.Web.UI.Page class:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (scriptBlocks == null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; scriptBlocks = new HybridDictionary();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;/p&gt;&lt;p&gt;As you probably well aware of, HybridDictionary changes its internal storage from ListDictionary to Hashtable starting from its ninth element. So, of course we cannot rely on any specific order of script registrations if script blocks are stored in HybridDictionary. But how did it work earlier and how the same code works on development server and QA environment without any bugs reported?&amp;nbsp;&lt;/p&gt;&lt;p&gt;So, I copied Reflector to the development server and found following code in the same RegisterScriptBlock method that I reviewed on my machine:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (scriptBlocks == null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; scriptBlocks = new ListDictionary();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;/p&gt;&lt;p&gt;The code was fixed. But where did the fix come from? I recalled that there is a service pack for .NET 1.1 that I installed on my old development machine several years ago. Google promptly gave me a &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38&amp;amp;displaylang=en" title=".NET 1.1 Service Pack 1" target="_blank" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38&amp;amp;displaylang=en"&gt;link&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;File name: NDP1.1sp1-KB867460-X86.exe, Version: 1, Date Published: 8/30/2004, Download Size: 10.2 MB &lt;br&gt;&lt;/p&gt;&lt;p&gt;Why am I presenting all this information here? Because the fix did not help, though I was almost certain that it should. The same HybridDictionary.&lt;/p&gt;&lt;p&gt;That's was fiasco. My working day was over several hours ago. Finish.&lt;/p&gt;&lt;p&gt;But today I decided to reproduce the issue at home. Fortunately I had a virtual machine with Windows XP and fortunately the copy of .NET 1.1 System.Web.dll had the same version as the one at work (i.e. HybridDictionary is used in RegisterScriptBlock).&lt;/p&gt;&lt;p&gt;So I started googling again and found the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=281FB2CD-C715-4F05-A01F-0455D2D9EBFB&amp;amp;displaylang=en" title=".NET 1.1 Service Pack 1" target="_blank" mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=281FB2CD-C715-4F05-A01F-0455D2D9EBFB&amp;amp;displaylang=en"&gt;second service pack&lt;/a&gt;. Strangely enough it has the same name (i.e. .NET Framework 1.1 &lt;b&gt;Service Pack 1&lt;/b&gt;) though with a lengthy suffix (.NET Framework 1.1 Service Pack 1 SYSTEM.WEB.DLL and MSCOREE.DLL Security Update for Windows 2000, Windows XP, Windows 2003 Server x64/IA64 and Windows 2003 Server R2 x64/IA64) . &lt;br&gt;&lt;/p&gt;&lt;p&gt;Like the previous service pack that I found, description for this one states that its purpose - security improvements. No mentions of ASP.NET-specific modifications. I could not find any documentation which describes the changes in detail.&lt;/p&gt;&lt;p&gt;But the main thing is that this second "Service Pack 1" done what I wanted. Eventually I had my ListDictionary back.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br&gt;The summary is: &lt;/p&gt;&lt;p&gt;1) there are at least TWO patches called ".NET 1.1 Service Pack 1"; &lt;/p&gt;&lt;p&gt;2) both of them state that they are focused on security improvements, but&lt;/p&gt;&lt;p&gt;3) one of them changes at least one fundamental aspect of ASP.NET 1.1 behavior.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br&gt;Thank you for reading. Good luck.&lt;/p&gt;</description><pubDate>Sat, 17 May 2008 12:36:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/net-1-1-service-pack-1-and-page-registerstartupscript</guid><category>.NET</category><category>ASP.NET</category></item><item><title>Array.prototype.slice vs manual array creation</title><link>https://weblogs.asp.net:443/alexeigorkov/array-prototype-slice-vs-manual-array-creation</link><description>&lt;DIV style="FONT-SIZE: 15px; FONT-FAMILY: Georgia,'Times New Roman',serif"&gt;
&lt;P&gt;In a constant pursuit of new and more effective ways to implement common JavaScript code patterns I've recently found out (sorry for such probably trivial finding but it was a real news for me) that Array.prototype.slice method can be easily used to make instance of Array from an arguments object. &lt;BR&gt;I instantly decided to use it in my current projects. Currently the same task is performed by simple iteration through members of the arguments object and filling in respective members of a new Array instance. &lt;BR&gt;I was pretty sure that performance of the new variant will be significantly better. It is a native method call after all instead of interpreted JavaScript code. Nevertheless, I wanted to run simple comparison tests and wrote following code:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/code_2.png" mce_href="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/code_2.png"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" alt=code src="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/code_2.png" border=0 mce_src="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/code_2.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The code is self-explanatory. I used four arguments for method calls. 10000 iterations. An alias for Array.prototype.slice method was added to avoid unnecessary lookup.&lt;/P&gt;
&lt;P&gt;The results were surprising. You can see them on the screenshot below. &lt;/P&gt;
&lt;P&gt;&lt;A href="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/comparison_2.png" mce_href="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/comparison_2.png"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" alt=comparison src="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/comparison_2.png" border=0 mce_src="https://aspblogs.blob.core.windows.net/media/alexeigorkov/WindowsLiveWriter/Array.prototy.slicevsmanualarraycreation_1328/comparison_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Of the four major browsers that I tested the code against, (FF 3.0b3, IE7, Opera 9.50 Alpha and Safari 3.0.4 (Windows)) only Safari proved my initial expectations. &lt;BR&gt;Why is that? Did I make some error in my test code that I can't notice? &lt;/P&gt;
&lt;P&gt;By the way, Opera 9.5 is really fast.&lt;/P&gt;&lt;/DIV&gt;</description><pubDate>Sun, 17 Feb 2008 22:22:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/alexeigorkov/array-prototype-slice-vs-manual-array-creation</guid><category>JavaScript</category></item></channel></rss>