Showing posts with label jQuery. Show all posts
Showing posts with label jQuery. Show all posts

Tuesday, June 11, 2013

Welcome to jsviews.com - the documentation and download site for JsViews, JsRender and JsObservable

This blog brings two pieces of news:

The jsviews.com website
The first is in the title: There is a now a new jsviews.com  website, which provides documentation, samples, downloads, and more, for JsViews, JsRender and JsObservable.

JsRender is now officially beta
And the second is that the JsRender bits (which have been "beta candidate" for a while) have today moved to being officially labelled "beta".  

The context
In fact both JsRender and JsViews have effectively been at beta quality for some time. The plan of course is to move to V1.0 as soon as is appropriate, and in fact the current code is already very close to the targeted V1.0 version, in that the code quality is high, and the feature coverage very complete. 

So what has been missing? Well the the most important missing piece was full API documentation, and the decision was not to label a library as being an official beta release until that API documentation for that library was available. But to achieve that meant not only writing the documentation content, but also providing the website to view and navigate through that documentation. And also the plan was to provide integrated live working samples completely within the flow of the documentation - and that too needed to be designed and implemented.

So jsviews.com is that website, and it is in fact itself an example of a single-page app built entirely using JsViews and JsRender, illustrating the power of those libraries for creating dynamic interactive single-page apps. If you are interested, you can see the code for the site here. (It actually includes a hidden feature which allows it to switch into editable mode, with wiki-style content creation, so it is more sophisticated than may meet the eye in normal read-only mode).

JsRender now has detailed (and interactive) API documentation
Here it is: jsviews.com/#jsrapi. More topics will be added in the coming period (along with. later on, tutorials, and "deep-dive" topics). But already the topics give complete coverage of the primary scenarios of JsRender.

And JsViews?
JsViews API documentation will be next, and as soon as it is ready, the official beta for JsViews will be declared. (So in fact the JsViews beta version will probably be almost identical to current JsViews bits). 

JsRender and JsViews V1.0
Version V1.0 should follow not too long after, since the number of triaged issues currently planned to be addressed for V1.0 is small - and could even be reduced slightly if necessary. V1.1 planned features have also already been largely determined - and V1.1 is not intended to be major release in terms of new features.   

Integrated samples within the documentation:
Now, just to give a flavor of the features of the new documentation, here is an example of a sample - taken from the end of this documentation topic:



The sample is live. You can click on Try it and change anything you want: - the template, the data, or the code. For example if you change each of the places I have circled in red - 


- and then hit Run Code, you will get something like this:


Now if you switch to the Full Code tab, you can copy the contents of that tab, and drop them into a simple HTML page. 



Run the page and you have a fully working sample of your own modified version of the original - which you can continue to experiment with from there...

I am looking forward to completing the documentation, and hope it will help you to discover and appreciated the possibilities of JsRender and JsViews!

Tuesday, March 6, 2012

Approaching Beta: What's changing in JsRender and JsViews

Major update to  JsRender and JsViews
In previous posts and elsewhere, I had set the goal of reaching beta for JsRender at the end of February. A major update has just been committed to GitHub for both JsRender and JsViews, which is effectively a beta candidate for JsRender.

This update brings a large number of API changes, new features, and improvements, to both JsRender and JsViews. It follows quite a period of apparent silence on GitHub (as far as commits are concerned), which left some folks with the impression that the project may have become inactive. The truth is quite the 
opposite. JsRender and JsViews are (in my view!) alive and well and growing apace...

So why the silence? In working on the new bits, I had to address the fact that the beta API design I was aiming for would be breaking for many users. Not a big deal usually for alpha software, but in the case of JsRender and JsViews there has been quite a lot of adoption already, so I wanted to avoid causing too much pain with a series of breaking commits. I decided to work on a single breaking update intended to provide a one-step transition to a beta candidate for JsRender (or at least a candidate for a stable beta API), and also introduce much of the future stable beta API for JsViews.

That update has taken a long time to complete, since it is a major rewrite not only of JsRender but also JsViews... The new bits for JsRender have been nearly ready for quite a while now, but the integration between JsViews and JsRender meant also moving JsViews a long way towards its future beta version. That way current users of JsViews can also port their apps to the new JsRender.

What's changed?
This post provides a guide through the changes, and is primarily intended to help existing users of JsViews or JsRender to move to the new version.

It can also be helpful to first-time adopters, but bear in mind that this is still not quite the official beta, so documentation is limited. I hope to provide more documentation (or update this post) as we move to the official beta for JsRender (fairly soon) and JsViews (probably end of April or early May...). In the meantime, take a look too at all the live samples and the corresponding code for JsViews and JsRender.

JsRender: principal changes
  • {{: ...}} and {{> ...}} tags: The basic tag for outputting data values, {{=some.data.path}}, is now {{:some.data.path}}, and supports converter functions, and almost any javascript expression, as in {{myConverter:someExpression}}.
    It is 
    not HTML-encoded by default.
    To HTML-encode, use the tag 
    {{>someExpression}}.
  • Block tags and inline tags: The syntax for block/inline tags is now similar to HTML element syntax in the use of the '/' character:
    • A block tag is written {{myBlockTag ...}} ... {{/myBlocktag}}.
    • A non-block (self-closing, or inline) tag is written {{myInlineTag/}}.
    • A block tag can become an inline tag if it references a template as content:
      {{myBlockTag ... tmpl="myNamedTemplate" /}}.
  • {{#each}} tag is now {{for}}: There was some confusion around the {{each ...}} tag, in that the name suggested that it only worked as an iterator over an array as in {{#each myArray}}...{{/each}}. In fact it worked also against singleton data objects, and this is made more intuitive by renaming it to {{for ...}}. This means you can write {{for myArray}}...{{/for}}, but for other scenarios you might also write  {{for myObject}}...{{/for}}, which will render against myObject as current data item (data context) for the nested content.
  • Expressions within template tags: JsRender template tags now support almost any JavaScript expression (and also allow parens, to any depth).
    For example, you can write:  {{if  price > 3 && price < (maxPrice - 10)}}Special deal{{/if}}.
    However, unlike with jQuery Templates, the expressions are evaluated within a parsing and execution context which precludes accessing global variables or running any code which arbitrarily assigns or modifies data or state. Only template data properties/methods and registered helper functions/parameters can be accessed. 
  • View properties syntax: To access view properties, such as parent, the syntax is now #parent.
  • $itemNumber is now #index: There is now a zero-based index, identical to the index on view objects when using JsViews. This change is thanks to expression support which has made getting a 1-based index very easy, as in: {{:#index + 1}}.
  • Helper functions: There is now a single concept of a helper function, which can be provided either via the options parameter in the $.render (or the $.link method, if using JsViews), or by registering using the $.views.helpers() API call.
    In either case, a registered helper function myHelper(...) will be accessed within the template using a simpler syntax than before: ~myHelper(...), rather than $ctx.myHelper(...). 
    F
    or example, you can write {{:~myFullNameHelper(firstName, lastName)}}.
  • Template parameters: In addition to helper functions, template parameters can be passed in with options or registered using $.views.helpers() - and then accessed by the same template syntax as helper functions, as in {{:~myParameter}}
  • Aliasing variables for use in nested contexts: If you want to access the data in a parent context, you can now provide a variable (accessed like a template parameter) which will be available within nested context. For example: {{for lineItems ~orderTitle=orderInfo.title}}...{{:~orderTitle}}...{{/for}}
  • Registration APIs: Registering of helper functions, converter functions and custom tags each use an equivalent API pattern: $.views.helpers()$.views.converters()$.views.tags().
  • Registering/compiling templates: This uses a similar API, $.templates(), which also allows defining template properties and resources (below).
  • "Intellisense-friendly" APIs for rendering:  New APIs are provided which are convenient for intellisense. For example, you can now write: $.render.detailsTmpl( person ); 
  • Template resources and settings: Registering templates now supports specifying individual settings for the template, and registering resources such as helpers, converters, other templates, etc. so that they are available only in the context of the registered template, and are not exposed globally to other templates.
  • Layout templates: A template may have a setting: layout: true. This will make it render just once, independently of whether the data supplied is an array, null, undefined, false, or any other data value. A {{for}} tag within the template will then render against the data in the normal way.
  • Debug setting: If a compiled template has the setting debug: true, a debugger; statement will be inserted at the beginning of the compiled template function. This makes debugging declarative templates easier.  
  • Unit tests:  JsRender now includes unit tests.
JsViews: principal changes
  • Views: Previously, both JsRender and JsViews had a concept of a view hierarchy, but the two were distinct. Now a single view hierarchy is created during rendering of templates (and nested templates) and the same view hierarchy is maintained (but augmented with additional methods or properties) during data linking by JsViews. 
  • Declarative data binding: data-fromdata-getfrom and data-to are now consolidated into a single data binding attribute: data-link. This provides for more concise and simpler data binding declarations that support both one-way and two-way binding. See the samples for different use-cases, including binding to multiple target attributes on the same HTML element.
  • Data binding expressions: Data binding expressions are evaluated according to the same contextual and parsing rules as template tag expressions. They can access exactly the same user-registered helper functions, template parameters, or converter functions that are available to template tag expressions - whether registered using $.views.helpers, or passed in with the options parameter in a render() call. In addition, helper functions and template parameters can be passed in with the options parameter of any link() call.
  • Automatic dependency detection :  In data binding expressions it is no longer necessary to put square brackets in paths to specify data-binding dependencies.
    <input data-getfrom="shipping.address[street]" data-to=" shipping.address[street] " /> is now written:
    <input data-link="shipping.address.street" />
    This opens the way to supporting [] syntax for array or property accessors.
  • "Intellisense-friendly" APIs for linking:  As with JsRender, JsViews now provides new APIs which are convenient for intellisense, such as:  $.link.movieTmpl( "#movieList", movies );
  • Disabling linking when rendering a template: If JsViews is loaded, rendered template were previously automatically data-linked. It is now possible to set link: false on a template, or as an option in the render call, or as a tag property: {{for link=false}}, to switch off data linking within a rendered template.
    This is useful, for example, if you want to include template tags within attribute markup, and suppress JsViews HTML comment annotations that were automatically inserted for data-linking purposes.
Missing, or not yet available features
  • Programmatic data linking: Programmatic data link APIs such as addLink have been removed. (They will probably return in modified form for JsViews beta)
  • Unit tests:  JsViews is not so close to beta as JsRender, and does not yet include unit tests. They will be added before it reaches beta.  
Performance and code size
In spite of the many new features, total minified code size for JsViews plus JsRender is similar to the previous update, and performance is slightly better. A performance test page is provided.

Specific examples of porting to the current design
The samples available at github.com/BorisMoore/jsrender (live here) and at github.com/BorisMoore/jsviews (live here) have been changed where necessary to work with current API calls and declarative syntax. In some cases there are new features available which would have provided a more elegant approach to the scenario shown, but the samples have generally been changed in a minimalistic way, to illustrate how to port to the new version. (More samples showing new features will be added at a later point, along with other documentation).

And from here?
The plan is to wait for some feedback or bug reports on this new update, before deciding whether to label this version of JsRender as the official beta. Once it has become beta, I hope to progressively add additional documentation.

In the meantime I will continue to work on moving JsViews towards beta. This may still take a while, since there are some significant changes and improvements in the pipeline. My hope is that it will be available late April or early May... 

Wednesday, October 12, 2011

jQuery Templates and JsViews: The Roadmap

Update: JsRender is now close to beta, and JsViews has many new features which also bring it closer to beta.
See Approaching Beta: What's changing in JsRender and JsViews for details on the latest changes.

From jQuery Templates to JsViews
This post provides some details and some context on the relationship between jQuery Templates, JsRender and JsViews, and provides information about the current roadmap.

History of jQuery Templates
jQuery Templates started out in March 2010, and went through a series of steps:
  • March 2010: John Resig posted a prototype
  • from May 2010 onwards: I worked on a fork of John's prototype (as did many others)
  • October 2010: My fork was pulled into the jQuery Templates repo, and it was decided to make this a jQuery Official Plugin:  (along with the Globalization and Data Link plugins, created primarily by Dave Reed, also at Microsoft). 
  • October 2010 - April 2011: I continued to iterate on the code on jquery/jquery-tmpl - taking it to Beta1 then working towards Beta2.
  • April 2011: The jQuery Project decided to change the status of official plugins. From that point the version of jQuery Templates at jquery/jquery-tmpl was owned by the jQuery UI team. I collaborated with jQuery UI on moving templates forward. 
  • April 2011 onwards: jQuery UI decided to put  jquery/jquery-tmpl  on hold - and asked me not to continue with fixes and updates under that repository. The plan was first to establish their templating requirements, and from there move on to determining what template engine they would use.
Meanwhile: JsRender and JsViews
At the same time (April 2011) I was working on an updated approach to jQuery Templates: JsRender and JsViews. JsRender uses pure string-based rendering without any DOM (or even jQuery) dependency, and JsViews integrates JsRender templates with data linking, to provide data-driven templated views.  I gave a preview of this work at the April 2011 jQuery Conference.

The jQuery UI team asked me to continue that ongoing development in my own repository rather than under the jQuery project. Meantime we collaborated on establishing design and feature requirements for templates in jQuery UI.

More recently jQuery UI decided that they did not want to use the jQuery Template syntax for their future templating engine, and instead opted for a logicless syntax (or as I prefer to say, codeless - since there would still be {{each}} and {{if}} tags) similar to Mustache and Handlebars. This led me to develop a version of JsRender using that style of markup. The result is the JsRender template engine that I showed at the October jQuery Conference, which is considerably faster that jQuery Templates, and remains very flexible thanks to the ease and power of creating custom tags and helpers (which include some features not found in Handlebars or Mustache - such as chaining of tags, intermixing of named and positional parameters, postfixed encoding syntax etc.)

Personally I had mixed feelings about the new codeless syntax. One big concern was that it will require porting of existing jQuery Template apps to the new syntax, and in the case where the templates include a lot of inline JavaScript expressions, it will mean either creating new custom tags, or falling back on the 'opt-in' {{*... }} tag for inline code.

But on the positive side, it provides better separation of presentation and behavior, and includes some other new features and improvements that provide considerable advantages, including the ease of creating custom tags, and the improved performance. So finally I am pretty excited by the new approach and what it brings...

Moving forwards with JsViews and JsRender
Currently JsViews and JsRender include a number of samples which can provide the basis for using them already for front-end development. Although there is not yet any documentation as such, and there has been no publicity (until now), they are nevertheless already being used at the prototype level by some important sites (notably by Hotmail - who are about to go into production using JsViews). That said, I anticipate some changes in JsViews, so it may be better to wait a bit longer before doing too much development using the JsViews platform. JsRender on the other hand is I think getting close to a stable Beta-release API.

Templates in jQuery UI 
As far as jQuery UI is concerned, the current expectation is that jQuery UI will use JsRender templates, or at least use JsRender as the starting point for jQuery UI templates. No  decision has been made yet on whether jQuery UI will use JsViews for data linking and binding.

Roadmap summary:
  • jQuery templates: Will remain at Beta1, and be superseded by JsRender templates, and JsViews.
  • JsRender: Soon move to Beta – then on to V1
    jQueryUI plan to use JsRender. (TBD whether it will migrate to jQuery project in GitHub...)
  • JsViews: Move to Beta (after JsRender) and then on to V1 …
    May also be used by jQueryUI

Monday, October 10, 2011

JsViews presentation at jQuery Conference, Boston

Six months in stealth mode...
My last blog entry was six months ago, and concerned my jQuery Conference presentation in April 2011. Since then, no blog entries, but lots of activity on moving  jQuery Templates forwards to the "next generation". It has been somewhat 'stealth mode' - since I wanted to stabilize the design and the code before drawing too much attention to it. That work has been progressing very well, and has now reached the point where I will gradually  bring it out from 'under wraps'.

jQuery Conference Presentation
The first step in that process just happened - another jQuery Conference presentation: I just returned from presenting on "JsViews: Next-generation jQuery Templates and Data Link" at the October 2011 jQuery Conference in Boston.

Here are the conference links:
The presentation was very well received, and created some buzz on Twitter, as illustrated by these tweets:
  • thinksaydo Think Say Do, LLC: super excited about github.com/BorisMoore/jsr… and github.com/BorisMoore/jsv… being part of jQuery's future
  • rascalking David Bonner: looking forward to playing with jsrender/jsviews. feels really comfortable, coming from a django background. #jqcon
  • chinmaybijwe Chinmay Bijwe#jqcon : JSViews and JSRender look great! Want to try soon.
  • vinbrown2 Vin Brown: seems any previously stated (by me) similarity between jsViews and xslt were overstated. this is oozing coolness. #jqcon
  • weisjohn john weis: coming from the Django template world, JsRender and JsViews are the      hotness! #jqcon
  • abackstrom Adam Backstrom: Super easy to add new template tags to jsViews. Tags can be      used in conditional template logic (if/else). #jqcon
  • abackstrom Adam Backstrom: Progressive enhancement in jsViews: render on the server, later apply a view to the DOM, get a view that is now observing for changes #jqcon
  • shooley Shawn Hooley: Excited about jsViews! Slick solution for dynamic rendering. #jqcon
  • addy_osmani Addy Osmani: Interesting next progression that's come out of the jQuery templatesproject: jsRender (no DOM/jQ dependence) -github.com/BorisMoore/jsr…
  • clayalouise clayalouise: Love the design for JsViews! I've been looking for a better than knockoutjs #jqcon
  • monkeysort Derek Meyer: Great talk by Boris Moore on the jQuery Templates replacementJsViews. Could have used a longer time slot for a public launch. #jqcon
  • ScottRHuff Scott Huff: Exciting and thought provoking talk from Boris Moore on JsViews #jqcon
  • _jeffrose Jeff Rose: Wish Boris Moore's presentation on JsViews was longer. Looks very impressive. #jqcon
One aspect that triggered a lot of excitement and questions was progressive enhancement, using the same JsRender template on the server as on the client, and then activating the content in the client by calling $.link().  (See this demo)

And now...
From this point I'll be working towards a documented Beta release - not too far away. More of that in an upcoming post on  "jQuery Templates and JsViews: The Roadmap".

Thursday, April 21, 2011

jQuery Bay Area Conference - presentation, meetings and movements

I just got back from speaking at this jQuery Conference Bay Area Conference last weekend, so this is a quick blog to provide some links.

This was the official jQuery Conference, which is held twice a year. So all the key members of the jQuery team and community were there.
  • 29 presentations over two days
  •  About 500 participants
  • Other presenters included John Resig, Yehuda Katz, Paul Irish, and others who you can see here
My Presentation
I spoke about “Harnessing jQuery Templates and Data Link, to build dynamic data-driven browser apps”.
The presentation was in three sections:
  • Discussion of App Scenarios for data and templates in the client, and example demo app
  • Templates today: walkthrough of all the main features
  • Templates ‘tomorrow’: preview of current work on really fast responsive interactive client-side views, integrating jQuery Templates and Data Linking. (Demo)
The slides are here

Meetings and movements
I had some great meetings and discussions with other developers and open-source community members. Definitely declarative binding of templated views to observable data is ‘in the air’, and there is clearly a huge interest in related scenarios and patterns like client-side MVVM or MVC. We were already doing much of this in Microsoft AJAX Preview 6 with observable objects and arrays and declarative bindings in templates, but it was not known to many. My hope is that the current JsViews integration of data link and templating we are working on will break new ground in this area, but this time within a simpler leaner approach, and in synergy with jQuery. People are looking for fast lightweight declarative frameworks of this kind. 

Update: I have published the demo pages above on GitHub as live pages, and have updated the links above to point to the new pages.

The new content is as follows:

Monday, February 14, 2011

In the Pipeline

Things have been busy, and I have been way less active on this blog than I intended.

But there's a good side to that: there are some important updates and improvements in the pipeline, and that's what's been keeping me busy...

I have been working in three main areas:

  • A Beta2 release of jQuery Templates, which is planned for April.

    This should address a number of issues and requests that have been expressed. One new feature planned for Beta2 is an API to render a template against data, straight to an HTML string, without any dependency on an HTML DOM. This can then be used for direct insertion as innerHTML, and will also enable easy use of jQuery Templates for rendering on the server, as well as improved performance of jQuery Templates when used in the browser for read-only scenarios.

    At the same time all the power of jQuery Templates will still be there, for those that choose to render templates with the full DOM activation phase included, as at present.

    In the case of server rendering, the idea is that the DOM activation can still happen in the browser, against server-rendered HTML. So progressive enhancement scenarios should be relatively easy to achieve...

  • A Beta2 release of jQuery Data Link, also planned for April.

    This involves significant changes to the current Data Link implementation, with much broader scenario coverage than at present. I hope to push my present code for this new version to a Beta2 branch of jQuery Data Link soon, for those who are curious about the ongoing design.

  • Finally, I have been working on a new script loader: JsDefer.

    You can find the current code for JsDefer here https://github.com/BorisMoore/JsDefer. This script loader shares a number of features with a script loader which we had released a long way back within the Microsoft AJAX platform (see http://aspnet.codeplex.com/releases/view/34488).

    It comes in two versions - a jQuery plugin, and another version that does not require jQuery to be loaded in the page.

    As well as providing some of the features we had in our Microsoft AJAX script loader, JsDefer also takes advantage of the concept of a "Deferred" object, to facilitate working with asynchronous processes (in particular, of course, the process of dynamically fetching a script and loading it into the page). The recent jQuery 1.5 release uses Deferred objects in the context of AJAX requests, so JsDefer is designed to work 'hand in glove' with jQuery 1.5 AJAX requests, among other scenarios. 

I plan to publish a blog post on JsDefer very soon, with an initial dive into how it works and the scenarios it addresses.

Monday, October 4, 2010

jQuery Templates is now an Official jQuery Plugin

Update - October 2011: Please see recent post: "jQuery Templates and JsViews: The Roadmap" for current information on the jQuery Templates roadmap.

Joint announcements were made today by jQuery and Microsoft that jQuery has decided to make the jQuery Templates, Data Link, and Globalization plugins 'Official jQuery Plugins'.

See the following blog announcements for more details:
Of course I am very pleased by this news, which is the result of some active collaboration with members of the jQuery team.

What this means:

A new home for the plugins...

First thing it means, of course, is that the repositories where those plugins live have now moved to a new home. The code that was at GitHub under the http://github.com/nje/ project has been moved to the following repositories under the jQuery project:
The above projects constitute Beta releases of the plugins.

The previous repositories under the http://github.com/nje/ project may continue to exist, but if they do then it will be for exploratory work which may or may not find its way back into the official plugins in a later update.

New documentation on the jQuery API site...

Another very important consequence of this announcement is that from now on, documentation for the jQuery Templates plugin and for the jQuery Data Link plugin will be available on the jQuery API site at http://api.jquery.com.

From today, new documentation is available there, which is much more complete than the previous Wiki provided on our repository.
One goal I have with this blog entry is to give you an idea of how the new documentation for jQuery Templates is organized, and to provide a convenient set of links to the various topics. Each topic concerns either a method from the plugin API, or a template tag that you can use within your template markup to obtain some of the rich features that this plugin provides.

API documentation topics:

Template tag documentation topics:


I hope this new documentation will help you to take advantage of some of the rich features of jQuery Templates.

For extra help I'm expecting soon to provide some more blog entries that continue the series Introducing jQuery Templates...

Thursday, September 23, 2010

Introducing jQuery Templates 1: First Steps


UPDATE: A joint announcement has just been made by jQuery and Microsoft that the jQuery Templates, Data Link and Globalization plugins are now 'Official jQuery Plugins'. In addition, a full set of documentation for the jQuery Templates and Data Link plugins is now available on the http://api.jquery.com/ site. See my next post: jQuery Templates is now an Official jQuery Plugin for details.
In my last post, I said I planned to start a series of posts introducing jQuery Templates. This is the first of that series. This post also introduces the Sample Viewer, which you can use to try out your own jQuery templates. In a sense jQuery Templates consists of three plugins: .tmpl(), .tmplItem() and .template(), and each one comes in two flavors: instance plugin and static plugin. From a basic scenario point of view, it is like this:
  • .tmpl(): Render the template
  • .tmplItem(): Find the template item
  • .template(): Compile/Store the template
The template itself is any HTML markup, along with any of a set of template tags which enable some very rich scenarios for creating data-driven UI. The current set of tags that are supported in jQuery templates are:
  • ${...}: Evaluate fields or expression
  • {{each ...}}...{{/each}}: Iterate without creating template items
  • {{if ...}}...{{else ...}}...{{/if}}: Conditional sections
  • {{html ...}}: Insert markup from data
  • {{tmpl ...}}: Composition, as template items
  • {{wrap ...}}...{{/wrap}}: Composition, plus incorporation of wrapped HTML
This blog will be the first of a series in which I hope to drill into the role of each of those APIs and tags. For this first blog, we'll start with the simplest possible scenario. We'll use just the .tmpl() API, for rendering a template, and the ${...} template tag, for inserting data values into the rendered output... So here goes:

Rendering a template using local data within the page

Here is some data:
var movies = [
    { Name: "The Red Violin", ReleaseYear: "1998" },
    { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
    { Name: "The Inheritance", ReleaseYear: "1976" }
];
Here is some markup to be used as a template:
<script id="movieTemplate" type="text/x-jquery-tmpl">
    <li>
        <b>${Name}</b> (${ReleaseYear})
    </li>
</script>
and a target element where we are going to render the result of rendering the template against our data:
<ul id="results"></ul>
And here is some code to take the template, render it with the data, and append the resulting HTML as content under our target element:
$( "#movieTemplate" ).tmpl( movies )
    .appendTo( "#results" );
In the above code, we get a jQuery wrapped set containing our template markup, and use the .tmpl() plugin method (to which we pass the data) to render the template. Then we chain with the appendTo method to append the results under our target element:
Demo:
    As you see the template got rendered once for each item in the movies array. Data values are inserted using the template tag ${...}. In fact ${expression} inserts the (HTML-encoded) result of evaluating the expression term, in the context of the current item. The template engine actually exposes the current data item as the variable $data, and also exposes each of the fields of the current data item as individual variables. So the most simplest use-case of ${...} is just with a field name as expression, such as ${ReleaseYear}. This is actually equivalent to ${$data.ReleaseYear} and inserts the value of that field on the current data item. Pretty straightforward. Here is the complete code of our example:
    <script src="http://code.jquery.com/jquery.js" type="text/javascript"></script>
    <script src="jquery.tmpl.js" type="text/javascript"></script>
    
    <script id="movieTemplate" type="text/x-jquery-tmpl">
        <li>
            <b>${Name}</b> (${ReleaseYear})
        </li>
    </script>
    
    <ul id="results"></ul>
    
    <script type="text/javascript">
        var movies = [
            { Name: "The Red Violin", ReleaseYear: "1998" },
            { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
            { Name: "The Inheritance", ReleaseYear: "1976" }
        ];
    
        $( "#movieTemplate" ).tmpl( movies )
            .appendTo( "#results" );
    </script>
    

    Playing with the data and the template: Sample Viewer

    To get the feeling of how it works, here is the same demo again, but this time I have used a special Sample Viewer script which is integrated into my blog, so that if you mouse over the demo, you will see a little '+' button that you can click on. The result will be a tabbed view in which you can see the data and the template, as well as the result:
    Demo with Sample Viewer (Mouse over...)
      Try mousing over the demo above, clicking on the '+' button, and modifying the data or the template under the respective tabs. Go back to the result tab and you will see how it renders. Click on the '-' button, and you will be back with the orginal data and template... By the way, this sample viewer is actually implemented using jQuery templates, and illustrates the kind of dynamic interactive client-side UI that can be built very easily with jQuery templates. Maybe at some point I'll reach the point of blogging about how I went about building the sample viewer. But for now, let's get back to just playing with it. For example, if you want to just change the data, and see how the template rendering works with your changes, here are some examples of changes to the data that you could explore:

      Changing the data

      Mouse over the demo above and expand the Sample Viewer. Now try copying and pasting the data examples below into the Data tab, and then switching back to the Result tab. Change values, number of elements etc.
      [
          { "Name": "The BLUE Violin", "ReleaseYear": "1998" }
      ]
      Conclusion: It actually is data-driven :-) Remove some fields and add others:
      [
          { "Name": "The Red Violin", "ReleaseYear": "1998" },
          { "Name": "Eyes Wide Shut"  },
          { "Name": "The Inheritance", "ReleaseYear": "1976", "Director": "Mauro Bolognini" }
      ]
      Conclusion: It ignores the missing/undefined values without error. If you put the value of those fields to null or to the empty string, the result is the same. And of course the added fields have no effect, unless you want to add ${Director} to the template. (Try it...) Replace the array with a single object:
      { Name: "The Red Violin", ReleaseYear: "1998" }
      Conclusion: The templating engine is smart about arrays. Pass an object and it renders the template once, with the object as data item. Pass it an array and it creates a template item (a rendered template) for each of the data items in the array. Set the data to null:
      null
      Conclusion: If you pass no data at all, the templating engine still renders the template once, but the current data item is null. We will see that there are many scenarios where you are just rendering boiler-plate, or where the template pulls in data from other places than the data item, so passing data to the template is not always appropriate or relevant. It may be a nested template, and use data from the parent item. It may have template tags whose parameters are not simple values, but function calls, and the template is driven by the data returned by that function call. For example it might include {{each myApp.getData(foo)}}, or ${myApp.getData(foo)}. In this blog I am staying with much simpler examples, but we will see in later blogs how passing functions to template tags is extremely common. Include some HTML markup in the data:
      { "Name": "The <strong style="color: Red;">Red</strong> Violin", "ReleaseYear": "1998" }
      Conclusion: This does not change the formatting of the text. Instead, it shows the markup in the rendered UI. This is by design: ${expression} HTML-encodes the value before inserting it into the DOM. If you actually want your markup to get inserted into the DOM, then use the {{html ...}} template tag rather than the ${...} template tag. You can try it now: go to the #movieTemplate tab and replace ${Name} by {{html Name}}. Now the markup will not be escaped, and the data will actually get inserted as HTML. (We'll come back to this lower down in the blog). One detail: the sample viewer is using JSON2 to convert between string expressions and JavaScript objects. So the text you are editing above is actually JSON, not JavaScript literals. That's why the keys are wrapped in quotes. Try removing them, and the sample viewer will tell you that you have a syntax error! But in your script, of course, you have literals, and those quotes can be omitted (as long as you avoid JavaScript keywords!)

      Changing the template

      Let's try changing the template, now, rather than the data. For convenience, here is the sample viewer again. This time I set it to show the tabs from the get-go, so you don't need to mouse over and click the '+' button... Sample Viewer
        So try copying and pasting the template examples below into the #movieTemplate tab, and then switching back to the Result tab. Add some text:
        <li>
            <b>${Name}</b> (Released in the year ${ReleaseYear})
        </li>
        Conclusion: It works as you would expect! Add some markup and some formatting:
        <li>
            <b>${Name}</b> (<span style="color: Blue;">${ReleaseYear}<span>)
        </li>
        Conclusion: It works as you would expect... Add simple JavaScript expressions:
        <li>
            <b>${Name.toUpperCase()}</b> (${parseInt(ReleaseYear) + 100})
        </li>
        Conclusion: This works too. You can put JavaScript expressions as parameters to the tags. But don't go overboard! There is not a complete JavaScript parser in the context of inline expressions in the template. If you have complex code, write a function, and call the function from your template, and pass parameters if you need to: ${myFunction(a,b)}. (More on that in a later blog...) Add another template tag:
        <li>
            <b>${Name}</b> (${ReleaseYear}) - Director: ${Director}
        </li>
        Conclusion: Nothing yet - there is no Director field... Now change the data too:
        [
            { "Name": "The Red Violin", "ReleaseYear": "1998", "Director": "Francois Girard" },
            { "Name": "Eyes Wide Shut", "ReleaseYear": "1999", "Director": "Stanley Kubrick" },
            { "Name": "The Inheritance", "ReleaseYear": "1976", "Director": "Mauro Bolognini" }
        ]
        Conclusion: Yes, it works as expected! Finally let's make the change I mentioned in the previous section, and get a 'teaser' on one of the other template tags to be covered in later blogs: the {{html ...}} tag... First, include HTML markup in the data:
        { "Name": "The <strong style='color: Red;'>Red</strong> Violin", "ReleaseYear": "1998" }
        Now change the template to use the {{html ...}} template tag instead of the ${...} template tag:
        <li>
            <b>{{html Name}}</b> (${ReleaseYear})
        </li>
        Conclusion: Thanks to the {{html ...}} tag, you can insert HTML markup into the DOM, as HTML. Combining some of the changes above to data and template, here is a working example that illustrates what you did, and which you can use for exploring further changes: Sample Viewer
          And here is the complete code of our modified example:
          <script src="http://code.jquery.com/jquery.js" type="text/javascript"></script>
          <script src="jquery.tmpl.js" type="text/javascript"></script>
          
          <script id="movieTemplate" type="text/x-jquery-tmpl">
              <li>
                  <b>{{html Name}}</b> 
                  (<span style="color: Blue"> ${ReleaseYear}</span>) - Director: ${Director}
              </li>
          </script>
          
          <ul id="results"></ul>
          
          <script type="text/javascript">
              var movies = [
                  { Name: "The <strong style='color: red'>Red</strong> Violin", ReleaseYear: "1998", Director: "Francois Girard" },
                  { Name: "Eyes Wide Shut", ReleaseYear: "1999", Director: "Stanley Kubrick" },
                  { Name: "The Inheritance", ReleaseYear: "1976", Director: "Mauro Bolognini" }
              ];
          
              $( "#movieTemplate" ).tmpl( movies )
                  .appendTo( "#results" );
          </script>
          

          What's next?...

          Of course we have only just started scratching the surface here. I hope to provide more blogs soon to continue exploring the possibilities of jQuery templates. In the meantime, you can download the code for jQuery templates from http://github.com/jquery/jquery-tmpl.

          Wednesday, September 22, 2010

          From Microsoft to Open Source

          Since earlier this year, I have been working on jQuery Templates, as well as some other contributions to jQuery. The starting point was an initial prototype by John Resig, sometimes referred to as his micro-templating proposal. I hope to follow this post with a series of posts on jQuery Templates.

          But before beginning those posts I wanted to to give some background:

          Microsoft and jQuery

          At Microsoft, we had a pretty cool client templating implementation which Dave Reed and I created. This was part of the Microsoft AJAX Library. The client templates were integrated with live data-linking, and with a script loader. We also worked on some very interesting integration between all that and jQuery, so that if you were using jQuery you could get jQuery-style APIs for the MS AJAX features, and use selectors, fluent-style APIs etc.

          But after reaching the point of releasing Preview 6, and getting very close to a final release, our management team decided to make a radical change. Client-side AJAX platforms are all about performance and optimization of Web requests, and in a sense we were in a contradictory situation. - We were encouraging our developers to use both the MS AJAX platform and jQuery in their client apps, but inevitably there was some overlap and the inclusion of both platforms in their apps was not completely optimal.

          So the change was that from that point on we would not just provide support for using jQuery alongside our own client-side Microsoft AJAX platform. We would instead begin to offer contributions directly to jQuery.

          In fact while jQuery has some very cool features, there were a number of features in our AJAX platform which were not in jQuery, and indeed were pretty much ahead of the curve as far as AJAX platforms in general are concerned - or at least that is my view :-). Amongst those features - our client templates, our concept of observable JavaScript objects and arrays (which we now refer to as "data-linking"), our globalization support, and our script loader.

          Moving to Open Source

          So we began the process of completely redesigning and re-implementing some of those features as pure jQuery plugins or extensions. The goal was very strongly towards lean and clean JavaScript code; to follow JavaScript best-practice for coding - in the sense of optimal use of the JavaScript language itself; and not to attempt to squeeze it into a strongly-typed or object-orientated (in the C# or Java sense) paradigm - or in general bring to bear coding habits and patterns that come from C# and are not really 'at home' in JavaScript code.

          The work is taking place as a true open source effort, hosted on GitHub, and in touch with the community. I have been having a great time as a developer working in that context, and enjoying every minute of it!

          So far we have three projects on GitHub: jQuery Templates, jQuery Data Linking, and jQuery Globalization. We are also working on bringing our original Script Loader code into a form that might be optimal for jQuery. The globalization plugin was announced here, and is already seeing a lot of use. jQuery Templates has been under very active development recently, and will be the subject of some of my upcoming blogs. And jQuery Data-Linking will probably see some more intensive development in the coming weeks, and is likely to include some very interesting integration with jQuery Templates...

          I am looking forward to sharing more of these Open Source efforts with you over the coming weeks, starting with a series of blogs introducing jQuery Templates...