<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>The "Tech. Arch."</title>
	
	<link>http://blog.monnet-usa.com</link>
	<description>Architecting Forward ::&gt;</description>
	<lastBuildDate>Tue, 03 Jan 2012 04:30:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/the-tech-arch" /><feedburner:info uri="the-tech-arch" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Creating Rich Interactive Web Apps With KnockOut.js – Part 4</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/tO61ikj6Csk/</link>
		<comments>http://blog.monnet-usa.com/?p=411#comments</comments>
		<pubDate>Tue, 03 Jan 2012 04:30:00 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[KnockoutJS]]></category>
		<category><![CDATA[rich web apps]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=411</guid>
		<description><![CDATA[Intro 
In part 3 we built a complete working version of the Savings Goal Simulator where each view model and view mediator is nicely separated in its own module and corresponding source file. But what about the view? Well the goal of part 4 is to modularize and extract each view component.

Synopsis Of The Approach [...]]]></description>
			<content:encoded><![CDATA[<h3>Intro <a id='part4-intro'></a></h3>
<p>In <a href='http://blog.monnet-usa.com/?p=404'>part 3</a> we built a complete working version of the <a href="http://savings-goal-simulator.heroku.com/">Savings Goal Simulator</a> where each view model and view mediator is nicely separated in its own module and corresponding source file. But what about the view? Well the goal of part 4 is to <b>modularize</b> and <b>extract each view</b> component.</p>
<p><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-intro1.png" alt="Breaking up [views] is not hard to do ...!" title="Breaking up [views] is not hard to do ...!" /></p>
<h3>Synopsis Of The Approach <a id='part4-approach'></a></h3>
<p>The approach will need to meet the following requirements:</p>
<ol>
<li>The view markup needs to have its own <a href="#part4-view-url"><strong>url</strong></a> and be cacheable</li>
<li>The view markup needs an <a href="#part4-view-id"><strong>ID</strong></a></li>
<li>The view should have an HTML <a href="#part4-view-element"><strong>element</strong></a> </li>
<li>The view HTML element should be <a href="#part4-view-renderable"><strong>renderable</strong></a></li>
</ol>
<h5>View Markup With A URL <a id='part4-view-url'></a></h5>
<p>Just like script blocks and images can be &#8220;sourced&#8221; externally from any url, we need a similar mechanism for our views.</p>
<pre class="brush: javascript">    &lt;view src="http://my.view.html"&gt;
    &lt;/view&gt;
</pre>
<p>So since the <strong>script</strong> tag allow us to do that already, let&#8217;s use it, assign an id, but let&#8217;s use a more appropriate <strong>type</strong> like <strong>text/html</strong>. </p>
<pre class="brush: javascript">    &lt;script src="http://my.view.html"
            type="text/html"&gt;
    &lt;/script&gt;
</pre>
<h5>View Markup With An ID <a id='part4-view-id'></a></h5>
<p>To make it possible to reference the &#8220;script-view-markup&#8221; later on in our page or Javascript code, we&#8217;ll just assign the script an ID like so:</p>
<pre class="brush: javascript">    &lt;script id="my-view-markup"
            src="http://my.view.html"
            type="text/html"&gt;
    &lt;/script&gt;
</pre>
<h5>View HTML Element <a id='part4-view-element'></a></h5>
<p>Now that we have a way to define how a view markup can be &#8220;included&#8221; in our page, we&#8217;ll just define our view &#8220;container&#8221; as a normal HTML element. We can use a &#8220;<strong>div</strong>&#8221; or any of the more semantically significant HTML5 elements like &#8220;<strong>section</strong>&#8220;:</p>
<pre class="brush: javascript">    &lt;div id="my-view"&gt;
    &lt;/div&gt;
</pre>
<p>What we&#8217;re missing is a mechanism to:</p>
<ul>
<li><strong>associate</strong> the view element and the view markup together</li>
<li><strong>render</strong> the actual view</li>
<li>optionally: <strong>data-bind</strong> any view model to the view</li>
</ul>
<h5>Renderable View <a id='part4-view-renderable'></a></h5>
<p>To render the markup for a given view we need a <strong>view rendering engine</strong>. As of this writing, the most prevalent option is <a href="#jqtpl">jQuery Template</a>. </p>
<p><em><u>Note:</u> The <a href="#jqtpl">jQuery Template</a> implementation is rock solid and in use in many production web sites and internal applications. However the <a href="#jqui">jQuery UI</a> core team is in the process of deprecating its use and eventually replace it with another implementation. A serious contender for this is the <a href="#jsrv">jsRender + jsViews</a> library. Other options also include <a href="#musta">Mustache</a> and <a href="#hdbars">Handlebars</a>. Although this tutorial is leveraging jQuery Template as its platform, I recommend you perform some additional due diligence once you&#8217;re ready to settle on library.</em></p>
<p><a href="#ko">KnockoutJS</a> goes one step further by integrating the view rendering engine with data-binding capabilities.</p>
<p><em><u>Note:</u> <a href="#ko">KnockoutJS</a> will allow pluggable view rendering engines over time, making it possible to use the one you choose (as long a as a plugin exists).</em></p>
<p>So <a href="#ko">KnockoutJS</a> can take a <strong>view element</strong> with a corresponding &#8220;<strong>view template</strong>&#8221;  and a <strong>view model</strong>, and render the resulting <strong>view</strong>.</p>
<p>Since we introduced the notion of &#8220;<strong>view template</strong>&#8220;, let&#8217;s spend some time getting familiar with the concept before proceeding with externalized views.</p>
<h3>Introduction To Templating <a id='part4-tpl-intro'></a></h3>
<h5>Simple String-Based Templates <a id='part4-string-tpl'></a></h5>
<p>An string-based template is just a string containing text plus <strong>placeholders</strong> for variables. A <strong>placeholder</strong> is the name of the <strong>variable</strong> surrounded by <strong>curly braces</strong> and a prefixed by a <strong>dollar sign</strong>. So for example a template to display a <strong>time</strong> variable would look like:</p>
<pre class="brush: javascript">    var viewTemplate = "${firstName}, the time is now ${time}"
</pre>
<p>We can group our &#8220;variables&#8221; in a Javascript object literal like so:</p>
<pre class="brush: javascript">    var viewData = { firstName: 'Chris',
                     time:  (new Date()).toLocaleTimeString()
                    }
</pre>
<p>We can get the engine to bind the template and the data like so:</p>
<pre class="brush: javascript">    var viewContent = $.tmpl(viewTemplate, viewData);
</pre>
<p>Finally assuming a div with the id &#8216;my-view&#8217;, jQuery can render the view content like so:</p>
<pre class="brush: javascript">    $('#my-view').html(viewContent);
</pre>
<p>In summary here is a diagram showing the relationships between the various components used in templating:<br />
<br/><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-intro2.png" alt="Template Engine Schematic" title="Template Engine Schematic" /></p>
<p>To try this out yourself:</p>
<ol>
<li>Create a web page named index.html</li>
<li>Add script references to both jQuery and jQuery Template using their content distribution network urls:
<ul>
<li>http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js</li>
<li>http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js</li>
</ul>
</li>
<li>
<p>Add a div with the id &#8216;my-view&#8217; in the body of the page</p>
<pre class="brush: javascript">&lt;div id='my-view'&gt;&lt;/div&gt;
</pre>
</li>
<li>
<p>Add a Javascript script block with a jQuery ready function with our template rendering code:</p>
<pre class="brush: javascript">&lt;script type="text/javascript" &gt;
    $(document).ready(function () {
        var viewTemplate = "${firstName}, the time is now ${time}";
        var viewData = { firstName: 'Chris',
                         time:  (new Date()).toLocaleTimeString()
        }
        var viewContent = $.tmpl(viewTemplate, viewData);
        $("#my-view").html(viewData);
    }
&lt;/script&gt;
</pre>
</li>
</ol>
<p>You should be able to open the <strong>index.html</strong> web page in a browser and the div should now contain the rendered text with the first name and the current time.</p>
<p>Now we have an idea of how templating using jQuery Template is working. But in this example we are just using a string to hold our template. The library actually has a feature where you can store the template in a script tag on the same page.</p>
<h5>Simple Inline Templates <a id='part4-inline-tpls'></a></h5>
<p>The jQuery Template library also allow us to store the template in a script tag with a text/html type like so:</p>
<pre class="brush: javascript">&lt;script id='my-view-template' type='text/html'&gt;
    ${firstName}, the time is now ${time}
&lt;/script&gt;
</pre>
<p>The template can then be rendered with a slightly different form of the <strong>tmpl</strong> API:</p>
<pre class="brush: javascript">var viewContent = $('#my-view-template').tmpl(viewData);
</pre>
<p>Having the template moved out of the code is a step in the right direction, but what we need is the ability to externalize the template to an external url. We&#8217;ll tackle that subject soon I promise, but in the meantime let&#8217;s look at what <a href="#ko">KnockoutJS</a> brings us in terms of additional templating power.</p>
<h5>KnockoutJS Databinding Support For Inline Templates <a id='part4-knockoutjs-tpl-databindng'></a></h5>
<p>Up to now, we have had to write the actual code to: a) <strong>render</strong> the template, and then b) <strong>insert</strong> the resulting text in an HTML element. Well, let&#8217;s see what <a href="#ko">KnockoutJS</a> can do to simplify our task. (This will be very handy especially when your main page has many views.)</p>
<p>As you know, <a href="#ko">KnockoutJS</a> provides a &#8220;<strong>data-bind</strong>&#8221; attribute where you can specify the visual or behavioral <strong>aspects</strong> <em>(e.g. value, text, visible, enable, &#8230;)</em> to <u>link</u> to a <strong>value model</strong> or <strong>dependent observable function</strong>. When we want to data-bind an HTML element to both a template and a view model, we&#8217;ll use the following syntax:</p>
<pre class="brush: javascript">&lt;div id='my-view'
     data-bind='template: { name: "my-view",
                            data: myViewModel }'&gt;
&lt;/div&gt;
</pre>
<p><a id='introToAfterRender'></a>It is even possible to specify a Javascript function in an <a href="#koafterrender"><strong>afterRender</strong></a> template parameter. That function will the be invoked <strong>once the HTML element has been rendered</strong>. This can be useful if you need to <strong>dynamically attach</strong> new behaviors or event handlers to the produced content. For example, you could invoke jQuery UI component configuration APIs such as applying icons for a jQuery UI button.  </p>
<pre class="brush: javascript">&lt;div id='my-view'
     data-bind='template: { name: "my-view",
                            data: myViewModel,
                            afterRender: myViewHookup }'&gt;
&lt;/div&gt;
</pre>
<p>Our view model would then be re-written as follows: </p>
<pre class="brush: javascript">var myViewModel = { firstName: ko.observable('Chris'),
                    time: ko.observable((new Date()).toLocaleTimeString())
}
</pre>
<p>And our &#8220;myViewHookup&#8221; <a href="#koafterrender"><strong>after-render</strong></a> function would have the following form:</p>
<pre class="brush: javascript">function myViewHookup(renderedElements, viewModel) {
    // E.g. highlight the new content for 3 seconds
    renderedElements.effect('highlight',
                            { color: 'LightGreen' },
                            3000);
}
</pre>
<p>And finally our page initialization code would ask <a href="#ko">KnockoutJS</a> to apply the data bindings using the  ko.applyBindings API:</p>
<pre class="brush: javascript">$(document).ready(function () {
    var myViewModel = { firstName: ko.observable('Chris'),
                        time: ko.observable((new Date()).toLocaleTimeString())
    }

    ko.applyBindings(viewModel);
});
</pre>
<p>So when using jQuery, <a href="#jqtpl">jQuery Template</a>, and <a href="#ko">KnockoutJS</a>, we can define a template-based view and data-bind it to a view model so it can be rendered dynamically.</p>
<p><br/><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-intro3.png" alt="Knockout Templating" title="Knockout Templating" /></p>
<p>Now we have covered all but one requirement: the ability to externalize the view template to a specific url.</p>
<h3>Externalized View Templates</h3>
<h5>Basic Mechanism Needed To Externalize A Template</h5>
<p>Let&#8217;s review our simple &#8220;template script markup&#8221;:</p>
<pre class="brush: javascript">&lt;script id='my-view-template' type='text/html'&gt;
    ${firstName}, the time is now ${time}
&lt;/script&gt;
</pre>
<p>What we really need at this point is a way to <strong>externalize</strong> this template into its own file (maybe in a sub-folder named after the parent page, itself organized under a &#8220;<strong>view</strong>&#8221; folder):</p>
<table>
<tr>
<th>/view/mypage/my.view.html</th>
</tr>
<tr>
<td style='padding:4px;border:1px solid #aaa'>${firstName}, the time is now ${time}</td>
</tr>
</table>
<p>We would then just add a <strong>src</strong> tag to our <strong>script</strong> block:</p>
<pre class="brush: javascript">&lt;script id='my-view-template'
        type='text/html'
        src='/view/mypage/_my.view.html' &gt;
&lt;/script&gt;
</pre>
<p>If you try this out you will notice that the browser will indeed [wget] &#8220;<strong>fetch</strong>&#8221; the content of <strong>_my.view.html</strong>, and using the web developer tool of your browser you will actually see the template markup. </p>
<p>But if you try to access the content of the script element using jQuery using:</p>
<pre class="brush: javascript">$("#my-view-template").text()
</pre>
<p>&#8230; you will notice that the content is <strong><em>empty</em></strong>! The browser engine has retrieved the content but <u>did not store</u> it in the actual DOM element for the script. This is due to the fact that a script of type text/html is not recognized as being a script to interpret.</p>
<p>So we need a mechanism to fetch and store the source. The approach consists of re-fetching the source using jQuery&#8217;s <a href="#jqget"><strong>$.get</strong></a> API. Since it was fetched once, the content is stored in the browser&#8217;s cache so retrieval wil be very fast. We then store it in the DOM&#8217;s element.<br />
Here is a simplistic example of what the code would look like:</p>
<pre class="brush: javascript">$(document).ready(function () {
    $.get("/view/mypage/_my.view.html",
                function(data, textStatus, jqXHR) {
                    $("#my-view-template")
                        .text(jqXHR.responseText);
                }
    );
});
</pre>
<p>So finally we can integrate our <a href="#ko">KnockoutJS</a> view model code in the ready function:</p>
<pre class="brush: javascript">$(document).ready(function () {
    $.get("/view/mypage/_my.view.html",
                function(data, textStatus, jqXHR) {
                    $("#my-view-template")
                        .text(jqXHR.responseText);

                    var myViewModel = { firstName: ko.observable('Chris'),
                                        time: ko.observable((new Date()).toLocaleTimeString())
                    }

                    ko.applyBindings(viewModel);
                }
    );
});
</pre>
<p>You now have <strong>externalized</strong> the view template, <strong>dynamically loaded</strong> it, <strong>data-bound</strong> it to a view model using <a href="#ko">KnockoutJS</a>, and <strong>rendered</strong> using the <a href="#jqtpl">jQuery Template</a> engine!</p>
<p>Our example was fairly basic but it illustrates the overall concept and approach. </p>
<h5>Generic ViewLoader Plugin</h5>
<p>The <a href="#viewldr">jQuery ViewLoader</a> plugin will take us even further by providing the ability to:</p>
<ol>
<li>Handle <strong>nested</strong> externalized templates</li>
<li><strong>Parallelize</strong> the processing of each template</li>
<li>Provide a simple way to handle all templates on a page and <strong>synchronize their post-processing</strong> so that the page initialization logic can proceed.</li>
</ol>
<p>Here is what the minimum syntax looks like:</p>
<pre class="brush: javascript">$(document).viewloader({
    logLevel: "debug",
    success: function () {
        ko.applyBindings(viewModel);
    }
});
</pre>
<p>The plugin will identify all scripts of <strong>type text/html</strong> and a source url ending in &#8220;<strong>.view.html</strong>&#8220;, including <strong>nested</strong> template scripts and request their <strong>parallel loading</strong>. Once <strong>all</strong> template scripts have been succesfully <strong>processed</strong> the <strong>success</strong> function is invoked.</p>
<p>Behind the scenes, <a href="#viewldr">jQuery ViewLoader</a> relies on the jQuery concept of <a href="#jqdfd">&#8220;<strong>Deferred</strong>&#8220;</a>, an action which can be <strong>launched for &#8220;deferred&#8221; (i.e. later) execution</strong>, but can <strong>trigger a callback when completed</strong>. Actions can be grouped together so that a specific callback can be triggered once all of them have completed.</p>
<p>Here is a diagram of the approach:<br />
<br/><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-intro4.png" alt="Dynamically Loaded External Templates" title="Dynamically Loaded External Templates" /></p>
<h3>Externalizing The Views Of Our Savings Goal Simulator</h3>
<h5>Intro</h5>
<p>We can now apply the new approach to our <a href="#sgs-site">Savings Goal Simulator</a> web app since it currently contains 3 views:</p>
<ol>
<li>savings-goal-view</li>
<li>consumption-scenarios-view</li>
<li>savings-forecast-view</li>
</ol>
<p>For each view, we will: </p>
<ol>
<li>Create an <strong>externalized template</strong> in the <strong>/view/index</strong> folder based on the view markup</li>
<li>Replace the <strong>view</strong> in index.html by a <strong>template script</strong> reference and a <strong>container DIV</strong> data-bound to the template.</li>
</ol>
<p>Finally, we&#8217;ll update the main <strong>application.js</strong> to plugin the <a href="#viewldr">jQuery ViewLoader</a>.</p>
<p>Here is an outline of the step-by-step approach:</p>
<table class="details_table">
<tr>
<th>#</th>
<th>To Do</th>
<th>Area</th>
</tr>
<tr>
<td><a href="#todo-part4-1">1</a></td>
<td>Create An External Template For The savings-goal-view</td>
<td>View</td>
</tr>
<tr>
<td><a href="#todo-part4-2">2</a></td>
<td>Refactor the savings-goal-view In Our Web Page</td>
<td>View</td>
</tr>
<tr>
<td><a href="#todo-part4-3">3</a></td>
<td>Hookup jQuery ViewLoader In Our Main application.js</td>
<td>Application</td>
</tr>
<tr>
<td><a href="#todo-part4-4">4</a></td>
<td>Refactor The Savings Goal Mediator</td>
<td>View Mediator</td>
</tr>
</table>
<p><a id='todo-part4-1'></a></p>
<h5>1. Create An External Template For The savings-goal-view</h5>
<p>Our first step will be to create a new folder named <strong>view</strong> under <strong>scripts</strong> to organize our external views. Similarly to frameworks like Ruby On Rails, or ASP.NET MVC, we&#8217;ll create a subfolder named <strong>shared</strong>, for all views reusable across pages, then we&#8217;ll create a subfolder named <strong>index</strong> for views appearing on our <strong>index.html</strong> web page.</p>
<p>In the <strong>scripts/view/index</strong> folder, let&#8217;s create a file named <strong>_savings-goal.view.html</strong>. I used an <strong>underscore prefix</strong> to reflect the Rails convention of &#8220;<strong>partial views</strong>&#8221; being prefixed that way.</p>
<p>Then we can copy the <strong>savings-goal-view markup</strong> from <strong>index.html</strong> page and paste it in our new <strong>_savings-goal.view.html</strong> file.</p>
<pre class="brush: javascript">&lt;section id='savings-goal-view' &gt;
    &lt;label for="savings-goal-amount"&gt;Savings Goal Amount:&lt;/label&gt;
    &lt;input id="savings-goal-amount"  /&gt;&lt;br/&gt;

    &lt;label for="savings-max-duration"&gt;Savings Max Duration (In Months):&lt;/label&gt;
    &lt;input id="savings-max-duration" maxlength="3" /&gt;&lt;br/&gt;

    &lt;label for="savings-target-per-month"&gt;Savings Target Per Month:&lt;/label&gt;
    &lt;span id="savings-target-per-month"  /&gt;&lt;br/&gt;
&lt;/section&gt;
</pre>
<p><br/><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-todo1.png" alt="Externalizing savings-goal-view" title="Externalizing savings-goal-view" /></p>
<p>Now we can refactor index.html.</p>
<p><a id='todo-part4-2'></a></p>
<h5>2. Refactor the savings-goal-view In Our Web Page</h5>
<p>In place of our <strong>savings-goal-view</strong> markup, let&#8217;s first add a script reference to the view we just created, and give it an id of savings-goal-view<strong>-template</strong>:</p>
<pre class="brush: javascript">&lt;script id='savings-goal-view-template'
        type='text/html'
        src='scripts/view/index/_savings-goal.view.html' &gt;
&lt;/script&gt;
</pre>
<p>Second, let&#8217;s add a <strong>div</strong> acting as a <strong>container</strong> for our external view. We&#8217;ll give it an id of savings-goal-view<strong>-container</strong>, and declare our KnockoutJS data-binding with the <strong>savings-goal-view-template</strong>:</p>
<pre class="brush: javascript">&lt;div id='savings-goal-view-container'
     data-bind='template: { name: "savings-goal-view-template" } ' &gt;
&lt;/div&gt;
</pre>
<p>Let&#8217;s download:</p>
<ol>
<li>the latest version of jQuery Templates from https://github.com/jquery/jquery-tmpl</li>
<li>the latest version of KnockoutJS from https://github.com/SteveSanderson/knockout</li>
<li>the <a href="#viewldr">jQuery ViewLoader</a> plugin and place it in the <strong>/scripts/vendor</strong> folder.</li>
</ol>
<p>In the index.html page, in the LAB loader section, let&#8217;s:</p>
<ol>
<li>Replace the call to load jQuery Template from our downloaded version (instead of the version from the CDN which is older)</li>
<li>Replace the call to load KnockoutJS from our downloaded version</li>
<li>
<p>Add a call to load the <a href="#viewldr">jQuery ViewLoader</a> plugin:</p>
<pre class="brush: javascript">
&lt;script type="text/javascript"&gt;
$LAB
    .script("http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js").wait()
    // ...
    .script("scripts/vendor/jquery.tmpl.min.js").wait()
    .script("scripts/vendor/knockout-latest.debug.js").wait()
    // ...
    .script("scripts/vendor/jquery.viewloader.js").wait()
    // ...
&lt;/script&gt;
</pre>
</li>
</ol>
<p>Here is how all the piece parts will fit together:</p>
<p><br/><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-todo2.png" alt="Dynamic loading of the savings-goal-view" title="Dynamic loading of the savings-goal-view" /></p>
<p>Ok, now it&#8217;s time to plug in code to get the ViewLoader to load our view.</p>
<p><a id='todo-part4-3'></a></p>
<h5>3. Hookup jQuery ViewLoader In Our Main application.js</h5>
<p>First let&#8217;s create 2 new utility functions in application.js:</p>
<ol>
<li>GetPageSettings &#8211; to retrieve our page settings from the DOM</li>
<li>
<p>SetPageSettings &#8211; to store our page settings in the DOM</p>
<pre class="brush: javascript">function GetPageSettings() {
    return $(document).data("sgs.pagesettings");
}

function SetPageSettings(pageSettings) {
    $(document).data("sgs.pagesettings", pageSettings);
}
</pre>
</li>
</ol>
<p>Let&#8217;s review the <strong>InitializeApplication</strong> function of our main <strong>application.js</strong> module. The core code consists of initializing a pageSettings dictionary and invoking our view mediators.</p>
<p>Let&#8217;s extract that part of the code into a new function named <strong>InitializeViewMediators</strong>:</p>
<pre class="brush: javascript">function InitializeViewMediators() {
    if (typeof(console) != 'undefined' &amp;&amp; console)
        console.info("InitializeViewMediators starting ...");

    // Initialize our page-wide settings
    var pageSettings = { defaultSavingsGoal: 500,
                         defaultSavingsMaxDuration: 6
    }

    // Save the page-wide settings
    SetPageSettings(pageSettings);

    // Create / launch our view mediator(s)
    sgs.mediator.savingsgoal.createViewMediator(pageSettings);
    sgs.mediator.coffeepricing.createViewMediator(pageSettings);
    sgs.mediator.consumptionscenarios.createViewMediator(pageSettings);
    sgs.mediator.savingsforecast.createViewMediator(pageSettings);

    if (typeof(console) != 'undefined' &amp;&amp; console)
        console.info("InitializeViewMediators done ...");
}
</pre>
<p>Let&#8217;s add the code to <strong>InitializeApplication</strong> to <strong>attach</strong> our ViewLoader plugin to the <strong>document</strong> object and invoke <strong>InitializeViewMediators</strong> upon success (i.e. once all views have been loaded):</p>
<pre class="brush: javascript">function InitializeApplication() {
    if (typeof(console) != 'undefined' &amp;&amp; console)
        console.info("InitializeApplication starting ...");

    $(document).viewloader({
        logLevel: "debug",
        success: function (successfulResolution) {
            InitializeViewMediators();
        }
    );

    if (typeof(console) != 'undefined' &amp;&amp; console)
        console.info("InitializeApplication done ...");
}
</pre>
<p>And let&#8217;s add some <strong>logging</strong> code in the <strong>error function</strong> to know when the ViewLoader is failing to load a given view.</p>
<pre class="brush: javascript">function InitializeApplication() {
    // ...

    $(document).viewloader({
        // ...
        success: function (successfulResolution) {
            InitializeViewMediators();
        },
        error: function (failedResolution) {
            if (typeof(console) != 'undefined' &amp;&amp; console) {
                console.error("index.html page failed to load");
            }
        }
    });

    // ...
}
</pre>
<p>Here is the visual depiction of how application.js coordinates with the ViewLoader:</p>
<p><br/><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-todo3.png" alt="Hooking up jQuery ViewLoader with application.js" title="Hooking up jQuery ViewLoader with application.js" /></p>
<p>Not so fast &#8230; if we run the app, we&#8217;ll get an <em>error</em>. This is due to the fact that the code from the <strong>createViewMediator</strong> function of our <strong>sgs.mediator.savingsgoal</strong> module is <em>expecting the view to be available</em>. But at this point in the execution the view as <em>not yet been rendered</em>. This leads us to one more refactoring.</p>
<p><a id='todo-part4-4'></a></p>
<h5>4. Refactor The Savings Goal Mediator</h5>
<p>The current implementation of the <strong>createViewMediator</strong> function of our <strong>sgs.mediator.savingsgoal</strong> module assumes that our view is in the DOM, but at the moment the ViewLoader plugin kicked off the <strong>InitializeViewMediators</strong> function, KnockoutJS <em>has not been requested to apply bindings yet</em> nor <em>render any view templates</em>. </p>
<p>So let&#8217;s refactor the code related to setting up the various data-bindings and invoking KnockoutJS into a new function named <strong>setupViewDataBindings</strong>:</p>
<pre class="brush: javascript">sgs.mediator.savingsgoal.setupViewDataBindings = function() {
    // Declare the HTML element-level data bindings
    $("#savings-goal-amount").attr("data-bind","value: savingsGoalAmount");
    $("#savings-max-duration").attr("data-bind","value: savingsMaxDuration");
    $("#savings-target-per-month").attr("data-bind","text: savingsTargetPerMonthFormatted()");

    // Ask KnockoutJS to data-bind the view model to the view
    var viewNode = $('#savings-goal-view')[0];
    var viewModel = sgs.mediator.savingsgoal.getViewModel();
    ko.applyBindings(viewModel, viewNode);

    // Apply masking to the savings goal amount and max duration input fields
    viewModel.savingsGoalAmountMask.attach($("#savings-goal-amount")[0]);
    viewModel.savingsMaxDurationMask.attach($("#savings-max-duration")[0]); 

    // Initialize default for value models linked to masked fields
    var pageSettings = GetPageSettings();
    viewModel.savingsGoalAmount(pageSettings.defaultSavingsGoal || 0);
    viewModel.savingsMaxDuration(pageSettings.defaultSavingsMaxDuration || 0);

    // Subscribe to interesting value model changes
    viewModel.savingsTargetPerMonthFormatted.subscribe(function() {
        $("#savings-target-per-month")
            .effect('highlight', { color: 'LightGreen' }, 3000); // for 3 seconds
    });

    if (typeof(console) != 'undefined' &amp;&amp; console)
        console.info("sgs.mediator.setupViewDataBindings done!");
}
</pre>
<p>Note: We had to add a new line to <em>access</em> the <strong>viewModel</strong> since it is now available in the DOM and accessible using the sgs.mediator.savingsgoal.<strong>getViewModel</strong> function. We also add to add a line to get the <strong>pageSettings</strong> using our new <strong>GetPageSettings</strong> function.</p>
<p>After having extracted some of the code the <strong>createViewMediator</strong> function consist of the following:</p>
<pre class="brush: javascript">sgs.mediator.savingsgoal.createViewMediator = function (pageSettings, pageViewModel) {
    // Create the view Savings Goal view-specific view model
    var viewModel = sgs.model.savingsgoal.initializeViewModel(pageSettings);

    // Save the view model
    sgs.mediator.savingsgoal.setViewModel(viewModel);   

    if (typeof(console) != 'undefined' &amp;&amp; console) console.info("sgs.mediator.savingsgoal ready!");
}
</pre>
<p>But since we added the <strong>savings-goal-view-container</strong> <strong>div</strong> to the page, we need to handle its <strong>data binding</strong> here. So let&#8217;s do that:</p>
<pre class="brush: javascript">sgs.mediator.savingsgoal.createViewMediator = function (pageSettings, pageViewModel) {
    // Create the view Savings Goal view-specific view model
    var viewModel = sgs.model.savingsgoal.initializeViewModel(pageSettings);

    // Save the view model
    sgs.mediator.savingsgoal.setViewModel(viewModel);   

    // Ask KnockoutJS to data-bind the view model to the view
    var viewNode = $('#savings-goal-view-container')[0];
    ko.applyBindings(viewModel, viewNode);

    if (typeof(console) != 'undefined' &amp;&amp; console) console.info ("sgs.mediator.savingsgoal ready!");
}
</pre>
<p>You probably noticed that there is <strong><em>no call</em></strong> yet to invoke our new <strong>setupViewDataBindings</strong> function! So where will it be invoked then? Well do you remember the comment about KnockoutJS exposing an <strong>afterRender</strong> callback function? (See back in <a href="#introToAfterRender" title="Intro to afterRender">KnockoutJS Databinding Support For Inline Templates</a>.)</p>
<p>We&#8217;ll update the data-binding of <strong>savings-goal-view-container</strong> in our <strong>index.html</strong>, by assigning our new <strong>sgs.mediator.savingsgoal.setupViewDataBindings</strong> function to the <strong>afterRender</strong> attribute:</p>
<pre class="brush: javascript">&lt;div id='savings-goal-view-container'
     data-bind='template: { name: "savings-goal-view-template",
                            afterRender: sgs.mediator.savingsgoal.setupViewDataBindings } ' &gt;
&lt;/div&gt;
</pre>
<p>And now if we re-run our application, we&#8217;ll see in the console that <strong>setupViewDataBindings</strong>  is being called while the <strong>savings-goal-view</strong> is being rendered, after the loading is successfully completed. </p>
<p>Here is an excerpt of the console:</p>
<pre class="brush: javascript">InitializeApplication starting ...
viewloader.loadSourceForPartialView loading source for view: id=savings-goal-view-template src=scripts/view/index/_savings-goal.view.html
InitializeApplication done ...
viewloader.loadSourceForPartialView saving source in savings-goal-view-template
viewloader.loadAllPartialViews executing 'success' function
InitializeViewMediators starting ...
sgs.mediator.setupViewDataBindings done!
sgs.mediator.savingsgoal ready!
...
InitializeViewMediators done ...
</pre>
<p>We have successfully externalized the markup for the savings-goal-view!!!</p>
<p>In summary here is a diagram illustrating the page load processing flow:</p>
<p><br/><img src="./wp-content/media/knockoutjs/savings-goal-simulator-part4-todo4.png" alt="Page Load Processing Flow Recap" title="Page Load Processing Flow Recap" /></p>
<p><a id='todo-part4-5'></a></p>
<h5>5. Recap</h5>
<p>Here is a quick recap of the steps we followed:</p>
<table class="details_table" style="border:1px solid #DDD;border-collapse:collapse;background-color:#FFF;">
<tr>
<th style="border:1px solid #DDD;background-color:#DDD;">#</th>
<th style="border:1px solid #DDD;background-color:#DDD;text-align:left;">To Do</th>
<th style="border:1px solid #DDD;background-color:#DDD;text-align:left;">Area</th>
</tr>
<tr>
<td style="border:1px solid #DDD;vertical-align:top;"><a href="#todo-part4-1">1</a></td>
<td style="border:1px solid #DDD">Create An External Template For The savings-goal-view<br/></p>
<ul>
<li>Create a _your.view.html file</li>
<li>Cut the view markup from your .html and paste it in the .view.html</li>
</ul>
</td>
<td style="border:1px solid #DDD;vertical-align:top;">View</td>
</tr>
<tr>
<td style="border:1px solid #DDD;vertical-align:top;"><a href="#todo-part4-2">2</a></td>
<td style="border:1px solid #DDD">Refactor the savings-goal-view In Our Web Page</p>
<ul>
<li>Add a script tag with an id, a text/html type and point the source to the new .view.html</li>
<li>Create a DIV container and add a data-bind with the template name (id)</li>
</ul>
</td>
<td style="border:1px solid #DDD;vertical-align:top;">View</td>
</tr>
<tr>
<td style="border:1px solid #DDD;vertical-align:top;"><a href="#todo-part4-3">3</a></td>
<td style="border:1px solid #DDD">Hookup jQuery ViewLoader In Our Main application.js</p>
<ul>
<li>Split the view mediators initialization code into a separate InitializeViewMeditors function</li>
<li>Add $(document).viewloader({ // &#8230; }) to InitializeApplication</li>
<li>Call InitializeViewMeditors from the success callback of viewloader</li>
</ul>
</td>
<td style="border:1px solid #DDD;vertical-align:top;">Application</td>
</tr>
<tr>
<td style="border:1px solid #DDD;vertical-align:top;"><a href="#todo-part4-4">4</a></td>
<td style="border:1px solid #DDD">Refactor The Savings Goal Mediator</p>
<ul>
<li>Create a new setupViewDataBindings function to create and apply data bindings inside the view</li>
<li>Trim down createViewMediators to focus only on initializing and storing the view model and asking KnockoutJS to apply the bindings to the view container.</li>
<li>Add an afterRender parameter to the template data-binding to instruct the template engine to invoke the setupViewDataBindings</li>
</ul>
</td>
<td style="border:1px solid #DDD;vertical-align:top;">View Mediator</td>
</tr>
</table>
<p><a id='todo-part4-6'></a></p>
<h5>6. Externalizing The Remaining Views</h5>
<p>Now we just need to repeat the process on our remaining two views:</p>
<ul>
<li>consumption-scenarios-view</li>
<li>savings-forecast-view</li>
</ul>
<p>If you want to follow along with the source code changes, just get code for the <strong>tag</strong> corresponding to any particular step on the <a href="https://github.com/techarch/savings-goal-simulator/tags">GitHub repository</a> for the Savings Goal Simulator.</p>
<h3>So What? <a id='part4-sowhat'></a></h3>
<p><a href="#jqtpl">jQuery Template</a> and <a href="#jqvl">jQuery ViewLoader</a> allow you to structure and load views within a web page.</p>
<p>Externalizing your views makes your web pages more <strong>modular</strong> and <strong>easier to maintain</strong>, especially if you are working within a team as this allows you to assign different views (markup + code) to different individuals.</p>
<p>In the context of a &#8220;single page application&#8221; where you may have many views, these benefits are crucial to help you manage the <strong>complexity</strong> and allow you to <strong>grow</strong> the application <strong>organically</strong> / incrementally.</p>
<p>Another benefit of modularizing your views and view mediators will be that it will be easier to adapt and create different versions of the application for other channels, like a mobile web site or a mobile version of the application (using for example jQuery Mobile and PhoneGap).</p>
<h3>References And Resources</h3>
<h5>jQuery Plugins</h5>
<ul>
<li><a id='jqtpl'></a> <a href="http://api.jquery.com/category/plugins/templates/" title="jQuery Template">jQuery Template</a> : http://api.jquery.com/category/plugins/templates/</li>
<li><a id='jqvl'></a> <a href="http://github.com/techarch/jquery-viewloader" title="jQuery ViewLoader">jQuery ViewLoader</a> : http://github.com/techarch/jquery-viewloader</li>
<li><a id='jsrv'></a> <a href="https://github.com/BorisMoore/jsviews">jsRender + jsViews</a> rendering engine : https://github.com/BorisMoore/jsviews</li>
<li><a id='musta'></a> <a href="http://mustache.github.com/">Mustache</a> rendering engine : http://mustache.github.com/</li>
<li><a id='hdbars'></a> <a href="http://www.handlebarsjs.com/">Handlebars</a> rendering engine : http://www.handlebarsjs.com/</li>
<li><a id='viewldr'></a> <a href="https://github.com/techarch/jquery-viewloader">jQuery ViewLoader</a> rendering engine : https://github.com/techarch/jquery-viewloader</li>
</ul>
<h5>Miscellaneous</h5>
<ul>
<li><a id='jqget'></a> <a href="http://api.jquery.com/jQuery.get/" title="jQuery $.get">jQuery $.get</a> : http://api.jquery.com/jQuery.get/</li>
<li><a id='jqdfd'></a> <a href="http://api.jquery.com/category/deferred-object/" title="jQuery Deferred">jQuery Deferred</a> : http://api.jquery.com/category/deferred-object/</li>
<li><a id='koafterrender'></a> <a href="http://knockoutjs.com/documentation/template-binding.html#note_4_using_the__option" title="KnockoutJS afterRender">KnockoutJS afterRender</a> : http://knockoutjs.com/documentation/template-binding.html#note<em>4</em>using<em>the</em>_option</li>
<li><a id='sgs-site'></a> <a href="http://savings-goal-simulator.heroku.com/" title="Savings Goal Simulator">Savings Goal Simulator</a> : http://savings-goal-simulator.heroku.com/</li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a name='ko-part1' href='http://blog.monnet-usa.com/?p=354'>Creating Rich Interactive Web Apps With KnockOut.js &#8211; Part 1</a></li>
<li><a name='ko-part2' href='http://blog.monnet-usa.com/?p=368'>Creating Rich Interactive Web Apps With KnockOut.js &#8211; Part 2</a></li>
<li><a name='ko-part3' href='http://blog.monnet-usa.com/?p=404'>Creating Rich Interactive Web Apps With KnockOut.js &#8211; Part 3</a></li>
</ul>
<p><a name='kodemosrc'></a></p>
<h5>Full Source Of The Savings Goal Simulator (KnockoutJS Demo)</h5>
<p>The whole application is available on Github under <a href='https://github.com/techarch/savings-goal-simulator' target='_blank'>techarch / savings-goal-simulator</a>.</p>
<div class="blog-msm-ad">
<div class="blog-msm-ad1">
		If you enjoyed this post, I would love it if you could check out <a href="http://bit.ly/myskillsmap">mySkillsMap</a>, my skills management app.
	</div>
<div class="blog-msm-ad2">
			<a href="http://www.myskillsmap.com/take-charge-of-your-skills-development"><br />
				<img src='./wp-content/media/msm/start-your-free-trial-now.png'  /><br />
			</a>
	</div>
</div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/tO61ikj6Csk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=411</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=411</feedburner:origLink></item>
		<item>
		<title>Creating Rich Interactive Web Apps With KnockOut.js – Part 3</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/gDRhtcAYFyo/</link>
		<comments>http://blog.monnet-usa.com/?p=404#comments</comments>
		<pubDate>Sun, 30 Oct 2011 13:44:33 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[KnockoutJS]]></category>
		<category><![CDATA[rich web apps]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=404</guid>
		<description><![CDATA[
						h3 {	text-decoration: underline; }
						h5 {margin-left:20px !important;}
						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}
						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.details_table th
						{
						background-color:lightgray;
						}
						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}

Intro
In Part 1, we introduced the key concepts and patterns including KnockoutJS. In Part 2, we started to build the first increment of our Savings Goal Simulation [...]]]></description>
			<content:encoded><![CDATA[<style>
						h3 {	text-decoration: underline; }</p>
<p>						h5 {margin-left:20px !important;}</p>
<p>						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}</p>
<p>						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.details_table th
						{
						background-color:lightgray;
						}</p>
<p>						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}</p>
</style>
<h3>Intro</h3>
<p>In <a href="http://blog.monnet-usa.com/?p=354" target="_blank">Part 1</a>, we introduced the key concepts and patterns including KnockoutJS. In <a href="http://blog.monnet-usa.com/?p=368" target="_blank">Part 2</a>, we started to build the first increment of our Savings Goal Simulation rich web app. The objectives of this third tutorial are:</p>
<ul>
<li>Build up the rest of the application</li>
<li>Gain more practice with View Models, View Mediators, and KnockoutJS</li>
<li>Incorporate some basic elements of usability</li>
</ul>
<p>Here is the overall target structure of the application:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-overview.png" /><br/></p>
<h3>Building Our App Step-By-Step</h3>
<p>Here is what the app will look like at the end of this tutorial:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part2-6.png" /><br/></p>
<p>Here is an outline of the approach:</p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
<th>Area</th>
</tr>
<tr>
<td><a href='#todo1'>1</a></td>
<td>Create the Consumption Scenarios View</td>
<td>View</td>
</tr>
<tr>
<td><a href='#todo2'>2</a></td>
<td>Create the Consumption Scenarios ViewModel</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo3'>3</a></td>
<td>Create the Consumption Scenarios View Mediator</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo4'>4</a></td>
<td>Link the Page and the View Mediator</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo5'>5</a></td>
<td>Create the Coffee Pricing ViewModel</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo6'>6</a></td>
<td>Create the Coffee Pricing ViewMediator</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo7'>7</a></td>
<td>Link the Page and the Coffee Pricing View Mediator</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo8'>8</a></td>
<td>Leveraging Independent View Models</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo9'>9</a></td>
<td>Create the Savings Forecast View</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo10'>10</a></td>
<td>Create the Savings Forecast ViewModel</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo11'>11</a></td>
<td>Create the Savings Forecast View Mediator</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo12'>12</a></td>
<td>Link the Page and the Savings Forecast View Mediator</td>
<td>Main App</td>
</tr>
</table>
<p></p>
<p>					<a name='todo1'></a></p>
<h5>1. Create the Consumption Scenarios View</h5>
<p>In our <b>index.html</b> page, let&#8217;s add a second section tag to represent our second panel / view: the <b>consumption-scenarios-view</b>.The view will let us enter current habits and see how modifying these habits can yield savings counting towards our saving goal.</p>
<pre class="brush: html">
&lt;body&gt;
	&lt;!-- ... --&gt;
	&lt;section id='consumption-scenarios-view'&gt;
	&lt;/section&gt;
&lt;/body&gt;
</pre>
<p>This is what the view will look like:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part2-1.png" /><br/></p>
<p>Let&#8217;s add a table with 3 columns, one for the dimension to capture and affect (e.g. drink size), one for current habits, and one for our proposed consumption:</p>
<pre class="brush: html">
&lt;body&gt;
	&lt;!-- ... --&gt;
	&lt;section id='consumption-scenarios-view'&gt;
			&lt;header&gt;Weekly Coffee Consumption&lt;/header&gt;

			&lt;table&gt;
				&lt;thead&gt;
					&lt;tr&gt;
						&lt;th&gt;Coffee Options&lt;/th&gt;
						&lt;th&gt;Current Habits&lt;/th&gt;
						&lt;th&gt;Proposed Change&lt;/th&gt;
					&lt;/tr&gt;
				&lt;/thead&gt;

				&lt;tbody&gt;
					&lt;tr&gt;
						&lt;td&gt;Type:&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
					&lt;/tr&gt;

					&lt;tr&gt;
						&lt;td&gt;Size:&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
					&lt;/tr&gt;

					&lt;tr&gt;
						&lt;td&gt;Frequency:&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
					&lt;/tr&gt;

					&lt;tr&gt;
						&lt;td&gt;&lt;label for="drinks-per-day"&gt;Drinks per Day:&lt;/label&gt;&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
					&lt;/tr&gt;

					&lt;tr&gt;
						&lt;td&gt;&lt;label for="cost-per-week"&gt;Cost Per Week:&lt;/label&gt;&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
						&lt;td&gt;&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/tbody&gt;
			&lt;/table&gt;
	&lt;/section&gt;
&lt;/body&gt;
</pre>
<p>Let&#8217;s fill the [Drink] Type row, consisting of sets of radio buttons for Regular, Latte, and Espresso, in both Current and Proposed columns:</p>
<pre class="brush: html">
&lt;tbody&gt;
	&lt;tr&gt;
		&lt;td&gt;Type:&lt;/td&gt;
		&lt;td&gt;
			&lt;div id="current-drink-type"&gt;
				&lt;input type="radio" id="current-drink-regular"  name="CurrentDrinkType" value="Regular" /&gt;
					&lt;label for="current-drink-regular"&gt;Regular&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="current-drink-latte"  name="CurrentDrinkType" value="Latte" /&gt;
					&lt;label for="current-drink-latte"&gt;Latte&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="current-drink-espresso"  name="CurrentDrinkType" value="Espresso" /&gt;
					&lt;label for="current-drink-espresso"&gt;Espresso&lt;/label&gt;&lt;br/&gt;
			&lt;/div&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;div id="proposed-drink-type"&gt;
				&lt;input type="radio" id="proposed-drink-regular"  name="ProposedDrinkType" value="Regular" /&gt;
					&lt;label for="proposed-drink-regular"&gt;Regular&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="proposed-drink-latte"  name="ProposedDrinkType" value="Latte" /&gt;
					&lt;label for="proposed-drink-latte"&gt;Latte&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="proposed-drink-espresso"  name="ProposedDrinkType" value="Espresso" /&gt;
					&lt;label for="proposed-drink-espresso"&gt;Espresso&lt;/label&gt;&lt;br/&gt;
			&lt;/div&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;!-- ... --&gt;
&lt;/tbody&gt;
</pre>
<p>Let&#8217;s fill the [Drink] Size row, consisting of sets of radio buttons for Tall, Grande, and Venti, in both Current and Proposed columns:</p>
<pre class="brush: html">
&lt;tbody&gt;
	&lt;!-- ... --&gt;
	&lt;tr&gt;
		&lt;td&gt;Size:&lt;/td&gt;
		&lt;td&gt;
				&lt;div id="current-drink-size"&gt;
					&lt;input type="radio" id="current-size-tall" 		name="CurrentDrinkSize" value="Tall" /&gt;
						&lt;label for="current-size-tall"&gt;Tall&lt;/label&gt;&lt;br/&gt;
					&lt;input type="radio" id="current-size-grande" 	name="CurrentDrinkSize" value="Grande" /&gt;
						&lt;label for="current-size-grande"&gt;Grande&lt;/label&gt;&lt;br/&gt;
					&lt;input type="radio" id="current-size-venti" 	name="CurrentDrinkSize" value="Venti" /&gt;
						&lt;label for="current-size-venti"&gt;Venti&lt;/label&gt;&lt;br/&gt;
				&lt;/div&gt;
		&lt;/td&gt;
		&lt;td&gt;
				&lt;div id="proposed-drink-size"&gt;
					&lt;input type="radio" id="proposed-size-tall" 		name="ProposedDrinkSize" value="Tall" /&gt;
						&lt;label for="proposed-size-tall"&gt;Tall&lt;/label&gt;&lt;br/&gt;
					&lt;input type="radio" id="proposed-size-grande" 	name="ProposedDrinkSize" value="Grande" /&gt;
						&lt;label for="proposed-size-grande"&gt;Grande&lt;/label&gt;&lt;br/&gt;
					&lt;input type="radio" id="proposed-size-venti" 	name="ProposedDrinkSize" value="Venti" /&gt;
						&lt;label for="proposed-size-venti"&gt;Venti&lt;/label&gt;&lt;br/&gt;
				&lt;/div&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;!-- ... --&gt;
&lt;/tbody&gt;
</pre>
<p>Let&#8217;s fill the [Drink] Frequency row, consisting of sets of radio buttons for Everyday, Monday-through-Friday, and Other (i.e. N days per week), in both Current and Proposed columns:</p>
<pre class="brush: html">
&lt;tbody&gt;
	&lt;!-- ... --&gt;
	&lt;tr&gt;
		&lt;td&gt;Frequency:&lt;/td&gt;
		&lt;td&gt;
			&lt;div id="current-drink-frequency"&gt;
				&lt;input type="radio" id="current-frequency-everyday"	name="CurrentDrinkFrequency" value="Everyday" /&gt;
					&lt;label for="current-frequency-everyday"&gt;Everyday&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="current-frequency-workdays" name="CurrentDrinkFrequency" value="WorkDays" /&gt;
					&lt;label for="current-frequency-workdays"&gt;Mon-Fri&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="current-frequency-other" 		name="CurrentDrinkFrequency" value="Other" /&gt;
					&lt;label for="current-frequency-other"&gt;Other:&lt;/label&gt;
					&lt;input type="text" id="current-custom-frequency" name="CurrentCustomFrequency" /&gt;&lt;br/&gt;
			&lt;/div&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;div id="proposed-drink-frequency"&gt;
				&lt;input type="radio" id="proposed-frequency-everyday"	name="ProposedDrinkFrequency" value="Everyday" /&gt;
					&lt;label for="proposed-frequency-everyday"&gt;Everyday&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="proposed-frequency-workdays" name="ProposedDrinkFrequency" value="WorkDays" /&gt;
					&lt;label for="proposed-frequency-workdays"&gt;Mon-Fri&lt;/label&gt;&lt;br/&gt;
				&lt;input type="radio" id="proposed-frequency-other" 		name="ProposedDrinkFrequency" value="Other" /&gt;
					&lt;label for="proposed-frequency-other"&gt;Other:&lt;/label&gt;
					&lt;input type="text" id="proposed-custom-frequency" name="ProposedCustomFrequency" /&gt;&lt;br/&gt;
			&lt;/div&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;!-- ... --&gt;
&lt;/tbody&gt;
</pre>
<p>Let&#8217;s fill the Drinks Per Day row consisting of an simple input field, in both Current and Proposed columns:</p>
<pre class="brush: html">
&lt;tbody&gt;
	&lt;!-- ... --&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;label for="drinks-per-day"&gt;Drinks per Day:&lt;/label&gt;&lt;/td&gt;
		&lt;td&gt;
				&lt;input type="text" id="current-drinks-per-day" name="CurrentDrinksPerDay" /&gt;
		&lt;/td&gt;
		&lt;td&gt;
				&lt;input type="text" id="proposed-drinks-per-day" name="ProposedDrinksPerDay" /&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;!-- ... --&gt;
&lt;/tbody&gt;
</pre>
<p>Let&#8217;s fill the Cost Per Week row consisting of &lt;div&#038;gt: results elements, in both Current and Proposed columns:</p>
<pre class="brush: html">
&lt;tbody&gt;
	&lt;!-- ... --&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;label for="cost-per-week"&gt;Cost Per Week:&lt;/label&gt;&lt;/td&gt;
		&lt;td&gt;
				&lt;div id="current-cost-per-week"&gt;&lt;/div&gt;
		&lt;/td&gt;
		&lt;td&gt;
				&lt;div id="proposed-cost-per-week"&gt;&lt;/div&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;!-- ... --&gt;
&lt;/tbody&gt;
</pre>
<p>Let&#8217;s fill the Savings Per Week row consisting of &lt;div&#038;gt: results elements, in the Proposed column:</p>
<pre class="brush: html">
&lt;tbody&gt;
	&lt;!-- ... --&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;label for="savings-per-week"&gt;Savings Per Week:&lt;/label&gt;&lt;/td&gt;
		&lt;td&gt;
				&nsbsp;
		&lt;/td&gt;
		&lt;td&gt;
				&lt;div id="savings-per-week"&gt;&lt;/div&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;!-- ... --&gt;
&lt;/tbody&gt;
</pre>
<p>					<a name='todo2'></a></p>
<h5>2. Create the Consumption Scenarios ViewModel</h5>
<p>In the <b>ViewModels</b> folder under the <b>scripts</b> folder, create a file named: <b>sgs.model.consumption-scenarios.js</b>.And let&#8217;s add a statement to load our new module in in our <b>LAB.js</b> section:
					</p>
<pre class="brush: javascript">
$LAB
	// ...
	.script("scripts/viewmodel/sgs.model.savings-goal.js").wait()
	.script("scripts/viewmodel/sgs.model.savings-goal.js").wait()
	.script("scripts/viewmediator/sgs.mediator.savings-goal.js").wait()
	.script("scripts/viewmodel/sgs.model.consumption-scenarios.js").wait()
	// ...
</pre>
<p>Let&#8217;s add the code snippet to lazy-create the namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.model.consumptionscenarios
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.model) == 'undefined') sgs.model = { }
if (typeof(sgs.model.consumptionscenarios) == 'undefined') sgs.model.consumptionscenarios = { }
</pre>
<p>Let&#8217;s create our <b>initializeViewModel</b> function to initialize the view model and its three value models:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo2a.png" /><br/></p>
<ul>
<li><b>currentConsumption</b> will track our current coffee drinking habits</li>
<li><b>proposedConsumption</b> will allow us to experiment to see how much we could save</li>
<li><b>savingsPerWeek</b> will show us the difference between proposed and current costs and will be implemented as a dependent observable function</li>
<li><b>savingsPerMonth</b>(self explanatory)</li>
</ul>
<p>For now let&#8217;s just assign currentConsumption and proposedConsumption to a <b>ko.observable(null)</b> for now &#8211; we&#8217;ll change that <a href="#todo2c">later</a> (once we create the needed sub-view model).</p>
<pre class="brush: javascript">
sgs.model.consumptionscenarios.initializeViewModel = function (pageSettings) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	var viewModel = {
		currentConsumption: 	ko.observable(null),
		proposedConsumption: 	ko.observable(null)
	};

	// Stub implementation to be fully implemented later on
	viewModel.savingsPerWeek = ko.dependentObservable(function() {
		var result = 0;
		return result;
	}, viewModel);

	viewModel.savingsPerMonth = ko.dependentObservable(function() {
		var perMonth = this.savingsPerWeek() * 4;
		var result = Math.round(perMonth * 100) / 100;
		return result;
	}, viewModel);

	return viewModel;
}
</pre>
<p>We need a way to model our coffee consumption.<br />
					So we&#8217;ll create a new module file named <b>sgs.model.coffee-consumption.js</b> under <b>scripts/viewmodel</b>.<br />
					And let&#8217;s add a statement to load our new module in in our <b>LAB.js</b> section (right before consumption-scenarios):
					</p>
<pre class="brush: javascript">
$LAB
	// ...
	.script("scripts/viewmodel/sgs.model.coffee-consumption.js").wait()
	.script("scripts/viewmodel/sgs.model.consumption-scenarios.js").wait()
	// ...
</pre>
<p>Let&#8217;s add the code snippet to lazy-create the namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.model.coffeeconsumption
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.model) == 'undefined') sgs.model = { }
if (typeof(sgs.model.coffeeconsumption) == 'undefined') sgs.model.coffeeconsumption = { }

if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.model.coffeeconsumption loading!");
</pre>
<p>Let&#8217;s create our <b>initializeViewModel</b> function to initialize the view model based on the pageSettins as well as a scenario name. We&#8217;ll have the following value models:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo2b.png" /><br/></p>
<ul>
<li>scenarioName &#8211; will be either Current or Proposed</li>
<li>drinkType</li>
<li>drinkSize</li>
<li>drinkFrequency</li>
<li>customFrequency</li>
<li>drinksPerDay</li>
</ul>
<pre class="brush: javascript">
sgs.model.coffeeconsumption.initializeViewModel = function (pageSettings, scenarioName) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	var viewModel = {
		scenarioName: 		ko.observable(scenarioName),
		drinkType: 			ko.observable("Regular"),
		drinkSize: 			ko.observable("Tall"),
		drinkFrequency: 	ko.observable("Everyday"),
		customFrequency:	ko.observable(1),
		drinksPerDay: 		ko.observable(1)
	}

	return viewModel;
}
</pre>
<p>Let&#8217;s add two dependent observable functions named <b>drinkHasStandardSize</b> (will allow us to later restrict the drink size options based on the drink type) and <b>drinkDaysPerWeek</b> (will allow to calculate the cost per week):</p>
<pre class="brush: javascript">
sgs.model.coffeeconsumption.initializeViewModel = function (pageSettings, scenarioName) {
	// ...

	var viewModel = {
		// ...
	}

	viewModel.drinkHasStandardSize = ko.dependentObservable(function() {
		return this.drinkType() != 'Espresso';
	}, viewModel);

	viewModel.drinkDaysPerWeek = ko.dependentObservable(function() {
		var count = 0;

		switch(this.drinkFrequency()) {
			case "Everyday":
				count = 7;
				break;

			case "WorkDays":
				count = 5;
				break;

			case "Other":
				count = this.customFrequency();
				break;
		}

		return count;
	}, viewModel);

	return viewModel;
}
</pre>
<p>I encourage you to test as you develop along , whether or not you are using a TDD or BDD approach (and framework like <a href="#js-jasmie">Jasmine</a>). So refresh your browser and in the Firebug (or Webkit browser) console, instantiate a <b>sgs.model.coffeeconsumption</b> view model and invoke its <b>drinkDaysPerWeek</b> dependent observable like so:</p>
<pre class="brush: javascript">
var cs = sgs.model.coffeeconsumption.initializeViewModel()
cs.drinkDaysPerWeek()
</pre>
<p>You can also step through the code in the debugger if you really want to check out what happens.</p>
<p>Now let&#8217;s move on and add a stub for a third dependent observable function named: <b>costPerWeek</b></p>
<pre class="brush: javascript">
sgs.model.coffeeconsumption.initializeViewModel = function (pageSettings, scenarioName) {
	// ...

	var viewModel = {
		// ...
	}

	// ...

	// Stub implementation to be fully implemented later on
	viewModel.costPerWeek = ko.dependentObservable(function() {
		var result = 0;
		return result;
	}, viewModel);

	return viewModel;
}
</pre>
<p>Later on we&#8217;ll come back to this view model and complete the stub implementation of the <b>costPerWeek</b> dependentObservable function to calculate the actual cost of the consumption model (based on pricing).</p>
<p>					<a name="todo2c"></a></p>
<p>Now let&#8217;s go back to the <b>initializeViewModel</b> of our <b>sgs.model.consumptionscenarios</b> module and update the value model definitions to use custom instantiations of the sgs.model.coffeeconsumption view model so that the relationship between the two view models looks like this:</p>
<p>										<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo2c.png" /><br/></p>
<pre class="brush: javascript">
sgs.model.consumptionscenarios.initializeViewModel = function (pageSettings) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	var current 	= sgs.model.coffeeconsumption.initializeViewModel (pageSettings, "Current");
	var proposed 	= sgs.model.coffeeconsumption.initializeViewModel (pageSettings, "Proposed");

	var viewModel = {
		currentConsumption: 	ko.observable(current),
		proposedConsumption: 	ko.observable(proposed)
	}

	// Stub implementation to be fully implemented later on
	viewModel.savingsPerWeek = ko.dependentObservable(function() {
		var result = 0;
		return result;
	}, viewModel);

	viewModel.savingsPerMonth = ko.dependentObservable(function() {
		var perMonth = this.savingsPerWeek() * 4;
		var result = Math.round(perMonth * 100) / 100;
		return result;
	}, viewModel);

	return viewModel;
}
</pre>
<p>So now you have implemented an example of hierarchical view model! Again I invite you to test it using the browser Javascript console and debugger.</p>
<p>					<a name='todo3'></a></p>
<h5>3. Create the Consumption Scenarios View Mediator</h5>
<p>Let&#8217;s tackle the view mediator and connect the parts!<br/>In the <b>ViewMediator</b> folder under the <b>scripts</b> folder, create a file named: <b>sgs.mediator.consumption-scenarios.js</b>.<br />
					This is the module where we&#8217;ll place our data-binding logic as well as any code related to mediating access between<br />
					the page, the consumption scenario view, and its view model.<br/><br />
					And let&#8217;s add a statement to load our new module in in our <b>LAB.js</b> section:
					</p>
<pre class="brush: javascript">
$LAB
	// ...
	.script("scripts/viewmodel/sgs.model.consumption-scenarios.js").wait()
	.script("scripts/viewmediator/sgs.mediator.consumption-scenarios.js").wait()
	// ...
</pre>
<p>Let&#8217;s define our namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.mediator.consumptionscenarios
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.mediator) == 'undefined') sgs.mediator = { }
if (typeof(sgs.mediator.consumptionscenarios) == 'undefined') sgs.mediator.consumptionscenarios = { }

if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.consumptionscenarios loading!");
</pre>
<p>Let&#8217;s create our <b>createViewMediator</b> function (per our convention) which we will eventually invoke from the <b>InitializeApplication</b> method in <b>application.js</b>. The createViewMediator function will have 4 responsibilities:</p>
<ol>
<li>Instantiate a view model for the consumption scenarios view</li>
<li>Declare the data-binding between the HTML elements of the view and their corresponding value models in the view model</li>
<li>Ask KnockoutJS to make the bindings effective (they will be live right after that)</li>
<li>Save off the view model so we can access it from other parts of the app</li>
</ol>
<p>So let&#8217;s implement the first responsibility to instantiate a view model for the consumption scenario view (using the <b>initializeViewModel</b> function we just created in the consumption scenario view model module).</p>
<pre class="brush: javascript">
sgs.mediator.consumptionscenarios.createViewMediator = function (pageSettings) {
	// Create the view Consumption Scenarios view-specific view model
	var viewModel = sgs.model.consumptionscenarios.initializeViewModel(pageSettings);
}
</pre>
<p>Now let&#8217;s declare the data-bindings we need. For <b>input</b> elements we used the <b>value</b> attribute in our <b>data-bind</b> declaration, but since we have some radio buttons, it is the <b>checked</b> attribute of <b>each radio button</b> we need to target. Note that our binding will have a level of indirection via the <b>currentConsumption</b> value model, which is itself a view model with value models like <b>drinkType</b>. Here is what a snippet looks like for the radio buttons located inside the <b>current-drink-type</b> div:</p>
<pre class="brush: javascript">
sgs.mediator.consumptionscenarios.createViewMediator = function (pageSettings) {
	// Create the view Consumption Scenarios view-specific view model
	var viewModel = sgs.model.consumptionscenarios
		.initializeViewModel(pageSettings);

	// Declare the HTML element-level data bindings for the Current Habits column
	$("#current-drink-type input[type=radio]")
		.attr("data-bind",
				"checked: currentConsumption().drinkType");
</pre>
<p>Let&#8217;s finish up the rest of the bindings:</p>
<pre class="brush: javascript">
	// ...

	// Declare the HTML element-level data bindings for the Current Habits column
	$("#current-drink-type  input[type=radio]")
		.attr("data-bind","checked: currentConsumption().drinkType");
	$("#current-drink-size input[type=radio]")
		.attr("data-bind","checked: currentConsumption().drinkSize");
	$("#current-drink-frequency input[type=radio]")
		.attr("data-bind","checked: currentConsumption().drinkFrequency");
	$("#current-custom-frequency")
		.attr("data-bind","value: currentConsumption().customFrequency");
	$("#current-drinks-per-day")
		.attr("data-bind","value: currentConsumption().drinksPerDay");
	$("#current-cost-per-week")
		.attr("data-bind","text: currentConsumption().costPerWeek");

	// Declare the HTML element-level data bindings for the Proposed Change column
	$("#proposed-drink-type input[type=radio]")
		.attr("data-bind","checked: proposedConsumption().drinkType");
	$("#proposed-drink-size input[type=radio]")
		.attr("data-bind","checked: proposedConsumption().drinkSize");
	$("#proposed-drink-frequency input[type=radio]")
		.attr("data-bind","checked: proposedConsumption().drinkFrequency");
	$("#proposed-custom-frequency")
		.attr("data-bind","value: proposedConsumption().customFrequency");
	$("#proposed-drinks-per-day")
		.attr("data-bind","value: proposedConsumption().drinksPerDay");
	$("#proposed-cost-per-week")
		.attr("data-bind","text: proposedConsumption().costPerWeek");
	$("#savings-per-week")
		.attr("data-bind","text: savingsPerWeek");

	// ...
</pre>
<p>Let&#8217;s add a new kind of binding attribute: &#8220;<b>enable</b>&#8220;, which allow us to control whether or not the data-bound HTML element should be enabled. This is a very useful binding as it will simplify enabling/disabling rules a lot. Here we&#8217;ll use it to control whether or not the drink size radio buttons should be enabled, since an espresso does not typically come in a Tall / Grande / Venti size! (Wow imagine the buzz on Venti!)<br/><br/><br />
					<u>Reminder:</u> The syntax of data-bind in KnockoutJS is:
					</p>
<pre class="brush: javascript">
databind="attribute1: valueModel1, attribute2: valueModel2, etc." // comma-separated list
</pre>
<p>This means that we will need to <b>comma-separate</b> and <b>concatenate</b> our new &#8220;<b>attribute: valueModel</b>&#8221; binding pair at the end of our existing declaration for the &#8220;checked&#8221; attribute like so:
</p>
<pre class="brush: javascript">
	// ...

	// Declare the HTML element-level data bindings for the Current Habits column
	// ...
	$("#current-drink-size input[type=radio]")
		.attr("data-bind","checked: currentConsumption().drinkSize " +
						", enable: currentConsumption().drinkHasStandardSize");
	// ...

	// Declare the HTML element-level data bindings for the Proposed Change column
	// ...
	$("#proposed-drink-size input[type=radio]")
		.attr("data-bind","checked: proposedConsumption().drinkSize" +
						", enable: proposedConsumption().drinkHasStandardSize");

	// ...
</pre>
<p><u>Caution</u>: the name of the attribute is &#8220;<b>enable</b>&#8221; <i>(not &#8220;enabled&#8221; &#8211; I have been bit by that many times)</i>!</p>
<p>Now we&#8217;ll ask KnockoutJS to &#8220;apply&#8221;, i.e. register / enable our bindings. </p>
<pre class="brush: javascript">
sgs.mediator.consumptionscenarios.createViewMediator = function (pageSettings) {
	// ...

	// Ask KnockoutJS to data-bind the view model to the view
	var viewNode = $('#consumption-scenarios-view')[0];
	ko.applyBindings(viewModel, viewNode);
}
</pre>
<p>Now let&#8217;s add the 2 functions to store retrieve our consumption scenarios view model:</p>
<pre class="brush: javascript">
sgs.mediator.consumptionscenarios.getViewModel = function() {
	return $(document).data("sgs.model.consumptionscenarios.viewmodel");
}

sgs.mediator.consumptionscenarios.setViewModel = function(viewModel) {
	$(document).data("sgs.model.consumptionscenarios.viewmodel", viewModel);
}
</pre>
<p>Now we can call the <b>setViewModel</b> function from inside <b>createViewMediator</b> to save off our freshly-created view model.</p>
<pre class="brush: javascript">
sgs.mediator.consumptionscenarios.createViewMediator = function (pageSettings) {
	// ...

	// Save the view model
	sgs.mediator.consumptionscenarios.setViewModel(viewModel);	

	if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.coffeeconsumption ready!");
}
</pre>
<p>If you want to test the mediator, just refresh the browser, and invoke the <b>createViewMediator</b> in the browser Javascript console like so:</p>
<pre class="brush: javascript">
sgs.mediator.consumptionscenarios.createViewMediator({})
</pre>
<p>You will then see the radio buttons get set to their default value. And clicking on the Espresso radio button should cause the Size radio buttons to become disabled.</p>
<p>					<a name='todo4'></a></p>
<h5>4. Link the Page and the Consumptions Scenarios View Mediator</h5>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo4.png" /><br/></p>
<p>To instantiate our new mediator, we just need to add a call to the overall page <b>InitializeApplication</b> function (located in our <b>scripts/application.js</b>) to our consumption scenario <b>createViewMediator</b> function like so:</p>
<pre class="brush: javascript">
function InitializeApplication() {
	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication starting ...");

	// Initialize our page-wide settings
	var pageSettings = { defaultSavingsGoal: 500 }

	// Create / launch our view mediator(s)
	sgs.mediator.savingsgoal.createViewMediator(pageSettings);
	sgs.mediator.consumptionscenarios.createViewMediator(pageSettings);

	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication done ...");
}
</pre>
<p>So now you should be able to load your index.html page in Firefox with the Firebug console on and watch the debug statement and finally our new consumption scenarios view displays with our default values:
					</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part2-2.png" /><br/></p>
<p>					<a name='todo5'></a></p>
<h5>5. Create the Coffee Pricing ViewModel</h5>
<p>Now we need a pricing engine! It needs to ake into account : the drink type and drink size. And we can apply frequency and drinks per day to calculate the cost. To keep logic encapsulated, let&#8217;s create a new module file in the <b>scripts/viewmodel</b> folder named <b>sgs.model.coffee-pricing.js</b>. The new module will be responsible for:
					</p>
<ol>
<li>having a default example pricing list for the various coffee options</li>
<li>providing its own view model with a <b>pricing</b> value model</li>
<li>loading / saving its content to the browser local storage (using <a href="#js-jstorage">jStorage</a>, a cross-browser HTML 5 local storage abstraction library)</li>
</ol>
<p>Let&#8217;s add the code snippet to lazy-create the namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.model.coffeeconsumption
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.model) == 'undefined') sgs.model = { }
if (typeof(sgs.model.coffeepricing) == 'undefined') sgs.model.coffeepricing = { }

if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.model.coffeepricing loading!");
</pre>
<p>Update the LAB.js section of the index.html page so we can load the new module (before sgs.model.coffee-consumption):</p>
<pre class="brush: html">
	$LAB
		// ...
		.script("scripts/viewmodel/sgs.model.coffee-pricing.js").wait()
		.script("scripts/viewmodel/sgs.model.coffee-consumption.js").wait()
		// ...
</pre>
<p>Now we&#8217;ll create an <b>examplePricing</b> function which will return a hash of key-value pairs where the key will be a composite of the coffee type and size, and the value an amount.</p>
<pre class="brush: javascript">
sgs.model.coffeepricing.examplePricing = function() {
	var priceList = {
		"Regular-Tall": 1.40,
		"Regular-Grande": 1.60,
		"Regular-Venti": 1.70,

		"Latte-Tall": 2.55,
		"Latte-Grande": 3.10,
		"Latte-Venti": 3.40,

		"Espresso": 1.75,
		"EspressoShot": 0.25
	}

	return priceList;
}
</pre>
<p>Now let&#8217;s define our initializeViewModel function with a place holder for the price list:</p>
<pre class="brush: javascript">
sgs.model.coffeepricing.initializeViewModel = function (pageSettings) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	var priceList = { }
	var viewModel = {
		pricing: 		ko.observable(priceList)
	}

	return viewModel;
}
</pre>
<p>Ok, now we want to check if we have a price list in local storage and lazy-initialize it otherwise. We&#8217;ll encapsulate the logic in a function named: <b>getPriceList</b>. We&#8217;ll try to retrieve the &#8220;<b>coffee-price-list</b>&#8221; using <b>$.jStorage.get(key)</b> API:</p>
<pre class="brush: javascript">
sgs.model.coffeepricing.getPriceList = function () {
	// Check if we have ever stored the price list locally
	var priceList = $.jStorage.get("coffee-price-list");

	if (priceList == null) {
		// If not create an example
		priceList = sgs.model.coffeepricing.examplePricing();

		// Save it off
		$.jStorage.set("coffee-price-list", priceList);
	}

	return priceList;
}
</pre>
<p>So now we can edit our in <b>initializeViewModel</b> function and plug in the <b>getPriceList</b> for the initialization of the <b>pricing</b> value model:</p>
<pre class="brush: javascript">
sgs.model.coffeepricing.initializeViewModel = function (pageSettings) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	// Lazy-initialize the price list
	var priceList = sgs.model.coffeepricing.getPriceList();

	var viewModel = {
		pricing: 		ko.observable(priceList)
	}

	return viewModel;
}
</pre>
<p>To encapsulate pricing data requests, let&#8217;s add a &#8220;normal&#8221; function (i.e. not an dependent observable) named <b>getCoffeeBeveragePrice</b> to our view model:</p>
<pre class="brush: javascript">
sgs.model.coffeepricing.initializeViewModel = function (pageSettings) {
	// ...

	viewModel.getCoffeeBeveragePrice = function (drinkType, drinkSize) {
		var key = drinkType;

		if (drinkType != 'Espresso' &#038;&#038; drinkSize) {
			key += '-' + drinkSize;
		}

		var price = viewModel.pricing()[key];
		return price;
	}

	return viewModel;
}
</pre>
<p>Once reloading the index.html page, you should be able to experiment with jStorage. To see all keys stored with jStorage (should be an empty array initially):</p>
<pre class="brush: javascript">
$.jStorage.index()
</pre>
<p>Now, let&#8217;s make a call to <b>sgs.model.coffeepricing.getPriceList()</b>. This will lazy-initialize the price list and store it. So when asking for the jStorage index a second time the console should display an array with our &#8220;<b>coffee-price-list</b>&#8221; key. And we can access the value for our key using:</p>
<pre class="brush: javascript">
sgs.model.coffeepricing.getPriceList()
$.jStorage.index()
$.jStorage.get("coffee-price-list")
</pre>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part2-3.png" /><br/></p>
<p>					<a name='todo6'></a></p>
<h5>6. Create the Coffee Pricing ViewMediator</h5>
<p>In the <b>Viewmediator</b> folder under the <b>scripts</b> folder, create a file named: <b>sgs.mediator.coffee-pricing.js</b>. This is the module where we&#8217;ll place our data-binding logic as well as any code related to mediating access between the page, a future pricing editing view, and its view model.<br/> And let&#8217;s add a statement to load our new module in in our <b>LAB.js</b> section:
					</p>
<pre class="brush: javascript">
$LAB
	// ...
	.script("scripts/viewmodel/sgs.model.coffee-pricing.js").wait()
	.script("scripts/viewmediator/sgs.mediator.coffee-pricing.js").wait()
	// ...
</pre>
<p>Let&#8217;s define our namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.mediator.coffeepricing
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.mediator) == 'undefined') sgs.mediator = { }
if (typeof(sgs.mediator.coffeepricing) == 'undefined') sgs.mediator.coffeepricing = { }

if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.coffeepricing loading!");
</pre>
<p>Let&#8217;s create our <b>createViewMediator</b> function (per our convention) which we will eventually invoke from the <b>InitializeApplication</b> method in <b>application.js</b>. The createViewMediator function will have 3 responsibilities:</p>
<ol>
<li>Instantiate a view model for the future pricing editor view</li>
<li>Ask KnockoutJS to make the bindings effective (they will be live right after that)</li>
<li>Save off the view model so we can access it from other parts of the app</li>
</ol>
<p>Note: this mediator will not need to setup any data-bindings with the view, since we are not planning on displaying the pricing. However, the <b>consumption scenario mediator</b> will collaborate with it in order to access its <b>pricing view model</b>.</p>
<p>So let&#8217;s implement the first responsibility to instantiate a view model<br />
					(using the <b>initializeViewModel</b> function we just created in the coffee pricing view model module).</p>
<pre class="brush: javascript">
sgs.mediator.coffeepricing.createViewMediator = function (pageSettings) {
	// Create the view Pricing Editor view-specific view model
	var viewModel = sgs.model.coffeepricing.initializeViewModel(pageSettings);
}
</pre>
<p>Now let&#8217;s add the 2 functions to store retrieve our coffee pricing view model:</p>
<pre class="brush: javascript">
sgs.mediator.coffeepricing.getViewModel = function() {
	return $(document).data("sgs.model.coffeepricing.viewmodel");
}

sgs.mediator.coffeepricing.setViewModel = function(viewModel) {
	$(document).data("sgs.model.coffeepricing.viewmodel", viewModel);
}
</pre>
<p>Now we can use the setViewModel function inside createViewMediator to save off our freshly-created view model.</p>
<pre class="brush: javascript">
sgs.mediator.coffeepricing.createViewMediator = function (pageSettings) {
	// ...

	// Save the view model
	sgs.mediator.coffeepricing.setViewModel(viewModel);	

	if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.coffeepricing ready!");
}
</pre>
<p>					<a name='todo7'></a></p>
<h5>7. Link the Page and the Coffee Pricing View Mediator</h5>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo7.png" /><br/></p>
<p>To instantiate our new mediator, we just need to add a call to the overall page <b>InitializeApplication</b> function (located in our <b>scripts/application.js</b>) to our coffee pricing <b>createViewMediator</b> function like so:</p>
<pre class="brush: javascript">
function InitializeApplication() {
	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication starting ...");

	// Initialize our page-wide settings
	var pageSettings = { defaultSavingsGoal: 500 }

	// Create / launch our view mediator(s)
	sgs.mediator.savingsgoal.createViewMediator(pageSettings);
	sgs.mediator.coffeepricing.createViewMediator(pageSettings);
	sgs.mediator.consumptionscenarios.createViewMediator(pageSettings);

	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication done ...");
}
</pre>
<p>					<a name='todo8'></a></p>
<h5>8. Leveraging Independent View Models</h5>
<p>At this point we have created the consumption, scenarios, and pricing view models, but we have not yet &#8220;connected&#8221; all the parts to allow for the <b>costPerWeek</b> value model of <b>coffeeconsumption</b> to work. Before we proceed let&#8217;s review a few requirements and guiding principles:</p>
<ul>
<li>The consumptionscenarios view model knows about the <b>current</b> and <b>proposed</b> coffee consumptions</li>
<li>The coffeeconsumption view model has the <b>costPerWeek</b> dependent observable function</li>
<li>The coffeepricing view model has the <b>pricing</b></li>
<li>The coffeepricing view mediator manages access to its view model</li>
<li>We want to keep the view models from knowing about the mediators</li>
<li>Over time, we may want to test different pricing models in each scenario</li>
</ul>
<p>So to maintain isolation but yet gain some flexibility we will:</p>
<ol>
<li>Add a <b>pricing</b> value model to the <b>coffeeconsumption</b> view model &#8211; this way costPerWeek will have access to it</li>
<li>Add a <b>pricing</b> value model to the <b>consumptionscenarios</b> view model &#8211; this way it can pass it on each of the current and proposed consumptions models</li>
<li>Add a <b>subscription</b> to the <b>pricing change</b> in the <b>consumptionscenarios</b> view model so we can update the pricing of the current and proposed consumptions models</li>
<li>Have the consumption-scenario and coffee pricing view mediators <b>share the pricing</b> view model</li>
</ol>
<p>Here is what the relationship between the various mediators and model will look like:</p>
<p>										<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo8.png" /><br/></p>
<p>First, let&#8217;s add a <b>pricing</b> value model to the <b>coffeeconsumption</b> view model (located in <b>scripts/viewmodel/sgs.model.coffeeconsumption.js</b>):</p>
<pre class="brush: javascript">
sgs.model.coffeeconsumption.initializeViewModel = function (pageSettings, scenarioName) {
	// ...

	var viewModel = {
		pricing: 		ko.observable(null),
		scenarioName: 	ko.observable(scenarioName),
		// ...
	}

	// ...
}
</pre>
<p>Second, let&#8217;s add a <b>pricing</b> value model to the <b>consumptionscenarios</b> view model (located in <b>scripts/viewmodel/sgs.model.consumptionscenarios.js</b>)</p>
<pre class="brush: javascript">
sgs.model.consumptionscenarios.initializeViewModel = function (pageSettings) {
	// ...

	var viewModel = {
		pricing: 				ko.observable(null),
		currentConsumption: 	ko.observable(current),
		proposedConsumption: 	ko.observable(proposed)
	}

	// ...
}
</pre>
<p>Third, let&#8217;s add a <b>subscription</b> to <b>pricing</b> value model so we can re-act to pricing model changes and pass the new pricing down to our 2 consumption models:</p>
<pre class="brush: javascript">
sgs.model.consumptionscenarios.initializeViewModel = function (pageSettings) {
	// ...

	viewModel.pricing.subscribe(function(newPricing) {
		viewModel.currentConsumption().pricing(newPricing);
		viewModel.proposedConsumption().pricing(newPricing);
	});

	// ...
}</pre>
<p>Fourth, let&#8217;s have the <a href="">consumption-scenario view mediator</a> set the <b>pricing</b> based on the view model of the <b>coffee pricing view mediator</b>:</p>
<pre class="brush: javascript">
sgs.mediator.consumptionscenarios.createViewMediator = function (pageSettings) {
	// ...

	// Save the view model
	sgs.mediator.consumptionscenarios.setViewModel(viewModel);	

	// Set the pricing based on the Coffee Pricing view model
	var priceList = sgs.mediator.coffeepricing.getViewModel();
	viewModel.pricing(priceList);

	// ...
}
</pre>
<p>So now we have the bits in place to fully implement the <b>costPerWeek</b> function of the <b>coffeeconsumption</b> view model. (Remember we had just put in a stub implementation returning 0 in step <a href="#todo2">&#8220;2. Create the Consumption Scenarios ViewModel&#8221;</a>). It&#8217;s a matter of performing the calculations like so:</p>
<pre class="brush: javascript">
sgs.model.coffeeconsumption.initializeViewModel = function (pageSettings, scenarioName) {
	// ...

	viewModel.costPerWeek = ko.dependentObservable(function() {
		// Get the base price
		if (this.pricing() == null) {
			return 0;
		}

		var basePrice 	= this.pricing().getCoffeeBeveragePrice(this.drinkType(), this.drinkSize());
		var dailyCost 	= basePrice * this.drinksPerDay();
		var weeklyCost	= dailyCost * this.drinkDaysPerWeek();
		var result 		= Math.round(weeklyCost * 100) / 100;

		return result;
	}, viewModel);

	return viewModel;
}
</pre>
<p>And finally we can go back and finish the implementation of the <b>savingsPerWeek</b> function in the <b>consumptionscenarios</b> view model. (Remember we had just put in a stub implementation returning 0 in step <a href="#todo2">&#8220;2. Create the Consumption Scenarios ViewModel&#8221;</a>)</p>
<pre class="brush: javascript">
sgs.model.consumptionscenarios.initializeViewModel = function (pageSettings) {
	// ...

	viewModel.savingsPerWeek = ko.dependentObservable(function() {
		var costDifference = this.currentConsumption().costPerWeek() - this.proposedConsumption().costPerWeek();
		var result = Math.round(costDifference * 100) / 100;
		return result;
	}, viewModel);

	// ...

	return viewModel;
}
</pre>
<p>Now we&#8217;re ready to refresh the index.html page, select Grande Latte under Current Habits and Tall Regular under Proposed Changes and you should see the costs update as well as the savings. We now have a functioning Weekly Coffee Consumption panel! :-)</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part2-4.png" /><br/></p>
<p>I will leave the following usability additions for you to do:</p>
<ul>
<li>Formatting of the costs and saving amounts (dependent observables and Accounting.js &#8211; see <a href="http://blog.monnet-usa.com/?p=368#todo9" target='_blank'>Part 1 ToDo #9 &#8211; Applying Formatting Rules</a>)</li>
<li>Add visual feedback (using the jQuery highlight effect) for the costs and savings fields see <a href="http://blog.monnet-usa.com/?p=368#todo10" target='_blank'>Part 1 ToDo #10 &#8211; Applying Visual Feedback Clues</a></li>
<li>Overall styling</li>
</ul>
<p>					<a name='todo9'></a></p>
<h5>9. Create the Savings Forecast View</h5>
<p>In our <b>index.html</b> page, let&#8217;s add a second section tag to represent our third panel / view:<br />
					the <b>savings-forecast-view</b>.<br />
					The view will help us compare projected savings against our goal.</p>
<pre class="brush: html">
&lt;body&gt;
	&lt;!-- ... --&gt;
	&lt;section id='savings-forecast-view'&gt;
	&lt;/section&gt;
&lt;/body&gt;
</pre>
<p>This is what the view will look like:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part2-5.png" /><br/></p>
<p>The view will have three pairs of labels and spans to show calculated values for:</p>
<ul>
<li>Savings forecast per month</li>
<li>Forecast variance from the target monthly savings goal</li>
<li>Forecasted number of months to achieve the savings goal</li>
</ul>
<pre class="brush: html">
			&lt;label for="savings-forecast-per-month"&gt;Savings Forecast Per Month:&lt;/label&gt;
			&lt;span id="savings-forecast-per-month" &gt;&lt;/span&gt;&lt;br/&gt;

			&lt;label for="forecast-variance-per-month"&gt;Forecast Variance:&lt;/label&gt;
			&lt;span id="forecast-variance-per-month"&gt;&lt;/span&gt;&lt;br/&gt;

			&lt;label for="time-to-goal-in-months"&gt;Months To Savings Goal:&lt;/label&gt;
			&lt;span id="time-to-goal-in-months"&gt;&lt;/span&gt;&lt;br/&gt;
</pre>
<p>					<a name='todo10'></a></p>
<h5>10. Create the Savings Forecast ViewModel</h5>
<p>In the <b>ViewModels</b> folder under the <b>scripts</b> folder, create a file named: <b>sgs.model.savings-forecast.js</b>.<br />
					And let&#8217;s add a statement to load our new module in in our <b>LAB.js</b> section:
					</p>
<pre class="brush: javascript">
$LAB
	// ...
	.script("scripts/viewmodel/sgs.model.savings-forecast.js").wait()
	// ...
</pre>
<p>Let&#8217;s add the code snippet to lazy-create the namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.model.savingsforecast
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.model) == 'undefined') sgs.model = { }
if (typeof(sgs.model.savingsforecast) == 'undefined') sgs.model.savingsforecast = { }

if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.model.savingsforecast loading!");
</pre>
<p>Let&#8217;s create our <b>initializeViewModel</b> function to initialize the view model.<br />
					We need two dependent observable functions:</p>
<ul>
<li><b>forecastVariancePerMonth</b> will allow us to experiment to see how much we could save</li>
<li><b>timeToGoalInMonths</b> will show us the difference between proposed and current costs and will be implemented as a dependent observable function</li>
</ul>
<p>										<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo10.png" /><br/></p>
<pre class="brush: javascript">
sgs.model.savingsforecast.initializeViewModel = function (pageSettings) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	var viewModel = {
	};	

	viewModel.forecastVariancePerMonth = ko.dependentObservable(function() {
		// TBD
	}, viewModel);

	viewModel.timeToGoalInMonths = ko.dependentObservable(function() {
		// TBD
	}, viewModel);

	return viewModel;
}
</pre>
<p>Design Note: in this series of tutorial I have promoted the idea of <b>decoupling all views, models, and mediators</b> (as possible) as it makes the application <b>more modular</b> and it is <b>easier to test</b> all parts independently. So for this view model, instead of requesting the value models from other mediators namely <b>savingsGoalAmount</b>, <b>savingsTargetPerMonth</b> and  <b>savingsPerMonth</b>, we will create dedicated value models which will later synchronize with using subscriptions in our mediators &#8211; since it is ok for the mediators to collaborate.
					</p>
<pre class="brush: javascript">
sgs.model.savingsforecast.initializeViewModel = function (pageSettings) {
	// ...

	var viewModel = {
		savingsGoalAmount: ko.observable(0),
		savingsTargetPerMonth: ko.observable(0),
		savingsPerMonth: ko.observable(0)
	};	

	// ...

	return viewModel;
}
</pre>
<p>Let&#8217;s flesh-out our calculations:</p>
<pre class="brush: javascript">
sgs.model.savingsforecast.initializeViewModel = function (pageSettings) {
	// ...	

	viewModel.forecastVariancePerMonth = ko.dependentObservable(function() {
		var variance = this.savingsPerMonth() - this.savingsTargetPerMonth();
		var result = Math.round(variance * 100) / 100;
		return result;
	}, viewModel);

	viewModel.timeToGoalInMonths = ko.dependentObservable(function() {
		var timeToGoal = 0;
		var savingsPerMonth = this.savingsPerMonth();
		var savingsGoalAmount = this.savingsGoalAmount();

		if (savingsPerMonth != 0) {
			timeToGoal = savingsGoalAmount / savingsPerMonth;
		}
	}, viewModel);

	// ...
}
</pre>
<p>					<a name='todo11'></a></p>
<h5>11. Create the Savings Forecast View Mediator</h5>
<p>In the <b>Viewmediator</b> folder under the <b>scripts</b> folder, create a file named: <b>sgs.mediator.savings-forecast.js</b>. This is the module where we&#8217;ll place our data-binding logic as well as any code related to mediating access between the page, the consumption scenario view, and its view model.<br/> And let&#8217;s add a statement to load our new module in in our <b>LAB.js</b> section:
					</p>
<pre class="brush: javascript">
$LAB
	// ...
	.script("scripts/viewmodel/sgs.model.savings-forecast.js").wait()
	.script("scripts/viewmediator/sgs.mediator.savings-forecast.js").wait()
	// ...
</pre>
<p>Let&#8217;s define our namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.mediator.savingsforecast
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.mediator) == 'undefined') sgs.mediator = { }
if (typeof(sgs.mediator.savingsforecast) == 'undefined') sgs.mediator.savingsforecast = { }

if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.savingsforecast loading!");
</pre>
<p>Let&#8217;s create our <b>createViewMediator</b> function (per our convention) which we will eventually invoke from the <b>InitializeApplication</b> method in <b>application.js</b>. The createViewMediator function will have 5 responsibilities:</p>
<ol>
<li>Instantiate a view model for the savings forecast view</li>
<li>Establish subscriptions for various value models to keep the main view model synchronized</li>
<li>Declare the data-binding between the HTML elements of the view and their corresponding value models in the view model</li>
<li>Ask KnockoutJS to make the bindings effective (they will be live right after that)</li>
<li>Save off the view model so we can access it from other parts of the app</li>
</ol>
<p>So let&#8217;s implement the first responsibility to instantiate a view model for the consumption scenario view  (using the <b>initializeViewModel</b> function we just created in the consumption scenario view model module).</p>
<pre class="brush: javascript">
sgs.mediator.savingsforecast.createViewMediator = function (pageSettings) {
	// Create the view Savings Forecast view-specific view model
	var viewModel = sgs.model.savingsforecast.initializeViewModel(pageSettings);
}
</pre>
<p>Now we need to establish <b>3 subscriptions</b> so that we can keep our saving forecast view model in synch with value models from the <b>savings goal</b>  and <b>consumption scenarios</b> view models. Here is a graphical depiction of what we need:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo11.png" /><br/></p>
<p>To make this happen we need the <b>savingsforecast mediator</b> to request specific value models from the view models of the <b>savingsgoal</b> and <b>consumptionsscenarios</b> mediators:</p>
<pre class="brush: javascript">
sgs.mediator.savingsforecast.createViewMediator = function (pageSettings) {
	// ...

	// Subscribe to changes in savingsGoalAmount and savingsTargetPerMonth
	// to synchronize our own equivalent value models
	var savingsGoalModel = sgs.mediator.savingsgoal.getViewModel();

	// Initialize the current savingsGoalAmount
	viewModel.savingsGoalAmount(savingsGoalModel.savingsGoalAmount());

	savingsGoalModel.savingsGoalAmount.subscribe(function(newValue) {
		viewModel.savingsGoalAmount(newValue);
	});

	savingsGoalModel.savingsTargetPerMonth.subscribe(function(newValue) {
		viewModel.savingsTargetPerMonth(newValue);
	});

	// Subscribe to changes in savingsPerMonth to synchronize our own equivalent value model
	var consumptionscenariosModel = sgs.mediator.consumptionscenarios.getViewModel();
	consumptionscenariosModel.savingsPerMonth.subscribe(function(newValue) {
		viewModel.savingsPerMonth(newValue);
	});

	// ...
}
</pre>
<p>Now let&#8217;s declare the data-bindings we need.</p>
<pre class="brush: javascript">
sgs.mediator.savingsforecast.createViewMediator = function (pageSettings) {
	// Create the view Savings Forecast view-specific view model
	var viewModel = sgs.model.savingsforecast
		.initializeViewModel(pageSettings);

	// Declare the HTML element-level data bindings
	$("#savings-forecast-per-month")
		.attr("data-bind","text: savingsPerMonth");
	$("#forecast-variance-per-month")
		.attr("data-bind","text: forecastVariancePerMonth");
	$("#time-to-goal-in-months")
		.attr("data-bind","text: timeToGoalInMonths");

	// ...
</pre>
<p>Now we&#8217;ll ask KnockoutJS to &#8220;apply&#8221;, i.e. register / enable our bindings. </p>
<pre class="brush: javascript">
sgs.mediator.savingsforecast.createViewMediator = function (pageSettings) {
	// ...

	// Ask KnockoutJS to data-bind the view model to the view
	var viewNode = $('#savings-forecast-view')[0];
	ko.applyBindings(viewModel, viewNode);
}
</pre>
<p>Now let&#8217;s add the 2 functions to store retrieve our savings forecast view model:</p>
<pre class="brush: javascript">
sgs.mediator.savingsforecast.getViewModel = function() {
	return $(document).data("sgs.model.savingsforecast.viewmodel");
}

sgs.mediator.savingsforecast.setViewModel = function(viewModel) {
	$(document).data("sgs.model.savingsforecast.viewmodel", viewModel);
}
</pre>
<p>Now we can use the setViewModel function inside createViewMediator to save off our freshly-created view model.</p>
<pre class="brush: javascript">
sgs.mediator.savingsforecast.createViewMediator = function (pageSettings) {
	// ...

	// Save the view model
	sgs.mediator.savingsforecast.setViewModel(viewModel);	

	if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.savingsforecast ready!");
}
</pre>
<p>Again you can try your new mediator using the browser console:</p>
<pre class="brush: javascript">
sgs.mediator.savingsforecast.createViewMediator({})
</pre>
<p>Playing with the simulation should now update the savings-forecast view.</p>
<p>					<a name='todo12'></a></p>
<h5>12. Link the Page and the Savings Forecast View Mediator</h5>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part3-todo12.png" /><br/></p>
<p>To instantiate our new mediator, we just need to add a call to the overall page <b>InitializeApplication</b> function (located in our <b>scripts/application.js</b>) to our consumption scenario <b>createViewMediator</b> function like so:</p>
<pre class="brush: javascript">
function InitializeApplication() {
	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication starting ...");

	// Initialize our page-wide settings
	var pageSettings = { defaultSavingsGoal: 500 }

	// Create / launch our view mediator(s)
	sgs.mediator.savingsgoal.createViewMediator(pageSettings);
	sgs.mediator.coffeepricing.createViewMediator(pageSettings);
	sgs.mediator.consumptionscenarios.createViewMediator(pageSettings);
	sgs.mediator.savingsforecast.createViewMediator(pageSettings);

	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication done ...");
}
</pre>
<p>Now you can refresh your page and should be able to see the new savings forecast view update as you experiment!</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part2-6.png" /><br/></p>
<hr />
<h5>Overall Recap</h5>
<p>In this part 3 of the tutorial we have added quite a bit more functionality and complexity. Hopefully the modularization, separation into different files and folders, the namespacing, and various patterns are now starting to reveal their purpose and value. ;-)<br/> So here is a quick recap of the steps we followed:</p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
<th>Area (Module)</th>
</tr>
<tr>
<td><a href='#todo1'>1</a></td>
<td>Create the Consumption Scenarios View</td>
<td>View</td>
</tr>
<tr>
<td><a href='#todo2'>2</a></td>
<td>Create the Consumption Scenarios ViewModel</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo3'>3</a></td>
<td>Create the Consumption Scenarios View Mediator</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo4'>4</a></td>
<td>Link the Page and the View Mediator</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo5'>5</a></td>
<td>Create the Coffee Pricing ViewModel</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo6'>6</a></td>
<td>Create the Coffee Pricing ViewMediator</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo7'>7</a></td>
<td>Link the Page and the Coffee Pricing View Mediator</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo8'>8</a></td>
<td>Leveraging Independent View Models</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo9'>9</a></td>
<td>Create the Savings Forecast View</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo10'>10</a></td>
<td>Create the Savings Forecast ViewModel</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo11'>11</a></td>
<td>Create the Savings Forecast View Mediator</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo12'>12</a></td>
<td>Link the Page and the Savings Forecast View Mediator</td>
<td>Main App</td>
</tr>
</table>
<p>					<a name='sowhat'></a></p>
<h3>So What?</h3>
<p>This part 3 gave you a lot more practice with the core patterns and also showed you the following:</p>
<ul>
<li>Create hierarchical view models</li>
<li>Setup custom subscriptions to keep independent view models synchronized</li>
<li>Configure multiple attributes inside a data-bind declaration (e.g. checked and enabled)</li>
<li>Leverage jStorage for local browser data caching</li>
</ul>
<p>If we step back and look at the <b>modularization</b> of our application so far, we&#8217;ll notice that although our models and view mediators are modular, the actual index.html web page has become larger and is not modular at all. Wouldn&#8217;t it be nice if we could extract each of our views into external modules? Well, this is exactly what <a href="#">part 4</a> will cover!</p>
<ul>
<li>Leveraging jQuery templates</li>
<li>Extracting views into templates (and in separate files)</li>
<li>&#8230; and more!</li>
</ul>
<p>So stay tuned!</p>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>Patterns</h5>
<ul>
<li><a name='mvvmp' href='http://en.wikipedia.org/wiki/Model_View_ViewModel'>Model View &#8211; ViewModel Pattern</a></li>
<li><a name='mvcp' href='http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html'>MVC Xerox Parc 1978-79</a></li>
<li><a name='mvcp' href='http://c2.com/cgi/wiki?ModelViewController'>MVC Pattern</a></li>
<li><a name='obp' href='http://c2.com/cgi/wiki?ObserverPattern'>Observer Pattern</a></li>
<li><a name='psp' href='http://c2.com/cgi/wiki?PublishSubscribeModel'>Publish Subscribe Pattern</a></li>
<li><a name='vmp' href='http://c2.com/cgi/wiki?ValueModel'>Value Model Pattern</a></li>
<li><a name='dbp' href='http://c2.com/cgi/wiki?DataBinding'>Data Binding Pattern</a></li>
<li><a name='ns-summary' href='http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/'>Summary of Namespacing Approaches (by Elijah Manor)</a></li>
<li><a name='ns-objectliteral' href='http://stackoverflow.com/questions/881515/javascript-namespace-declaration/881556#881556'>Namespacing using Object Literals</a></li>
<li><a name='ns-function' href='http://stackoverflow.com/questions/881515/javascript-namespace-declaration/881611#881611'>Namespacing using Functions</a></li>
</ul>
<h5>Frameworks And Blogs</h5>
<ul>
<li><a name='ko' href='http://knockoutjs.com/'>KnockoutJS</a></li>
<li><a name='lko' href='http://learn.knockoutjs.com/'>Learn KnockoutJS (Interactive Tutorial / Playground)</a></li>
<li><a name='jq' href='http://jquery.com/'>jQuery</a></li>
<li><a name='jqui' href='http://jqueryui.com/'>jQuery UI</a></li>
<li><a name='jqt' href='http://api.jquery.com/jQuery.template/'>jQuery Template</a></li>
<li><a name='jqtapi' href='http://api.jquery.com/jQuery.template/'>jQuery Template API</a></li>
<li><a name='ss' href='http://blog.stevensanderson.com/'>Knock Me Out (Steve Sanderson&#8217;s Blog)</a></li>
<li><a name='kmo' href='http://www.knockmeout.net/'>Knock Me Out (Ryan Niemeyer&#8217;s Blog)</a></li>
<li><a name='pflsjaa' href='http://addyosmani.com/blog/patterns-for-large-scale-javascript-application-architecture/'>Patterns For Large-Scale Javascript Architecture (Addy Osmani)</a></li>
</ul>
<p>					<a name="javascript-loaders" ></a></p>
<h5>Javascript Loaders</h5>
<ul>
<li><a name='headjs' href='http://headjs.com/' target='_blank'>HeadJS</a></li>
<li><a name='labjs' href='http://labjs.com/' target='_blank'>LABjs</a></li>
<li><a name='lazyload' href='https://github.com/rgrove/lazyload' target='_blank'>LazyLoad</a></li>
<li><a name='jquery-cookie' href='https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js' target='_blank'>jQuery Cookie</a></li>
</ul>
<p>					<a name="jquery-plugins" ></a></p>
<h5>jQuery Plugins</h5>
<ul>
<li><a name='jquery-blockui' href='http://jquery.malsup.com/block/' target='_blank'>jQuery BlockUI</a></li>
<li><a name='jquery-cookie' href='https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js' target='_blank'>jQuery Cookie</a></li>
<li><a name='jquery-datatables' href='http://datatables.net/' target='_blank'>jQuery DataTables</a></li>
<li><a name='jquery-hotkeys' href='https://github.com/tzuryby/jquery.hotkeys' target='_blank'>jQuery HotKeys</a></li>
<li><a name='jquery-tree' href='http://www.jstree.com/' target='_blank'>jQuery jsTree</a></li>
<li><a name='jquery-validate' href='http://plugins.jquery.com/project/jqueryvalidate' target='_blank'>jQuery Validate</a></li>
</ul>
<p>					<a name="other-js-libraries" ></a></p>
<h5>Other Javascript Libraries</h5>
<ul>
<li><a name='js-modernizr' href='http://www.modernizr.com/' target='_blank'>Modernizr</a></li>
<li><a name='js-blockui' href='http://jquery.malsup.com/block/' target='_blank'>BlockUI</a></li>
<li><a name='js-accounting' href='http://josscrowcroft.github.com/accounting.js/' target='_blank'>Accounting.js</a></li>
<li><a name='js-currencymask' href='https://github.com/techarch/CurrencyMaskJS' target='_blank'>CurrencyMask JS</a></li>
<li><a name='jquery-maskedinput' href='http://digitalbush.com/projects/masked-input-plugin/' target='_blank'>Masked Input</a></li>
<li><a name='js-raphael' href='http://raphaeljs.com/' target='_blank'>Raphael JS</a></li>
<li><a name='js-graphael' href='http://g.raphaeljs.com/' target='_blank'>gRaphael JS</a></li>
<li><a name='js-storage' href='https://github.com/andris9/jStorage' target='_blank'>jStorage</a></li>
<li><a name='js-underscore' href='http://documentcloud.github.com/underscore/' target='_blank'>Underscore</a></li>
<li><a name='js-fixtures' href='http://jupiterjs.com/news/organizing-a-jquery-application#news/ajax-fixtures-plugin-for-jquery' target='_blank'>Ajax Fixtures</a></li>
</ul>
<p>					<a name="js-test-frameworks" ></a></p>
<h5>Javascript Test Frameworks</h5>
<ul>
<li><a name='js-jasmine' href='http://http://pivotal.github.com/jasmine/' target='_blank'>Jasmine, BDD for Javascript</a></li>
<li><a name='js-jasmine-species' href='http://rudylattae.github.com/jasmine-species/' target='_blank'>Jasmine Species, BDD Grammar Extensions (Given, When, Then, etc.)</a></li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a name='ko-part1' href='http://blog.monnet-usa.com/?p=354'>Creating Rich Interactive Web Apps With KnockOut.js &#8211; Part 1</a></li>
<li><a name='ko-part2' href='http://blog.monnet-usa.com/?p=368'>Creating Rich Interactive Web Apps With KnockOut.js &#8211; Part 2</a></li>
</ul>
<p>					<a name='kodemosrc'></a></p>
<h5>Full Source Of The Savings Goal Simulator (KnockoutJS Demo)</h5>
<p>The whole application is available on Github under <a href='https://github.com/techarch/savings-goal-simulator' target='_blank'>techarch / savings-goal-simulator</a>.</p>
<div class="blog-msm-ad">
<div class="blog-msm-ad1">
							If you enjoyed this post, I would love it if you could check out <a href="http://bit.ly/myskillsmap">mySkillsMap</a>, my skills management app.
						</div>
<div class="blog-msm-ad2">
								<a href="http://www.myskillsmap.com/take-charge-of-your-skills-development"><br />
									<img src='./wp-content/media/msm/start-your-free-trial-now.png'  /><br />
								</a>
						</div>
</p></div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/gDRhtcAYFyo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=404</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=404</feedburner:origLink></item>
		<item>
		<title>Creating Rich Interactive Web Apps With KnockOut.js – Part 2</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/pIDq8V5J-20/</link>
		<comments>http://blog.monnet-usa.com/?p=368#comments</comments>
		<pubDate>Tue, 18 Oct 2011 03:29:18 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[rich web apps]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=368</guid>
		<description><![CDATA[
						h3 {	text-decoration: underline; }
						h5 {margin-left:20px !important;}
						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}
						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.details_table th
						{
						background-color:lightgray;
						}
						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}

Intro
In Part 1 of &#8220;Creating Rich Interactive Web Apps With KnockOut.js&#8221;, I reviewed some of the key patterns you need to consider such as: MVC, Model View [...]]]></description>
			<content:encoded><![CDATA[<style>
						h3 {	text-decoration: underline; }</p>
<p>						h5 {margin-left:20px !important;}</p>
<p>						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}</p>
<p>						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.details_table th
						{
						background-color:lightgray;
						}</p>
<p>						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}</p>
</style>
<h3>Intro</h3>
<p>In <a href="http://blog.monnet-usa.com/?p=354" target="_blank">Part 1 of &#8220;Creating Rich Interactive Web Apps With KnockOut.js&#8221;</a>, I reviewed some of the key patterns you need to consider such as: <a name='mvcp' href='http://c2.com/cgi/wiki?ModelViewController' target='_blank'>MVC</a>, <a name='mvvmp' href='http://en.wikipedia.org/wiki/Model_View_ViewModel' target='_blank'>Model View &#8211; ViewModel</a>, <a name='obp' href='http://c2.com/cgi/wiki?ObserverPattern' target='_blank'>Observer</a>, <a name='psp' href='http://c2.com/cgi/wiki?PublishSubscribeModel' target='_blank'>Publish Subscribe</a>, <a name='vmp' href='http://c2.com/cgi/wiki?ValueModel' target='_blank'>Value Model</a>, <a name='dbp' href='http://c2.com/cgi/wiki?DataBinding' target='_blank'>Data Binding</a>.</p>
<p>					<img src="./wp-content/media/knockoutjs/patterns.png" /><br/></p>
<p>In this second post, we will cover the following topics while creating a fun app:</p>
<ul>
<li>Architecting our  application so it can easily be extended over time</li>
<li>Splitting the logic according to separations of concerns</li>
<li>Incorporating rudimentary elements of usability</li>
</ul>
<h3>For The Price Of N Cups of Coffee &#8230;</h3>
<p>To illustrate the various concepts, we&#8217;ll create a simulator application to figure out how we can tweak our coffee consumption habits to save a given amount of money over a period of time.
					</p>
<p>Note: You can try the app at: <a href='http://savings-goal-simulator.heroku.com/' target='_blank'>savings-goal-simulator.heroku.com</a> and inspect / play with it in Firebug. The full source is also available on Github under <a href='https://github.com/techarch/savings-goal-simulator' target='_blank'>techarch / savings-goal-simulator</a>.</p>
<h3>Building Our App Step-By-Step</h3>
<p>Here is an outline of the approach:</p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
<th>Area</th>
</tr>
<tr>
<td><a href='#todo1'>1</a></td>
<td>Create a Shell Application</td>
<td>Main app</td>
</tr>
<tr>
<td><a href='#todo2'>2</a></td>
<td>Organize our Application Code</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo3'>3</a></td>
<td>Create the Savings Goal View</td>
<td>View</td>
</tr>
<tr>
<td><a href='#todo4'>4</a></td>
<td>Create the Savings Goal ViewModel</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo5'>5</a></td>
<td>Create the Savings Goal View Mediator</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo6'>6</a></td>
<td>Link the Page and the View Mediator</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo7'>7</a></td>
<td>Apply Data Masking Business Rules</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo8'>8</a></td>
<td>Apply Custom Masking Rules</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo9'>9</a></td>
<td>Applying Formatting Rules</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo10'>10</a></td>
<td>Providing Visual Feedback Cues</td>
<td>View Mediator</td>
</tr>
</table>
<p>					<br/><br />
					Thanks to <a href="http://susanpotter.net/" target='_blank'>Susan Potter</a>&#8216;s suggestion of tagging the source code on Github, you can download the source corresponding to the application as of the end of each &#8220;todo&#8221; step! You can find the list of tags <a href="https://github.com/techarch/savings-goal-simulator/tags" target='_blank'>here</a>.<br />
					<br/></p>
<p>					<a name='todo1'></a></p>
<h5>1. Create a Shell Application</h5>
<p>Note: In this tutorial we will de-emphasize the server framework side and focus on browser considerations.<br/><br />
					So let&#8217;s start:</p>
<ol>
<li>Create a root folder for our application named <b>savings-goal-simulator</b></li>
<li>Create a file named <b>index.html</b> for our main page</li>
<li>Create a folder for our Javascript files named <b>scripts</b></li>
<li>Create a sub-folder under <b>scripts</b> for our vendor Javascript libraries named <b>vendor</b></li>
<li>Add the basic markup for a page in <b>index.html</b></li>
</ol>
<p>					<a name='vendor-libraries'></a></p>
<p>Ok, now we&#8217;re ready to add our key <b>external Javascript libraries</b>.<br />
					Here is the basic minimum we&#8217;ll need with a quick rationale as of why they will help us:</p>
<table class='details_table'>
<tr>
<th>Library</th>
<th>Purpose / Rationale</th>
</tr>
<tr>
<td><a href='#js-modernizr'>Modernizr</a></td>
<td>Detects HTML 5 support and provide IE shims</td>
</tr>
<tr>
<td><a href='#jquery'>jQuery</a></td>
<td>Main foundation (do I need to say more :-) ?!)</td>
</tr>
<tr>
<td><a href='#jqueryui'>jQuery UI</a></td>
<td>Prefabricated UI super-elements like tabs, accordions, sliders, etc.</td>
</tr>
<tr>
<td><a href='#jquery-cookies'>jQuery Cookies</a></td>
<td>Easy management of cookies</td>
</tr>
<tr>
<td><a href='#jquery-hotkeys'>jQuery HotKeys</a></td>
<td>Handling of keyboard shortcuts</td>
</tr>
<tr>
<td><a href='#jquery-maskedinput'>jQuery Masked Input</a></td>
<td>Allow creation of custom input masks</td>
</tr>
<tr>
<td><a href='#jquery-validate'>jQuery Validate</a></td>
<td>Validation framework</td>
</tr>
<tr>
<td><a href='#js-accounting'>Accounting.js</a></td>
<td>Allow formatting currency amounts</td>
</tr>
<tr>
<td><a href='#js-currencymask'>CurrencyMaskJS</a></td>
<td>Allow masked input of currency amounts</td>
</tr>
<tr>
<td><a href='#jquery-jstorage'>jStorage</a></td>
<td>Wrapper for local storage APIs</td>
</tr>
</table>
<p>If we want to start authoring HTML 5 semantic pages, <a href="#js-modernizr">Modernizr</a> is a library which can facilitate detection of specific HTML5 and CSS3 features. But it also shines for Internet Explorer versions earlier than 9 by plugging in &#8220;<b>shims</b>&#8220;, i.e. fake HTML elements in the DOM, named after the new HTML5 missing elements, making it possible to use tags like<b>header</b>, <b>footer</b>, <b>section</b>, etc. and styling them too. <br/><br/><br />
					<u>You</u> will need to create <u>your own</u> custom version of Modernizr based on the features you need. This will ensure the smallest most effective script for your situation. <br/><br />
					For our app, I chose to only include the &#8220;HTML5 Shim/IEPP&#8221; and the &#8220;CSS classes&#8221; &#8211; see <a href="http://www.modernizr.com/download/#-iepp-cssclasses" target='_blank'>this download</a> configuration. I renamed the resulted file as <b>modernizr.custom.min.js</b> and placed it in the <b>scripts/vendor</b> folder.<br />
					So we&#8217;ll need to include the script for <a href="#js-modernizr">Modernizr</a> right at the beginning our our HEAD section.</p>
<pre class="brush: html">
&lt;head&gt;
	&lt;!-- Important: Modernizr must be the very first script in HEAD --&gt;
	&lt;script src="scripts/vendor/modernizr.custom.min.js"&gt;&lt;/script&gt; 

	&lt;!-- ... --&gt;
&lt;/head&gt;
</pre>
<p>For performance reasons, we&#8217;ll use a Javascript loader (see available <a href='#javascript-loaders'>options</a> further on) to ensure the Javascript libraries we&#8217;ll need can be loaded asynchronously, in parallel, and not block the execution of our page load.<br />
					For this app, I chose <a href='#labjs'>LABjs</a> as it is specializes only on loading and is commonly used.<br />
					But note that you could use some of the conditional loading features of Modernizr, called <a href="http://yepnopejs.com/" target='_blank'>yepnope</a>.<br />
					I chose to keep things minimal for our app. ;-)
					</p>
<p>Starting from a basic HTML page, let&#8217;s add a script reference to <a href="#labjs"><b>lab.js</b></a> below our <b>modernizr</b> script, and then let&#8217;s define the order in which we want to load our libraries.<br />
					We&#8217;ll add a call to <b><u>wait()</u></b> if we want the execution of the actual code to be order-dependent:</p>
<pre class="brush: html">
&lt;head&gt;
	&lt;!-- Important: Modernizr must be the very first script in HEAD --&gt;
	&lt;script src="scripts/vendor/modernizr.custom.min.js"&gt;&lt;/script&gt;
	&lt;script src="LAB.js"&gt;&lt;/script&gt; &lt;!-- Important: must be the very first script in HEAD --&gt;
	&lt;script&gt;
	$LAB
		.script("http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js").wait()
		.script("http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js")
		.script("http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js")
		.script("scripts/vendor/knockout-1.2.1.debug.js").wait()
		.script("scripts/vendor/jquery.cookie.js")
		.script("scripts/vendor/jquery.blockUI.js")
		.script("scripts/vendor/jquery.hotkeys.js")
		.script("scripts/vendor/jquery.maskedinput-1.3.min.js")
		.script("scripts/vendor/jquery.validate.min.js")
		.script("scripts/vendor/accounting.min.js")
		.script("scripts/vendor/jstorage.min.js")
		.script("scripts/vendor/raphael-min.js").wait()
		.script("scripts/vendor/g.raphael-min.js").wait()
		.script("scripts/vendor/g.line-min.js").wait()
		.script("scripts/application.js").wait(function(){
			// When ALL scripts have been loaded AND executed:
			InitializeApplication();
		});
	&lt;/script&gt;

	&lt;!-- CSS and other HEAD-specific tags --&gt;
&lt;/head&gt;
</pre>
<p>You will notice that I am assuming a specific directory structure for our locally hosted Javascript code</p>
<ul>
<li><b>scripts</b> is the root of all .js files</li>
<ul>
<li><b>Vendor</b> will host external vendor libraries not available on a CDN.<br/><br />
								Having all external JS libraries in a dedicated folder will keep our directory structure clean.</li>
<li><b>ViewMediator</b> will include Javascript code <b>mediating</b> interactions between Views and ViewModels</li>
<li><b>ViewModel</b> will include our ViewModel-specific Javascript code</li>
<li><b>application.js</b> will be the main application .js file with an <b>InitializeApplication</b> function (called from our $LAB configuration)</li>
</ul>
</ul>
<p>At this point go ahead and create the same folder structure and download the needed Javascript libraries for the <b>Vendor</b> folder.<br />
					You can use the links in the <a href='#vendor-libraries'>External Javascript Libraries</a> table above.</p>
<p>And create the application.js file under the root of the scripts folder, and let&#8217;s provide a minimal implementation for now:</p>
<pre class="brush: javascript">
function InitializeApplication() {
	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication starting ...");
}
</pre>
<p>If you run the application you should see the informational message being displayed in the console.<br />
					And in Firefox Firebug, or on a WebKit browser you should see the parallel loading of the scripts.</p>
<p>For our CSS, let&#8217;s create a folder named <b><u>css</u></b> in which we&#8217;ll extract the <b>custom-theme</b> folder from our jQuery UI download.<br/><br />
					We&#8217;ll also create an <b>application.css</b> file for our application-specific styles.
					</p>
<pre class="brush: html">
&lt;link href="css/custom-theme/jquery-ui-1.8.16.custom.css" rel="stylesheet" type="text/css"  /&gt;
&lt;link href="css/application.css" rel="stylesheet" type="text/css"  /&gt;
</pre>
<p>					<a name='todo2'></a></p>
<h5>2. Organize our Application Code</h5>
<p>Since our application will very modular and encompass many functions or classes,<br />
					we&#8217;ll establish a namespace to provide some structure and avoid function name clashes.<br />
					You can read more about how to implement namespaces in Javascript in the following two articles:</p>
<ul>
<li><a href='http://elegantcode.com/2011/01/26/basic-javascript-part-8-namespaces/' target='_blank'>Elegant Code &#8211; Namespaces<a></li>
<li><a href='http://stackoverflow.com/questions/881515/javascript-namespace-declaration' target='_blank'>StackOverflow &#8220;Javascript Namespace Declaration&#8221;</a></li>
</ul>
<p>For this app, we&#8217;ll use <b>sgs</b> (for <b>s</b>avings <b>g</b>oal <b>s</b>imulator) as a prefix,<br />
					followed by either <b>model</b> or <b>mediator</b> for ViewModel and ViewMediator respectively.<br />
					To keep our markup free of Javascript logic, we&#8217;ll organize the application code in the following folders:</p>
<ol>
<li>application.js will contain only logic to initialize / setup the views and viewmodels</li>
<li>ViewModel &#8211; this folder will contain several files:
<ul>
<li>sgs.model.common.js for reusable logic across all types of ViewModels</li>
<li>one file for the page-level view model &#8211; e.g. sgs.model.index.js</li>
<li>one file for each view-specific view model &#8211; e.g. sgs.model.savings-goal.js &#8211; </li>
</ul>
</li>
<li>ViewMediator &#8211; this folder will contain several files:
<ul>
<li>sgs.mediator.common.js for reusable logic across all view mediators</li>
<li>one file for the page-level view mediator &#8211; e.g. sgs.mediator.index.js</li>
<li>one file for each view-specific view mediator &#8211; e.g. sgs.mediator.savings-goal.js &#8211; </li>
</ul>
</li>
</ol>
<p>So at this point, create the folder structure described above as well as stub content for <b>sgs.model.common.js</b> and <b>sgs.model.common.js</b> (they can remain empty for now). And let&#8217;s update the LAB.js section to load these 2 files (before application.js):</p>
<pre class="brush: html">
&lt;head&gt;
	&lt;!-- ... --&gt;
	$LAB
		// ...
		.script("scripts/viewmodel/sgs.model.common.js")
		.script("scripts/viewmediator/sgs.mediator.common.js")
		.script("scripts/application.js").wait(function(){
			// When ALL scripts have been loaded AND executed:
			InitializeApplication();
		});
	&lt;/script&gt;

	&lt;!-- ... --&gt;
&lt;/head&gt;
</pre>
<p>Here is a quick synopsis of the architecture for the first increment of our app:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-1.png" /><br/></p>
<p>					<a name='todo3'></a></p>
<h5>3. Create the Savings Goal View</h5>
<p>Now that we have a minimal shell in <b>index.html</b>,<br />
					let&#8217;s add a section tag to represent our first panel / view: the <b>savings-goal-view</b>.<br />
					The view will let us enter a savings goal amout and a maximum number of months.</p>
<pre class="brush: html">
&lt;body&gt;
	&lt;section id='savings-goal-view'&gt;
	&lt;/section&gt;
&lt;/body&gt;
</pre>
<p>Now we can add the two input elements (<b>savings-goal-amount</b> and <b>savings-max-duration</b>).<br />
					And we&#8217;ll have a span to display the calculated (derived) <b>savings-target-per-month</b>. This is what the view will look like:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-1a.png" /><br/></p>
<p><i><u>Important Note:</u> In this tutorial, <b>instead</b> of &#8220;<b>inlining</b>&#8221; the data-binding declaration with the view model inside the markup (like you will see in the KnockoutJS site or on any other simple tutorials), I am proposing a more &#8220;<b>unobtrusive</b>&#8221; approach consisting of <b>keeping the markup pure</b> and explicitly <b>defining data-bindings separately later</b> (in the <b>view mediator</b> which we&#8217;ll see soon in the next <a href='#todo4'>section</a>).</i></p>
<pre class="brush: html">
&lt;section id='savings-goal-view'&gt;
	&lt;label for="savings-goal-amount"&gt;Savings Goal Amount:&lt;/label&gt;
	&lt;input id="savings-goal-amount" /&gt;&lt;br/&gt;

	&lt;label for="savings-max-duration"&gt;Savings Max Duration (In Months):&lt;/label&gt;
	&lt;input id="savings-max-duration" /&gt;&lt;br/&gt;

	&lt;label for="savings-target-per-month"&gt;Savings Target Per Month:&lt;/label&gt;
	&lt;span id="savings-target-per-month" /&gt;&lt;br/&gt;
&lt;/section&gt;
</pre>
<p>At some point in the future, once the number of views increases beyond a couple, we&#8217;ll externalize our views as individual [jQuery] template files &#8211; but we&#8217;ll see the approach in detail later.</p>
<p><i><u>Note:</u> as we go along in the tutorial, I will not cover the CSS styling explicitly but you can always get the CSS when downloading the source based on the tag for a given step. Example: <a href="https://github.com/techarch/savings-goal-simulator/zipball/part2-todo-2" target='_blank'>tag: part2-todo-2.zip</a> (also available in tar.gz form). Look under for <b>css/application.css</b></i></p>
<p>					<a name='todo4'></a></p>
<h5>4. Create the Savings Goal ViewModel</h5>
<p>If you have not yet created the <b>ViewModels</b> folder under the <b>scripts</b> folder, do that now. And then create a file named: <b>sgs.model.savings-goal.js</b>.
					</p>
<p>Here is a diagram summarizing what we&#8217;re about to implement:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-todo4.png" /><br/></p>
<p>As we indicated earlier, we&#8217;ll use namespaces to structure our code and avoid name collisions with other libraries.<br />
					There are various approaches for namespacing code in Javascript, some uses <a href="#ns-objectliteral">object literals</a>, and some use <a href="ns-function">functions</a> as containers for our functions. Elijah Manor has a great <a href="#ns-summary">summary</a> highlighting the pros and cons of the various approaches.<br/><br/><br />
					For our needs and to make it easy to extend and edit our namespace we&#8217;ll use the <a href="#ns-objectliteral">object literals</a>.<br />
					To lazy initialize our namespace hierarchy let&#8217;s add the following snippet, which checks if each node in our namespace exists and creates it if it is not yet defined.</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.model.savingsgoal
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.model) == 'undefined') sgs.model = { }
if (typeof(sgs.model.savingsgoal) == 'undefined') sgs.model.savingsgoal = { }
</pre>
<p>Now we can create functions prefixed by our namespace such as for e.g. the function to initialize the view model and its two value models:</p>
<pre class="brush: javascript">
sgs.model.savingsgoal.initializeViewModel = function (pageSettings) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	var viewModel = {
		savingsGoalAmount: ko.observable(pageSettings.defaultSavingsGoal || 0), // dollars
		savingsMaxDuration: ko.observable(6), // months
	};

	return viewModel;
}</pre>
<p>So our viewModel is basically an object literal (hash) where each property value is a <b>value model</b>,<br />
					implemented as <a href='http://knockoutjs.com/documentation/observables.html' target='_blank'>KnockoutJS observable</a>, essentially a function acting as an interceptor for a value. Everytime the function is acting as a setter, the interceptor notifies all observers (subscribers) of the value change.</p>
<p>Now let&#8217;s add a derived function (a.k.a. a dependent observable in KnockoutJS-speak) named <b>savingsTargetPerMonth</b>:
					</p>
<pre class="brush: javascript">
sgs.model.savingsgoal.initializeViewModel = function (pageSettings) {
	// We can use properties of the pageSettings as default values for any of our ValueModels
	// If pageSettings are not provided we'll initialize an empty object
	if (typeof(pageSettings) == 'undefined') var pageSettings = { }

	var viewModel = {
		savingsGoalAmount: ko.observable(pageSettings.defaultSavingsGoal || 0), // dollars
		savingsMaxDuration: ko.observable(6), // months
	};

	viewModel.savingsTargetPerMonth = ko.dependentObservable(function() {
		var result = 0;
		if (this.savingsMaxDuration() > 0) {
			result = this.savingsGoalAmount() / this.savingsMaxDuration();
		}
		return result;
	}, viewModel);

	return viewModel;
}
</pre>
<p>Note that <b>ko.dependentObservable</b> takes a function as a parameter as you would expect, but can also take a second optional parameter used to define the meaning of <b>this</b> inside the derived function. Typically we always pass the variable containing our viewModel.</p>
<p>Over time we can add more business logic to our <b>sgs.mode.savingsgoal</b> module.</p>
<p>					<a name='todo5'></a></p>
<h5>5. Create the Savings Goal View Mediator</h5>
<p>If you have not yet created the <b>ViewMediators</b> folder under the <b>scripts</b> folder, do that now. And then create a file named: <b>sgs.mediator.savings-goal.js</b>.<br />
					This is the module where we&#8217;ll place our data-binding logic as well as any code related to mediating access between the page, the savings goal view, and its view model.<br/></p>
<p>Here is a diagram summarizing what we&#8217;re about to implement:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-todo5.png" /><br/></p>
<p>Let&#8217;s define our namespace:</p>
<pre class="brush: javascript">
// Lazy initialize our namespace context: sgs.mediator.savingsgoal
if (typeof(sgs) == 'undefined') sgs = { }
if (typeof(sgs.mediator) == 'undefined') sgs.mediator = { }
if (typeof(sgs.mediator.savingsgoal) == 'undefined') sgs.mediator.savingsgoal = { }

if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.savingsgoal loading!");
</pre>
<p>Now as a convention, let&#8217;s create a new function for our mediator named <b>createViewMediator</b><br />
					which we will eventually invoke from the <b>InitializeApplication</b> method in <b>application.js</b>.<br/><br />
					The createViewMediator function will have 3 responsibilities:</p>
<ol>
<li>Instantiate a view model for the savings goal view</li>
<li>Declare the data-binding between the HTML elements of the view and their corresponding value models in the view model</li>
<li>Ask KnockoutJS to make the bindings effective (they will be live right after that)</li>
<li>Save off the view model so we can access it from other parts of the app</li>
</ol>
<p>So let&#8217;s implement the first responsibility to instantiate a view model for the savings goal view (using the <b>initializeViewModel</b> function we just created in the savings goal view model module).</p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.createViewMediator = function (pageSettings) {
	// Create the view Savings Goal view-specific view model
	var viewModel = sgs.model.savingsgoal.initializeViewModel(pageSettings);
}
</pre>
<p>Now let&#8217;s declare each of the 3 data-bindings we need:</p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.createViewMediator = function (pageSettings) {
	// Create the view Savings Goal view-specific view model
	var viewModel = sgs.model.savingsgoal.initializeViewModel(pageSettings);

	// Declare the HTML element-level data bindings
	$("#savings-goal-amount").attr("data-bind","value: savingsGoalAmount");
	$("#savings-max-duration").attr("data-bind","value: savingsMaxDuration");
	$("#savings-target-per-month").attr("data-bind","text: savingsTargetPerMonth()");
}
</pre>
<p>Now we&#8217;ll ask KnockoutJS to &#8220;apply&#8221;, i.e. register / enable our bindings. </p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.createViewMediator = function (pageSettings) {
	// Create the view Savings Goal view-specific view model
	var viewModel = sgs.model.savingsgoal.initializeViewModel(pageSettings);

	// Declare the HTML element-level data bindings
	$("#savings-goal-amount").attr("data-bind","value: savingsGoalAmount");
	$("#savings-max-duration").attr("data-bind","value: savingsMaxDuration");
	$("#savings-target-per-month").attr("data-bind","text: savingsTargetPerMonth()");

	// Ask KnockoutJS to data-bind the view model to the view
	var viewNode = $('#savings-goal-view')[0];
	ko.applyBindings(viewModel, viewNode);
}
</pre>
<p>This is where KnockoutJS is performing some heavy lifting behind the covers such as:</p>
<ul>
<li>Setting observers on the actual HTML elements</li>
<li>Connecting these observers with the value models of the view model</li>
<li>Getting the initial value of each value model</li>
<li>Initializing each HTML element with that corresponding initial value</li>
</ul>
<p>To make it possible to store and retrieve our view model later we&#8217;ll leverage the jQuery data API.<br />
					So let&#8217;s create 2 functions in the savings goal mediator (since it is acting as an intermediate between the browser, page, view and the model:</p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.getViewModel = function() {
	return $(document).data("sgs.model.savingsgoal.viewmodel");
}

sgs.mediator.savingsgoal.setViewModel = function(viewModel) {
	$(document).data("sgs.model.savingsgoal.viewmodel", viewModel);
}
</pre>
<p>Now we can use the setViewModel function inside createViewMediator to save off our freshly-created view model.</p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.createViewMediator = function (pageSettings) {
	// Create the view Savings Goal view-specific view model
	var viewModel = sgs.model.savingsgoal.initializeViewModel(pageSettings);

	// Declare the HTML element-level data bindings
	$("#savings-goal-amount").attr("data-bind","value: savingsGoalAmount");
	$("#savings-max-duration").attr("data-bind","value: savingsMaxDuration");
	$("#savings-target-per-month").attr("data-bind","text: savingsTargetPerMonth()");

	// Ask KnockoutJS to data-bind the view model to the view
	var viewNode = $('#savings-goal-view')[0];
	ko.applyBindings(viewModel, viewNode);

	// Save the view model
	sgs.mediator.savingsgoal.setViewModel(viewModel);	

	if (typeof(console) != 'undefined' &#038;&#038; console) console.info("sgs.mediator.savingsgoal ready!");
}
</pre>
<p>					<a name='todo6'></a></p>
<h5>6. Link the Page and the View Mediator</h5>
<p>Here is a diagram summarizing how we&#8217;ll be linking our parts:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-todo6.png" /><br/></p>
<p>Ok now we&#8217;re at a point to start testing our first draft, we just need to add a call to the overall page <b>InitializeApplication</b> function (located in <b>scripts/application.js</b>) to our savings goal <b>createViewMediator</b> function like so:</p>
<pre class="brush: javascript">
function InitializeApplication() {
	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication starting ...");

	// Initialize our page-wide settings
	var pageSettings = { defaultSavingsGoal: 500 }

	// Create / launch our view mediator(s)
	sgs.mediator.savingsgoal.createViewMediator(pageSettings);

	if (typeof(console) != 'undefined' &#038;&#038; console)
		console.info("InitializeApplication done ...");
}
</pre>
<p>So now you should be able to load your index.html page in Firefox with the Firebug console on and watch the debug statement and finally our view displays with our initial data as well as the initial derived data for the &#8220;Savings Target Per Month&#8221; when you tab out of the amount or max number of months input fields:
					</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-1b.png" /><br/></p>
<p>					<a name='todo7'></a></p>
<h5>7. Apply Data Formatting / Masking Business Rules</h5>
<p>So far we have a nice simplistic example but if you build a solid app you will want to format and ensure our amounts are correct / valid / displayed according to conventional rules.<br />
					To my knowledge (having researched these types of libraries for a while), only library from <a href="http://www.pengoworks.com/" target="_blank">PengoWorks</a> has currency <b>masking</b> capabilities and will format the amount as you type it.<br />
					Since that library stopped being maintained in 2007, I started updating it (after checking with the original author, David Switzer) to make it work with current browsers). The resulting library is called <a href="#js-currencymask">CurrencyMask JS</a>.<br />
					So let&#8217;s download the <a href="https://github.com/techarch/CurrencyMaskJS" target="_blank">latest version</a> to our <b>./scripts/vendor</b> folder, and add a code snippet in our &lt;head&gt; LAB section:</p>
<pre class="brush: html">
&lt;head&gt;
	&lt;!-- ... --&gt;
	$LAB
		// ...
		.script("scripts/vendor/currency-mask-0.5.0-min.js").wait()
		.script("scripts/application.js").wait(function(){
			// When ALL scripts have been loaded AND executed:
			InitializeApplication();
		});
	&lt;/script&gt;

	&lt;!-- ... --&gt;
&lt;/head&gt;
</pre>
<p>To apply masking to a field, you instantiate a Mask object with the format you want (e.g. &#8220;$#,###&#8221; for amounts up to $9,999 without decimals) and you attach it to the targetted HTML element like so:</p>
<pre class="brush: javascript">
    var savingsGoalAmountMask = new Mask("$#,###", "number");
    savingsGoalAmountMask.attach($("#savings-goal-amount")[0]);
</pre>
<p>Let&#8217;s add the mask instantiation snippet to the savings goal view model (at the end of the <b>initializeViewModel</b> function in <b>sgs.model.savings-goal.js</b>). Also note that we will need to perform the initialization of savingsGoalAmount based on pageSettings later on in the mediator &#8211; so here we&#8217;ll set the default value of savingsGoalAmountFormatted to an empty string:</p>
<pre class="brush: javascript">
sgs.model.savingsgoal.initializeViewModel = function (pageSettings) {
	// ...

	var viewModel = {
		savingsGoalAmountFormatted: ko.observable(""),
		savingsGoalAmountMask: new Mask("$#,###", "number"),
		// ...
	};

	// ...
}
</pre>
<p>And let&#8217;s add the &#8220;attach&#8221; snippet to the savings goal view mediator in the <b>createViewMediator</b> function in <b>sgs.mediator.savings-goal.js</b>, right after the bindings declarations:</p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.createViewMediator = function (pageSettings) {
	// ...

	// Declare the HTML element-level data bindings
	// ...

	// Apply masking to the savings goal amount input field
    viewModel.savingsGoalAmountMask.attach($("#savings-goal-amount")[0]);

	// ...
}
</pre>
<p>And if we refresh the page and start typing 1500 in the amount it should format as we type along and prevent any other character input, ensuring the amount is valid.</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-2.png" /><br/></p>
<p>But &#8230; we just introduced an issue (see the infamous NAN displayed in the Savings Target Per Month)!<br />
					Well, once formatted the savingsGoalAmount value model will now be a string containing currency and thousands delimiter characters.<br />
					So let&#8217;s recognize that semantic change by re-naming our <b>savingsGoalAmount</b> value model as <b>savingsGoalAmountFormatted</b> value model:</p>
<pre class="brush: javascript">
sgs.model.savingsgoal.initializeViewModel = function (pageSettings) {
	// ...

	var viewModel = {
		savingsGoalAmountFormatted: ko.observable(pageSettings.defaultSavingsGoal || 0), // dollars
		// ...
	};
</pre>
<p>Now what we need to re-create a new <b>savingsGoalAmount</b> value model, and make it act as a two-way adapter to convert back and forth between formatted and unformatted values.<br />
					KnockoutJS can help us with that, using a &#8220;<b>dependentObservable</b>&#8220;. KnockoutJS also allows a hash to be passed to ko.dependentObservable. That hash can include the following key-value pairs:
					</p>
<ul>
<li><b>owner</b> &#8211; will specify the value of <b>this</b></li>
<li><b>read</b> &#8211; a function which can perform some post-processing and ultimately return the value of the observable</li>
<li><b>write</b> &#8211; a function which can perform some pre-processing of a value and ultimately store it</li>
</ul>
<p>So here is a skeleton of what the savingsGoalAmount value model would look like as a dependentObservable:</p>
<pre class="brush: javascript">
viewModel.savingsGoalAmount = ko.dependentObservable({
	owner: viewModel,
	read: function () {
		// some post processing code
	},
	write: function (value) {
		// some pre processing code
	}
});
</pre>
<p>Let&#8217;s tackle the <b>read</b> function first. It will need to:</p>
<ul>
<li>Get the current value model from <b>savingsGoalAmountFormatted</b></li>
<li>Ask the savingsGoalAmountMask for a stripped (unformatted) value</li>
<li>Return a valid float value</li>
</ul>
<p>Here is what the code looks like for the &#8220;read&#8221;:</p>
<pre class="brush: javascript">
	read: function () {
		// Get the current formatted value model
		// Important Note: Even though we don't use the formatted_amt variable
		// in the rest of the function, we need to let KnockoutJS "know"
		// that this closure has a dependency on savingsGoalAmountFormatted
		// otherwise the closure will never be invoked on a read.
		var formatted_amt = this.savingsGoalAmountFormatted();

		// Unformat the value
		var amt = this.savingsGoalAmountMask.strippedValue;

		// Convert the result to a float
		if (amt.length == 0) { amt = 0 };
		return parseFloat(amt);
	},
</pre>
<p>Now let&#8217;s tackle the <b>write</b> function first. It will need to:</p>
<ul>
<li>Ask the savingsGoalAmountMask to format the value</li>
<li>Set the <b>savingsGoalAmountFormatted</b> to the formatted value</li>
<li>Return the passed value</li>
</ul>
<p>Here is what the code looks like for the &#8220;write&#8221;:</p>
<pre class="brush: javascript">
	write: function (value) {
		// Format the passed in value using the mask
		var formatted_value = this.savingsGoalAmountMask.updateFormattedValue(value);

		// Update the savingsGoalAmountFormatted value model
		this.savingsGoalAmountFormatted(formatted_value);
		return value;
	}
</pre>
<p>The complete and refactored savingsGoalAmount dependentObservable will now look like this:</p>
<pre class="brush: javascript">
viewModel.savingsGoalAmount = ko.dependentObservable({
	owner: viewModel,
	read: function () {
		// Get the current formatted value model
		var formatted_amt = this.savingsGoalAmountFormatted();

		// Unformat the value
		var amt = this.savingsGoalAmountMask.strippedValue;

		// Convert the result to a float
		if (amt.length == 0) { amt = 0 };
		return parseFloat(amt);
	},
	write: function (value) {
		// Format the passed in value using the mask
		var formatted_value = this.savingsGoalAmountMask.updateFormattedValue(value);

		// Update the savingsGoalAmountFormatted value model
		this.savingsGoalAmountFormatted(formatted_value);
		return value;
	}
});
</pre>
<p>Now refreshing the index.html page should allow you to enter amounts and see the calculated value!</p>
<p>Here is a diagram summarizing how we restructured the various parts using the dependent observables and the mask:</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-todo7.png" /><br/></p>
<p>I will leave the exercise for you dear reader to follow the same pattern for the &#8220;Savings Max Duration (In Months)&#8221; input field.<br />
					In that case the mask will be a little simpler since we need at most 2 digits.</p>
<p>					<a name='todo8'></a></p>
<h3>8. Apply Custom Masking Rules</h3>
<p>For custom masking needs, such as for example a phone number, social security id, special identifier,<br />
					I strongly recommend <a href="http://digitalbush.com/about/" target="_blank">Josh Bush</a>&#8216; <a href="#jquery-maskedinput">Masked Input Plugin</a>.
					</p>
<p>For dates I suggest using  Masked Input together with <a href="http://jqueryui.com/demos/datepicker/" target="_blank">jQuery Datepicker</a> since the calendar makes it easy to select a date but does <u>not</u> provide <b>masking</b> features.</p>
<p>					<a name='todo9'></a></p>
<h3>9. Applying Formatting Rules</h3>
<p>When using our simple view you might have noticed that the &#8220;Savings Target Per Month&#8221; may show some numbers with many decimals. This is because the <b>&lt;span&gt;</b> element is data-bound to the <b>savingsTargetPerMonth</b> dependentObservable which returns a <b>float</b>. So we have two options:</p>
<ul>
<li>Apply formatting to the float inside savingsTargetPerMonth</li>
<li>Or create another dependentObservable named savingsTargetPerMonthFormatted, in which we can apply the needed formatting logic. Then we would change the data binding for the <b>&lt;span&gt;</b>  to use our new value model.</li>
</ul>
<p>The cleanest approach is #2 since it also allows you in the future to build other dependentObservables on top of <b>savingsTargetPerMonth</b>. But if you don&#8217;t think you will need that ability then #1 will work and is very simple.
					</p>
<p>Approach 1 would require us to format the calculated value using the <b>formatMoney</b> function of <a href="#js-accounting">Accounting.js</a> like so:</p>
<pre class="brush: javascript">
		var result = this.savingsGoalAmount() / this.savingsMaxDuration();
		var formattedResult = accounting.formatMoney(result, "$", 2, ",", ".");  ;
		return formattedResult;
</pre>
<p>Approach 2 would require us to add a new dependentObservable named savingsTargetPerMonthFormatted in our savings goal view model:</p>
<pre class="brush: javascript">
sgs.model.savingsgoal.initializeViewModel = function (pageSettings) {
	// ...

	viewModel.savingsTargetPerMonthFormatted = ko.dependentObservable(function() {
		var result = 0;
		if (this.savingsMaxDuration() > 0) {
			result = this.savingsGoalAmount() / this.savingsMaxDuration();
		}
		var formattedResult = accounting.formatMoney(result, "$", 2, ",", ".");  ;
		return formattedResult;
	}, viewModel);
}
</pre>
<p>And we then need to update the data-binding code in the <b>createViewMediator</b> function of our mediator module:</p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.createViewMediator = function (pageSettings) {
	// ...

	$("#savings-target-per-month").attr("data-bind","text: savingsTargetPerMonthFormatted()");

	// ...
}
</pre>
<p>Let&#8217;s refresh the index.html page and now when we enter $500 and 7 months, the max per month updates to dollar formatted two-decimal amount: $71.43!</p>
<p>					<a name='todo10'></a></p>
<h3>10. Applying Visual Feedback Cues</h3>
<p>When web pages require a round-trip to the server, the user waits and then sees the whole page refreshing, but in rich interactive apps since processing happens often very fast without a page refresh, we need to provide visual cues when changes occur. For quick feedback logic (e.g. not requiring an Ajax call or processing longer than a second) I recommend using a jQuery UI <a href="http://jqueryui.com/demos/effect/" target="_blank">&#8220;effect&#8221;</a>, such a temporary highlight using a soft color, like so:</p>
<pre class="brush: javascript">
		$("#savings-target-per-month")
			.effect('highlight', { color: 'LightGreen' }, 3000); // for 3 seconds
</pre>
<p>Logically the code belongs to the mediator, so let&#8217;s <b>subscribe</b> to the <b>savingsTargetPerMonthFormatted</b> value model changes<br />
					inside our <b>createViewMediator</b> function.</p>
<pre class="brush: javascript">
sgs.mediator.savingsgoal.createViewMediator = function (pageSettings) {
	// ...

	// Subscribe to interesting value model changes
	viewModel.savingsTargetPerMonthFormatted.subscribe(function() {
		$("#savings-target-per-month")
			.effect('highlight', { color: 'LightGreen' }, 3000); // for 3 seconds
	});

	// ...
}
</pre>
<p>Let&#8217;s refresh index.html, and whenever we see the xxx recalculate, the light green highlight of the result should fade in and out during our 3-second timeframe!</p>
<p>					<img src="./wp-content/media/knockoutjs/savings-goal-simulator-part1-3.png" /><br/></p>
<hr />
<h5>Overall Recap</h5>
<p>So at this point we have built a reasonably solid foundation for our app even though it contains only one view. The architectural steps we took to decouple view, viewmodel, view mediator and the page will yield some benefits once we add continue adding features to our app (in part 3).<br/><br />
					So here is a quick recap of the steps we followed:</p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
<th>Area (Module)</th>
</tr>
<tr>
<td><a href='#todo1'>1</a></td>
<td>Create a Shell Application</td>
<td>Main app</td>
</tr>
<tr>
<td><a href='#todo2'>2</a></td>
<td>Organize your Application Code</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo3'>3</a></td>
<td>Break down each independent panel into Views</td>
<td>View</td>
</tr>
<tr>
<td><a href='#todo4'>4</a></td>
<td>Create a ViewModel for each View</td>
<td>View Model</td>
</tr>
<tr>
<td><a href='#todo5'>5</a></td>
<td>Create a View Mediator for each View</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo6'>6</a></td>
<td>Link the Page and the View Mediator(s)</td>
<td>Main App</td>
</tr>
<tr>
<td><a href='#todo7'>7</a></td>
<td>Apply Data Formatting / Masking Business Rules</td>
<td>View</td>
</tr>
<tr>
<td><a href='#todo8'>8</a></td>
<td>Apply Custom Masking Rules</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo9'>9</a></td>
<td>Applying Formatting Rules</td>
<td>View Mediator</td>
</tr>
<tr>
<td><a href='#todo10'>10</a></td>
<td>Providing Visual Feedback Cues</td>
<td>View Mediator</td>
</tr>
</table>
<p>					<a name='sowhat'></a></p>
<h3>So What?</h3>
<p>Many KnockoutJS tutorials focus on giving you the basics to run simple scenarios. My approach here although more &#8220;<b>architected</b>&#8221; is geared at building rich interactive apps made of multiple panels/views with solid interactions. </p>
<p>The modularization of our code base will also lend itself better to unit testing and even BDD testing using Javascript test frameworks like <a name='js-jasmine' href='http://http://pivotal.github.com/jasmine/' target='_blank'>Jasmine</a> and <a name='js-jasmine-species' href='http://rudylattae.github.com/jasmine-species/' target='_blank'>Jasmine-Species</a>. They will allow us to write tests against our view models and to a certain degree some of the various Javascript modules.</p>
<p>We have focused on a one-view increment for the app but in Part 3 we will cover the following topics:</p>
<ul>
<li>Adding more views, viewmodels and mediators to our basic app</li>
<li>Sharing data across views and mediators</li>
<li>Implementing masking and formatting</li>
<li>Incorporating rudimentary elements of usability</li>
<li>&#8230; and more!</li>
</ul>
<p>So stay tuned!</p>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>Patterns</h5>
<ul>
<li><a name='mvvmp' href='http://en.wikipedia.org/wiki/Model_View_ViewModel'>Model View &#8211; ViewModel Pattern</a></li>
<li><a name='mvcp' href='http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html'>MVC Xerox Parc 1978-79</a></li>
<li><a name='mvcp' href='http://c2.com/cgi/wiki?ModelViewController'>MVC Pattern</a></li>
<li><a name='obp' href='http://c2.com/cgi/wiki?ObserverPattern'>Observer Pattern</a></li>
<li><a name='psp' href='http://c2.com/cgi/wiki?PublishSubscribeModel'>Publish Subscribe Pattern</a></li>
<li><a name='vmp' href='http://c2.com/cgi/wiki?ValueModel'>Value Model Pattern</a></li>
<li><a name='dbp' href='http://c2.com/cgi/wiki?DataBinding'>Data Binding Pattern</a></li>
<li><a name='ns-summary' href='http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/'>Summary of Namespacing Approaches (by Elijah Manor)</a></li>
<li><a name='ns-objectliteral' href='http://stackoverflow.com/questions/881515/javascript-namespace-declaration/881556#881556'>Namespacing using Object Literals</a></li>
<li><a name='ns-function' href='http://stackoverflow.com/questions/881515/javascript-namespace-declaration/881611#881611'>Namespacing using Functions</a></li>
</ul>
<h5>Frameworks And Blogs</h5>
<ul>
<li><a name='ko' href='http://knockoutjs.com/'>KnockoutJS</a></li>
<li><a name='lko' href='http://learn.knockoutjs.com/'>Learn KnockoutJS (Interactive Tutorial / Playground)</a></li>
<li><a name='jq' href='http://jquery.com/'>jQuery</a></li>
<li><a name='jqui' href='http://jqueryui.com/'>jQuery UI</a></li>
<li><a name='jqt' href='http://api.jquery.com/jQuery.template/'>jQuery Template</a></li>
<li><a name='jqtapi' href='http://api.jquery.com/jQuery.template/'>jQuery Template API</a></li>
<li><a name='ss' href='http://blog.stevensanderson.com/'>Knock Me Out (Steve Sanderson&#8217;s Blog)</a></li>
<li><a name='kmo' href='http://www.knockmeout.net/'>Knock Me Out (Ryan Niemeyer&#8217;s Blog)</a></li>
<li><a name='pflsjaa' href='http://addyosmani.com/blog/patterns-for-large-scale-javascript-application-architecture/'>Patterns For Large-Scale Javascript Architecture (Addy Osmani)</a></li>
</ul>
<p>					<a name="javascript-loaders" ></a></p>
<h5>Javascript Loaders</h5>
<ul>
<li><a name='headjs' href='http://headjs.com/' target='_blank'>HeadJS</a></li>
<li><a name='labjs' href='http://labjs.com/' target='_blank'>LABjs</a></li>
<li><a name='lazyload' href='https://github.com/rgrove/lazyload' target='_blank'>LazyLoad</a></li>
<li><a name='jquery-cookie' href='https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js' target='_blank'>jQuery Cookie</a></li>
</ul>
<p>					<a name="jquery-plugins" ></a></p>
<h5>jQuery Plugins</h5>
<ul>
<li><a name='jquery-blockui' href='http://jquery.malsup.com/block/' target='_blank'>jQuery BlockUI</a></li>
<li><a name='jquery-cookie' href='https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js' target='_blank'>jQuery Cookie</a></li>
<li><a name='jquery-datatables' href='http://datatables.net/' target='_blank'>jQuery DataTables</a></li>
<li><a name='jquery-hotkeys' href='https://github.com/tzuryby/jquery.hotkeys' target='_blank'>jQuery HotKeys</a></li>
<li><a name='jquery-tree' href='http://www.jstree.com/' target='_blank'>jQuery jsTree</a></li>
<li><a name='jquery-validate' href='http://plugins.jquery.com/project/jqueryvalidate' target='_blank'>jQuery Validate</a></li>
</ul>
<p>					<a name="other-js-libraries" ></a></p>
<h5>Other Javascript Libraries</h5>
<ul>
<li><a name='js-modernizr' href='http://www.modernizr.com/' target='_blank'>Modernizr</a></li>
<li><a name='js-blockui' href='http://jquery.malsup.com/block/' target='_blank'>BlockUI</a></li>
<li><a name='js-accounting' href='http://josscrowcroft.github.com/accounting.js/' target='_blank'>Accounting.js</a></li>
<li><a name='js-currencymask' href='https://github.com/techarch/CurrencyMaskJS' target='_blank'>CurrencyMask JS</a></li>
<li><a name='jquery-maskedinput' href='http://digitalbush.com/projects/masked-input-plugin/' target='_blank'>Masked Input</a></li>
<li><a name='js-raphael' href='http://raphaeljs.com/' target='_blank'>Raphael JS</a></li>
<li><a name='js-graphael' href='http://g.raphaeljs.com/' target='_blank'>gRaphael JS</a></li>
<li><a name='js-storage' href='https://github.com/andris9/jStorage' target='_blank'>jStorage</a></li>
<li><a name='js-underscore' href='http://documentcloud.github.com/underscore/' target='_blank'>Underscore</a></li>
<li><a name='js-fixtures' href='http://jupiterjs.com/news/organizing-a-jquery-application#news/ajax-fixtures-plugin-for-jquery' target='_blank'>Ajax Fixtures</a></li>
</ul>
<p>					<a name="js-test-frameworks" ></a></p>
<h5>Javascript Test Frameworks</h5>
<ul>
<li><a name='js-jasmine' href='http://http://pivotal.github.com/jasmine/' target='_blank'>Jasmine, BDD for Javascript</a></li>
<li><a name='js-jasmine-species' href='http://rudylattae.github.com/jasmine-species/' target='_blank'>Jasmine Species, BDD Grammar Extensions (Given, When, Then, etc.)</a></li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a name='ko-part1' href='http://blog.monnet-usa.com/?p=354'>Creating Rich Interactive Web Apps With KnockOut.js &#8211; Part 1</a></li>
<li><a name='ko-part3' href='http://blog.monnet-usa.com/?p=404'>Creating Rich Interactive Web Apps With KnockOut.js &#8211; Part 3</a></li>
</ul>
<p>					<a name='kodemosrc'></a></p>
<h5>Full Source Of The Savings Goal Simulator (KnockoutJS Demo)</h5>
<p>The whole application is available on Github under <a href='https://github.com/techarch/savings-goal-simulator' target='_blank'>techarch / savings-goal-simulator</a>.</p>
<p>					<a name='credits'></a></p>
<h5>Credits</h5>
<p>Special thanks for <a href="http://blog.logeek.fr/" target='_blank'>Thibaut Barrère</a> and <a href="http://susanpotter.net/" target='_blank'>Susan Potter</a> for their feedback while I was working on drafts for this tutorial! :-)</p>
<div class="blog-msm-ad">
<div class="blog-msm-ad1">
							If you enjoyed this post, I would love it if you could check out <a href="http://bit.ly/myskillsmap">mySkillsMap</a>, my skills management app.
						</div>
<div class="blog-msm-ad2">
								<a href="http://www.myskillsmap.com/take-charge-of-your-skills-development"><br />
									<img src='./wp-content/media/msm/start-your-free-trial-now.png'  /><br />
								</a>
						</div>
</p></div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/pIDq8V5J-20" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=368</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=368</feedburner:origLink></item>
		<item>
		<title>Creating Rich Interactive Web Apps With KnockoutJS – Part 1</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/3uaW3cw3oWQ/</link>
		<comments>http://blog.monnet-usa.com/?p=354#comments</comments>
		<pubDate>Sat, 17 Sep 2011 21:35:28 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=354</guid>
		<description><![CDATA[
						h3 {	text-decoration: underline; }
						h5 {margin-left:20px !important;}
						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}
						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.details_table th
						{
						background-color:lightgray;
						}
						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}

Intro

					With the advent of online games, social apps, Flash/AIR apps, and rich instant-feedback sites
					like Google Search and GMail, consumers are demanding more and more interactivity.
					
While interacting with [...]]]></description>
			<content:encoded><![CDATA[<style>
						h3 {	text-decoration: underline; }</p>
<p>						h5 {margin-left:20px !important;}</p>
<p>						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}</p>
<p>						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.details_table th
						{
						background-color:lightgray;
						}</p>
<p>						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}</p>
</style>
<h3>Intro</h3>
<p>
					With the advent of online games, social apps, Flash/AIR apps, and rich instant-feedback sites<br />
					like Google Search and GMail, consumers are demanding more and more interactivity.
					</p>
<p>While interacting with your app customer now expect:</p>
<ul>
<li>Browser-side processing (calculation, business rules, &#8230;)</li>
<li>Instant validation </li>
<li>Instant visual feedback: animation/effect while making changes (add/remove/update)</li>
<li>Dynamic clues on what to do next</li>
<li>More same / on page functionality (without the need to refresh or navigate to other pages)</li>
</ul>
<p>For a while adding a sprinkling of AJAX and localized visual refresh using jQuery UI was sufficient.<br />
					But richer application interactions introduce more elaborate technical approaches: <br/><br />
					<img src="./wp-content/media/knockoutjs/browser-side-app-stack.png" />
					</p>
<ul>
<li>Present more related data at the same time</li>
<li>Leverage graphs and other data visualization techniques</li>
<li>Offer more on-page functionality</li>
<li>Allow interactions with one panel to cause updates on other panels</li>
<li>Support asynchronous back-end interactions</li>
</ul>
<h3>Extending the <a href="#mvcp">Model View Controller Pattern</a></h3>
<p>
					Here is a reminder of what typically happens in a traditional <a href="#mvcp">MVC</a> web app (e.g. Ruby On Rails, Ruby Camping, ASP.NET MVC, Cake PHP, Django Python, etc.):
					</p>
<ul>
<li>The routing engine identifies the appropriate controller</li>
<li>The controller retrieves the model</li>
<li>The view engine renders the view</li>
<li>The view contains HTML, CSS, and Javascript code</li>
<li>Rich browser-side applications typically have event handlers to allow page-level interactions to<br />
							handle validation, hide/show elements, perform some processing / calculations, executebusiness rules, invoke AJAX services, update content</li>
</ul>
<p>
					Note that the last bullet represents quite a bit of logic (possibly in the 500 to several thousand lines of Javascript code).<br />
					The logic gets even more complex once you have multiple panels and sets of model elements.<br />
					If your AJAX services return complex objects you also need to keep track of these objects,<br />
					their binding to panel elements/controls, and their inter-dependencies / impact on each other when a change occurs.</br></p>
<p>					<img src="./wp-content/media/knockoutjs/web-app-architecture.png" /></p>
<p><b>Key take-away:</b><br/><br />
					We need to organize our browser-side code (markup, CSS, and JS) according to their <b>concern</b>, i.e. model representation, business rules, display, user interaction, event handling, server interaction, etc..</p>
<p>This is where the notion of <a href="#mvvmp">ViewModel</a> and <a href="#obp">Observables</a> come in to help us out.<br />
					Let&#8217;s break things down:
					</p>
<p>					<a id="breakdown"></a></p>
<ol>
<li>The ViewModel is a specialized <b>browser-side</b> Javascript <b><u>m</u>odel</b> representing a <b>group of data elements</b> a given page or panel (View) will display or facilitate interaction with.<br/><br />
						<img src="./wp-content/media/knockoutjs/viewmodel-data-elements.png" /><br/><br />
						<u>Benefits:</u></p>
<ul>
<li><b>Partitioning</b>: each page / page can have its own clean model</li>
<li><b>Testability</b>: the View and ViewModel can be tested independently from the server logic</li>
<li><b>Modularity</b>: ViewModels code can be namespaced and contained in their own <b>.js</b> file</li>
</ul>
<p>							<br/>
						</li>
<li>Each attribute of a ViewModel will be mapped to an <a href="#obp">Observable</a> so that any value change can be <b>broadcasted</b> (a.k.a. &#8220;published&#8221; in the <a href="#psp">publish/subscribe</a> terminology) to any interested <b>subscriber</b>. (So essentially a ViewModel attribute is what is called a <a href="#vmp">Value Model</a>)<br/><br />
						<img src="./wp-content/media/knockoutjs/viewmodel-observables.png" /><br/><br />
						<u>Benefits:</u></p>
<ul>
<li><b>Fast UI</b>: derived values or content can be produced on-the-fly based on observed attributes</li>
<li><b>Increased responsiveness</b>: asynchronous server interactions can be triggered in the background and cause ViewModels to be updated</li>
</ul>
<p>							<br/>
						</li>
<li>The scenario where a UI element <b>subscribe</b> to a ViewModel attribute (Value Model) is known as &#8220;<a href="#dbp">Data-Binding</a>&#8220;.<br />
						This allows a clean separation between logic related to the ViewModel (calculations, derivations, retrieval, server interaction) and UI-specific presentation logic.<br/><br />
						<img src="./wp-content/media/knockoutjs/viewmodel-data-binding.png" /><br/><br />
						<u>Benefits:</u></p>
<ul>
<li><b>Synchronization</b>: HTML elements and ViewModel attributes are kept in synch</li>
<li><b>Instant visual feedback</b>: elements on the page can update visually as you interact / update data</li>
</ul>
<p>							<br/>
						</li>
</ol>
<h3>Introducing KnockOutJS</h3>
<p>KnockOutJS is a Javascript framework created by <a href="#ss">Steve Sanderson</a> to provide support for <a href="#mvvmp">ViewModel</a>, <a href="#obp">Observable</a>, and <a href="#dbp">Data-Binding</a> using jQuery.<br />
					For more details, check out the <a href="#ko">KnockOutJS</a> site as well as the <a href="#lko">Learning Playground</a>.<br/><br />
					Let&#8217;s dig into the basic infrastructure provided by KnockOutJS and then we&#8217;ll build up to more complex scenarios.
					</p>
<p>					<a id="ko-basics"></a></p>
<h4>Basics</h4>
<ol>
<li>In <a href="">KnockoutJS</a>, a ViewModel is defined as a Javascript Object Literal. Value Models are defined using <b>ko.observable()</b> and an initial value as follows:
<pre class="brush: javascript">
var viewModel = {
	savingGoalAmount: ko.observable(500), // dollars
	// ... more attributes ...
};
</pre>
<p>							The example ViewModel has one attribute: savingGoalAmount, with an initial value of 500.<br />
							<br/>
						</li>
<li>You can programmatically <b>&#8220;subscribe&#8221;</b> to changes in a ViewModel attribute (a Value Model) like this:<br/>
<pre class="brush: javascript">
// Set up the ViewModel
var viewModel = {
	savingGoalAmount: ko.observable(500), // dollars
	// ... more attributes ...
};

viewModel.savingGoalAmount.subscribe(function(newValue) {
	// Show the updated value on the FireBug's console
	console.info("savingGoalAmount is now " + newValue);
});

// Get KnockoutJS to apply bindings / subscriptions
ko.applyBindings(viewModel);	

// Test by changing the amount
viewModel.savingGoalAmount(600); // Should display in the console
</pre>
<p>							The <b>subscribe</b> function takes a callback function it will invoke upon any change on the value of the savingGoalAmount Value Model.<br/><br />
							The <b>ko.applyBindings</b> function tells KnockoutJS to start the dependency tracking. From that point on all subscribers will be notified of any changes.<br/></p>
</li>
<li>KnockoutJS makes it easy to setup <a href="#dbp">data binding</a> between any HTML element (e.g. INPUT) and a ViewModel attribute (Value Model) using the <a href="#kodb">data-bind</a> syntax and the <b>value:</b> keyword<br/>
<pre class="brush: html" >
<input id="saving-goal-amount"
			size="5" pattern="[0-9]{5}" min="0" max="99999"
			data-bind="value: savingGoalAmount" />
</pre>
<p>						KnockoutJS uses the <b>data-bind</b> attribute to let us specify the type of binding needed.<br />
						In this example we&#8217;re binding the <b>value</b> of the INPUT element to the savingGoalAmount Value Model.<br />
						We&#8217;ll see later on that there are other types of data-binding such as specific attributes, visibility, styling, etc. although you can see the full reference in the <a href="http://knockoutjs.com/documentation/visible-binding.html" target="_blank">documentation</a>.</p>
<p>						<img src="./wp-content/media/knockoutjs/basic-data-binding-example.png" /><br/><br />
						Note that the <a href="#kodb">data-bind</a> syntax is just &#8220;syntactic sugar&#8221; for use in our markup. If you prefer a clean separation between markup and Javascript, you can declare your data-bindings like so:<br/></p>
<pre class="brush: javascript">
$("#saving-goal-amount")
	.attr("data-bind","value: savingGoalAmount");
</pre>
<p>						You just need to make sure these declarations are performed <b><u>before</u></b> you get KnockoutJS to apply the bindings (using <b>ko.applyBindings</b>).
						</li>
</ol>
<p>You can play and run the examples above on this <a href="http://jsfiddle.net/techarch/z5Ptd/6/" target="_blank">jsFiddle.net</a> page.</p>
<p><br/><br />
					<a id="ko-building-up"></a></p>
<h4>Building Up</h4>
<p>Now that we have a basic understanding of KnockoutJS, let&#8217;s add a few more building blocks:</p>
<ol>
<li>If a ViewModel attribute needs to store an array, KnockoutJS provides a specialized type of <a href="#obp">Observable</a> called an <b>ko.observableArray</b>:
<pre class="brush: javascript">
var viewModel = {
	savingGoalObjectives: ko.observableArray([ 'Discretionary', 'Expensive Purchase', 'Investment']),
	// ... more attributes ...
};
</pre>
<p>						Adding / removing items in the array will cause KnockoutJS to trigger an update to all observers of this Value Model.<br />
						<br/>
						</li>
<li>In addition to attributes (Value Models), ViewModels can expose &#8220;<b>behaviors</b>&#8221; such as:<br/>
<ul>
<li>Derived attributes, resulting from a calculation, or a business rule.<br/><br />
									KnockoutJS refers to them as <a href="http://knockoutjs.com/documentation/dependentObservables.html" target="_blank">dependentObservables</a>:</p>
<pre class="brush: javascript">
var viewModel = {
	savingGoalAmount: ko.observable(500), // dollars
	savingMaxDuration: ko.observable(6), // dollars
	// ... more attributes ...
};

// Derived data
viewModel.savingTargetPerMonth = ko.dependentObservable(function() {
	return this.savingGoalAmount() / this.savingMaxDuration();
}, viewModel)
</pre>
<p>									Whenever either savingGoalAmount or savingMaxDuration change, the derived savingTargetPerMonth function will be re-evaluated.<br />
									If savingTargetPerMonth is data-bound to the UI, the corresponding element will redisplay.<br/><br />
									Note that you can create dependentObservable functions on top of dependent observables or plain observables!<br />
<img src="./wp-content/media/knockoutjs/advanced-derived-attribute.png" /><br/>
									</li>
<li>Formatted version of the data
<pre class="brush: javascript">
var viewModel = {
	savingGoalAmount: ko.observable(500), // dollars
	// ... more attributes ...
};

// Derived formatted display data
viewModel.savingGoalAmountAsCurrency = ko.dependentObservable(function() {
	return accounting.formatMoney(this.savingGoalAmount(),
			"$", 2, ",", ".");  ;
}, viewModel)
</pre>
<p>Above is an example using the <a href="http://josscrowcroft.github.com/accounting.js/" target="_blank">Accounting.js</a> library to format our savingGoalAmount Value Model within our dependent observable so that we can display a nicely formatted currency representation on the UI.<br/></p>
</li>
<li>Add / remove logic on arrays
<pre class="brush: javascript">
var viewModel = {
	myItems: ko.observableArray(),
	// ... more attributes ...
};

// Add / remove behaviors
viewModel.addItem = function (newItem) {
	var valid = validateItem(newItem); // custom logic
	if (valid) {
		this.myItems.push(newItem);
	}
}
</pre>
<p>										In this example, <b>addItem</b> is a custom behavior attached to the ViewModel which can be invoked to add new valid items.
									</li>
<li>Any other business logic related to an overall ViewModel
<pre class="brush: javascript">
var viewModel = {
	savingGoalAmount: ko.observable(500), // dollars
	// ... more attributes ...
};

viewModel.reset = function() {
	this.savingGoalAmount(500);
}
</pre>
</li>
</ul>
</li>
<li>To allow other parts of our browser-side logic to access our ViewModels, we need to have a way to access them.<br/><br />
						We can save ViewModels in the DOM, either at the document level or at a panel level using the <b>jQuery.data</b> API:</p>
<pre class="brush: javascript">
var viewModel1 = { }
var viewModel2 = { }

ko.applyBindings(viewModel1);
ko.applyBindings(viewModel2);	

$(document).data("MyDocumentViewModel", viewModel1);
$("#my-panel").data("MyPanelViewModel", viewModel2);
</pre>
<p>						This allows us to access a specific ViewModel later, outside data-binding logic (e.g. in an event handler) like so:</p>
<pre class="brush: javascript">
var viewModel1 = $(document).data("MyDocumentViewModel");
var viewModel2 = $("#my-panel").data("MyPanelViewModel");
</pre>
<p>							To keep our code organized we&#8217;ll want to create accessor functions such as for example:<br/></p>
<pre class="brush: javascript">
	MyApp.Model.GetMyDocumentViewModel = function() {
		return $(document).data("MyDocumentViewModel");
	}

	MyApp.Model.SetMyDocumentViewModel = function(viewModel) {
		$(document).data("MyDocumentViewModel", viewModel);
	}
</pre>
<p>							So that we can just access our ViewModel from other modules:<br/></p>
<pre class="brush: javascript">
// Initialization
var viewModel = { }
ko.applyBindings(viewModel);
MyApp.Model.SetMyDocumentViewModel(viewModel);

// Later on in a different module:
MyApp.Model.GetMyDocumentViewModel()
	.savingGoalAmount.subscribe(myCallBackFunction);
</pre>
<p>							<br/>
						</li>
<li>The attributes (<b>Value Models</b>) of the ViewModel can be updated using data returned by an AJAX call to a controller<br/>
<pre class="brush: javascript">
$.getJSON('ajax/myapi.json',
			parms,
			function(data) {
	// Assumption: we have saved the original viewModel
	var viewModel = $(document).data("MyViewModel");
	viewModel.savingGoalAmount(data.amount);
});
</pre>
</li>
<li>The ViewModel can also aggregate a <b>subset of attributes</b> from one or even several <b>server-side</b> [MVC] <b><u>M</u>odels</b><br/><br/>
						</li>
<li>Arbitrary Javascript functions can also subscribe to Value Model changes:<br/>
<pre class="brush: javascript">
// Set up the ViewModel
var viewModel = {
	savingGoalAmount: ko.observable(500), // dollars
	// ... more attributes ...
};

function GraphSavingScenario(newValue) {
	// some graphing logic
}

viewModel.savingGoalAmount.subscribe(GraphSavingScenario);
</pre>
<p>										<img src="./wp-content/media/knockoutjs/advanced-callback-function.png" /><br/>
						</li>
</ol>
<p>					<a name='sowhat'></a></p>
<h3>So What?</h3>
<p>KnockoutJS can help organize browser-side logic by facilitating the creation of panels (<b>Views</b>),<br />
					each logically data-bound to <a href="#mvvmp">ViewModels</a> built on top of a <u>local</u> <a href="#psp">publish/subscribe</a> mechanism using <a href="#obp">Observables</a>.<br/><br />
					Data-binding, combined with derived data / behaviors, and AJAX will boost the interactivity level of the application.
					</p>
<p>Part 2 of the series on &#8220;Creating Rich Interactive Web Apps&#8221; will be a tutorial on how to build a moderate complexity application with KnockoutJS.<br />
					We will cover the following topics:</p>
<ul>
<li>Enabling / disabling rules</li>
<li>Condition display</li>
<li>Leveraging jQuery templates</li>
<li>Extracting views into templates</li>
<li>&#8230; and more!</li>
</ul>
<p>So stay tuned!</p>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>Patterns</h5>
<ul>
<li><a name='mvvmp' href='http://en.wikipedia.org/wiki/Model_View_ViewModel'>Model View &#8211; ViewModel Pattern</a></li>
<li><a name='mvcp' href='http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html'>MVC Xerox Parc 1978-79</a></li>
<li><a name='mvcp' href='http://c2.com/cgi/wiki?ModelViewController'>MVC Pattern</a></li>
<li><a name='obp' href='http://c2.com/cgi/wiki?ObserverPattern'>Observer Pattern</a></li>
<li><a name='psp' href='http://c2.com/cgi/wiki?PublishSubscribeModel'>Publish Subscribe Pattern</a></li>
<li><a name='vmp' href='http://c2.com/cgi/wiki?ValueModel'>Value Model Pattern</a></li>
<li><a name='dbp' href='http://c2.com/cgi/wiki?DataBinding'>Data Binding Pattern</a></li>
</ul>
<h5>Frameworks And Blogs</h5>
<ul>
<li><a name='ko' href='http://knockoutjs.com/'>KnockoutJS</a></li>
<li><a name='lko' href='http://learn.knockoutjs.com/'>Learn KnockoutJS (Interactive Tutorial / Playground)</a></li>
<li><a name='jq' href='http://jquery.com/'>jQuery</a></li>
<li><a name='jqui' href='http://jqueryui.com/'>jQuery UI</a></li>
<li><a name='jqt' href='http://api.jquery.com/jQuery.template/'>jQuery Template</a></li>
<li><a name='jqtapi' href='http://api.jquery.com/jQuery.template/'>jQuery Template API</a></li>
<li><a name='ss' href='http://blog.stevensanderson.com/'>Knock Me Out (Steve Sanderson&#8217;s Blog)</a></li>
<li><a name='kmo' href='http://www.knockmeout.net/'>Knock Me Out (Ryan Niemeyer&#8217;s Blog)</a></li>
<li><a name='pflsjaa' href='http://addyosmani.com/blog/patterns-for-large-scale-javascript-application-architecture/'>Patterns For Large-Scale Javascript Architecture (Addy Osmani)</a></li>
</ul>
<p><!--					</p>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a name='caoauth' href='http://blog.monnet-usa.com/?p=XXX'>Easily Transform Your Ruby Camping App Into An OAuth Provider</a></li>
</ul>
<p>&#8211;><br />
					<a name='ko-fiddle'></a></p>
<h5>Source Of The KnockoutJS Examples</h5>
<p>You can find the examples on jsFiddle.net here:</p>
<ul>
<li><a href="http://jsfiddle.net/techarch/z5Ptd/" target="_blank">Basics &#8211; Example 1</a></li>
<li><a href="http://jsfiddle.net/techarch/YXxpG/" target="_blank">Building Up  &#8211; Example 1</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/3uaW3cw3oWQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=354</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=354</feedburner:origLink></item>
		<item>
		<title>Leverage Twitter Features In Your Ruby Application With Twitter4R</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/lWNQBxx00UM/</link>
		<comments>http://blog.monnet-usa.com/?p=342#comments</comments>
		<pubDate>Fri, 18 Mar 2011 03:24:08 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[Twitter4R]]></category>
<category>oauth</category><category>ruby</category><category>twitter</category><category>twitter4r</category>
		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=342</guid>
		<description><![CDATA[
						h3 {	text-decoration: underline; }
						h5 
						{
							margin:0 50px 0 50px;
						}
						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}

Intro 
A few years ago I integrated Twitter with a Ruby application, mainly to display a subset of my timeline.
					Later I added the ability to post tweets. All this became possible using Susan Potter&#8216;s &#8220;most-excellent&#8221; Twitter4R gem.
					
Back in late 2010, Twitter [...]]]></description>
			<content:encoded><![CDATA[<style>
						h3 {	text-decoration: underline; }</p>
<p>						h5 
						{
							margin:0 50px 0 50px;
						}</p>
<p>						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}</p>
</style>
<h3>Intro </h3>
<p>A few years ago I integrated Twitter with a Ruby application, mainly to display a subset of my timeline.<br />
					Later I added the ability to post tweets. All this became possible using <a href='#spbg'>Susan Potter</a>&#8216;s &#8220;most-excellent&#8221; <a href='#tw4rgh'>Twitter4R</a> gem.
					</p>
<p>Back in late 2010, Twitter upgraded its API from simple id/password authentication to <a href='#oan'>OAuth</a> authentication. The <a href='#tw4rgh'>Twitter4R</a> gem was then also enhanced to leverage the <a href='#oagh'>OAuth-Ruby</a> library. I had created a to-do item to go back and upgrade my apps so this past week I decided it was time to document the process in a quick tutorial!</p>
<h3>Twitter4R Approach</h3>
<p>					<img src='./wp-content/media/twitter4r/twitter4r-approach.png' width='60%'> </p>
<p>When you register your client application with Twitter, you are assigned an <a>App OAuth Token</a> consisting of a <a>consumer key</a> and <a>consumer secret</a> pair. Your app will configure Twitter4R to use this app token during all API calls with Twitter.</p>
<p>Your app will also need to keep track of <a>User OAuth Tokens</a> and pass a specific user token through the API.<br />
					Behind the scene Twitter4R will perform REST calls to the actual Twitter API using JSON data.
<p>If you only want your app to access your own account, you will create an Access Token for your Twitter account on your newly-registered app</p>
<h3>Playing With Twitter4R In The Console</h3>
<h5>Installing Twitter4R</h5>
<p>From a command window / shell, just run:</p>
<pre class="brush: ruby">
gem install oauth
</pre>
<p>Notice that both the Twitter4R and the OAuth gems are installed.</p>
<p>					<img src='./wp-content/media/twitter4r/twitter4r-install.png' > <br/><br/></p>
<h5>Registering Our App With Twitter</h5>
<p>To obtain a <a>consumer key and secret pair</a>, we&#8217;ll need to register our application with Twitter at <a href='https://dev.twitter.com/apps'>https://dev.twitter.com/apps</a>. We will need to provide the following:</p>
<ol>
<li>The name of our app (which must be unique within Twitter&#8217;s app registry)</li>
<li>A description</li>
<li>The base url of our app</li>
<li>The url to redirect authenticated users to in our app</li>
<li>The type of access needed: read or read/write (if we want to be able to update our status)</li>
</ol>
<p>						<span>Example:</span><br/><br />
						<img src='./wp-content/media/twitter4r/twitter4r-registration.png' > <br/><br/>
					</p>
<h5>Obtaining Your Own User OAuth Access Token</h5>
<p>Once you have registered the app, if you click on the &#8220;My Access Token&#8221; button, Twitter will give your OAuth user key and secret token.<br />
					<span>Example:</span><br/><br />
					<img src='./wp-content/media/twitter4r/twitter4r-mytoken.png' > <br/><br/>
					</p>
<p>In another section we&#8217;ll see how to authorize a user and get its access token programmatically.</p>
<h5>Testing Twitter4R In IRB</h5>
<p>Let&#8217;s start a Ruby console using IRB and load Twitter4R:</p>
<pre class="brush: ruby">
gem 'twitter4r'
require 'twitter'
require 'twitter/console'
 </pre>
<p>Now we can configure the Twitter4R client using the Twitter::Client.configure class method.<br />
					The block allows us to customize the application and its app OAuth token. Evaluate the following code snippet:</p>
<pre class="brush: ruby">
Twitter::Client.configure do |conf|
   # App configuration
   conf.application_name = 'BeaconPulse)))'
   conf.application_version = '1.0'
   conf.application_url = 'http://beaconpulse.heroku.com/'

   #  App OAuth token key/secret pair
   conf.oauth_consumer_token = "***YourAppConsumerKeyFromYourTwitterAppRegistration***"
   conf.oauth_consumer_secret = "***YourAppConsumerSecretFromYourTwitterAppRegistration***"
end
</pre>
<p>We can then inspect the resulting configuration using:</p>
<pre class="brush: ruby">
cfg = Twitter::Client.config
 </pre>
<h5>Instantiating A Twitter4RClient</h5>
<p>We&#8217;ll use the user key/secret pair we looked up on the Twitter Access Token page earlier:</p>
<pre class="brush: ruby">
client = Twitter::Client.new(:oauth_access =>
 { 	:key 	=> "***YourUserOAuthAccessTokenKey***",
	:secret => "***YourUserOAuthAccessTokenPassword***"
 })
 </pre>
<h5>Taking Twitter Features For A Spin</h5>
<p>Now that we have a client instance, we can exercise its various methods (see <a href='http://twitter4r.rubyforge.org/rdoc/classes/Twitter/Client.html'>rdoc</a> for details) such as:</p>
<ul>
<li><a href='http://twitter4r.rubyforge.org/rdoc/classes/Twitter/Client.html#M000048'>user</a> information about a given account:
<pre class="brush: ruby">
i = client.user 'techarch'
 </pre>
</li>
<li><a href='http://twitter4r.rubyforge.org/rdoc/classes/Twitter/Client.html#M000049'>my</a> info / friends / followers:
<pre class="brush: ruby">
fr = client.my :friends
fo = client.my :followers
 </pre>
</li>
<li><a href='http://twitter4r.rubyforge.org/rdoc/classes/Twitter/Client.html#M000035'>timeline_for</a> me / user / public / friends / :
<pre class="brush: ruby">
tm = client.timeline_for :me
tm1 = client.timeline_for :me, :count => 1 # my last tweet

tu = client.timeline_for :user, :id => 'susanpotter'
tp = client.timeline_for :public
tf = client.timeline_for :friends
 </pre>
</li>
<li>post a <a href='http://twitter4r.rubyforge.org/rdoc/classes/Twitter/Client.html#M000045'>status</a>:
<pre class="brush: ruby">
t = client.status :post, 'Posting tweets from IRB using the Twitter4R gem rocks!'
</pre>
</li>
</ul>
<p>					As you can see you can have a lot of fun with the client!
					</p>
<h3>Authorizing A User And Getting Its Access Token</h3>
<p>In an earlier section, we just looked up our own access token on the Twitter page for our app registration.<br />
					But to allow any user to access our app we would need to:</p>
<ol>
<li>Instantiate an <a>OAuth Consumer</a> (like Twitter4R does behind the scenes) with our app consumer key/secret pair:
<pre class="brush: ruby">
# we reuse the cfg variable we set earlier since it contains our app configuration
k = cfg.oauth_consumer_token
s = cfg.oauth_consumer_secret
u = "#{(cfg.protocol == :ssl ? :https : cfg.protocol).to_s}://#{cfg.host}:#{cfg.port}"

oc = OAuth::Consumer.new(k ,s, :site=> u)
</pre>
</li>
<li>Ask the OAuth consumer to:
<ul>
<li>create an <a>OAuth RequestToken</a> (a temporary credential token used to authenticate our consumer app on Twitter)</li>
<li>and give us an authorization url:</li>
</ul>
<pre class="brush: ruby">
rt = oc.get_request_token
auth_url = rt.authorize_url
</pre>
<p>							We can actually paste this url in a browser.<br/><br/>
							</li>
<li>Redirect the user to the authorization url so that Twitter can prompt for authorization to access our app<br/><br/>
							</li>
<li>Once authorized, get the <a>OAuth Verifier</a> (a verification code which will be passed back to Twitter in subsequent requests) <br/><br/>
							</li>
<li>User the Request Token to retrieve an <a>OAuth AccessToken</a> (the actual authorized user token needed for all future API calls to Twitter) for the user based on the OAuth Verifier:
<pre class="brush: ruby">
at = rt.get_access_token(:oauth_verifier=>'***ThePINnumberReturnedByTwitter***')

user_key = at.token
user_secret = at.secret
 </pre>
</li>
<li>Optionally store the user OAuth key/secret pair so we can instantiate a Twitter4R Client to invoke APIs on the user&#8217;s behalf:
<pre class="brush: ruby">
client = Twitter::Client.new(:oauth_access => { :key => user_key, :secret => user_secret })
info = client.user 'techarch'
 </pre>
</li>
</ol>
<h3>Approach For Integrating Twitter4R In Your App</h3>
<p>Now that you have a handle on the basics using the Interactive Ruby Console, you can check out the full <a href='http://twitter4r.rubyforge.org/rdoc/'>RDoc</a><br />
					and add Twitter support to your favorite Ruby app. In a future blog post I&#8217;ll cover the integration approach for a Ruby Camping web app.</p>
<p><span>Here is what the Twitter4R ecosystem looks like from 50,000 feet:</span><br/><br />
					<img src='./wp-content/media/twitter4r/twitter4r-yuml.png' > </p>
<p><br/></p>
<h3>So What? </h3>
<p>Since Twitter has moved to <a href='#oan'>OAuth</a> you need a robust and efficient library like <a href='#tw4rgh'>Twitter4R</a> to integrate Twitter in your application.<br />
					<a href='#tw4rgh'>Twitter4R</a> leverages the Twitter REST API using the JSON format to limit bandwith consumption.<br />
					The gem is &#8220;framework-neutral&#8221;, so it can be used in pure Ruby apps, as well as on top of frameworks such as Rails, <a href='#rc'>Ruby-Camping</a>, and Sinatra.<br/><br />
					If you have not experimented with <a href='#tw4rgh'>Twitter4R</a>, hopefully this tutorial will get you started.</p>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>Twitter4R</h5>
<ul>
<li><a name='tw4rgh' href='https://github.com/twitter4r/twitter4r-core'>Twitter4R on GitHub</a></li>
<li><a name='spbg' href='http://geek.susanpotter.net/'>Susan Potter&#8217;s blog</a></li>
<li><a name='tw4rsh' href='http://www.slideshare.net/mbbx6spp/twitter4r-oauth'>&#8220;Configuring Your Twitter4R App With OAuth&#8221; by Susan Potter &#8211; on SlideShare</a></li>
</ul>
<h5>OAuth And My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a name='oan' href='http://oauth.net/'>OAuth.net site</a></li>
<li><a name='oau' href='http://hueniverse.com/'>OAuth Universe site</a></li>
<li><a name='oagh' href='https://github.com/oauth/oauth-ruby'>OAuth Ruby on GitHub</a></li>
<li><a href='http://blog.monnet-usa.com/?p=293'>Transform Your Ruby Camping Web App Into An OAuth Provider (explains the OAuth &#8220;dance&#8221;!)</a></li>
<li><a name='rc' href='http://github.com/camping/camping'>Ruby Camping Framework</a></li>
</ul>
<div class="blog-msm-ad">
<div class="blog-msm-ad1">
							If you enjoyed this post, I would love it if you could check out <a href="http://bit.ly/myskillsmap">mySkillsMap</a>, my skills management app.
						</div>
<div class="blog-msm-ad2">
								<a href="http://www.myskillsmap.com/take-charge-of-your-skills-development"><br />
									<img src='./wp-content/media/msm/start-your-free-trial-now.png'  /><br />
								</a>
						</div>
</p></div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/lWNQBxx00UM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=342</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=342</feedburner:origLink></item>
		<item>
		<title>Improving Web Conversions In 3 Key Steps</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/AxZHQY7jtQE/</link>
		<comments>http://blog.monnet-usa.com/?p=337#comments</comments>
		<pubDate>Sun, 09 Jan 2011 15:00:05 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[A/B Testing]]></category>
		<category><![CDATA[Conversion Optimization]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Web Analytics]]></category>
<category>a/b testing</category><category>conversion optimization</category><category>seo</category><category>web analytics</category>
		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=337</guid>
		<description><![CDATA[
						h3 {	text-decoration: underline; }
						h5 
						{
							margin:0 50px 0 50px;
						}
						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}

Intro 
I am a huge fan of the TechZing podcast, a show focused on bootstrapped web entrepreneur.
					In the last couple months Jason Roberts and Justin Vincent
					have had a series of interviews focused on improving usability, web analytics.
					The latest show (#98) includes [...]]]></description>
			<content:encoded><![CDATA[<style>
						h3 {	text-decoration: underline; }</p>
<p>						h5 
						{
							margin:0 50px 0 50px;
						}</p>
<p>						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}</p>
</style>
<h3>Intro </h3>
<p>I am a huge fan of the <a href="http://techzinglive.com/">TechZing</a> podcast, a show focused on bootstrapped web entrepreneur.<br />
					In the last couple months <a href="http://www.codusoperandi.com/">Jason Roberts</a> and <a href="http://justinvincent.com/">Justin Vincent</a><br />
					have had a <a href='#tzshows'>series of interviews</a> focused on improving usability, web analytics.<br />
					The <a href="http://techzinglive.com/page/606/98-tz-interview-lance-jones-conversion-optimization/">latest show (#98)</a> includes Lance Jones as a guest and focuses on <b>Conversion Optimization</b>.
					</p>
<p>After listening to the show while driving I decided to replay it once more and take notes as I think it brings a lot of value for any web entrepreneur!<br />
					And since I could not fit all the contents and links in the comments I decided to create this short post. Enjoy!</p>
<h3>The 3-Step Process</h3>
<p>					<img src='./wp-content/media/conversion-optimization/conversion-optimization-1.png' width='80%'></p>
<p>Before starting any A/B test or optimization it is important to really think through the goals and key performance indicators you want to optimize for.<br />
					Otherwise you will waste a lot of time or may not get meaningful information and probably not achieve your target goals.<br />
					To optimize the conversion process you need to:</p>
<ol>
<li>Track and analyze <b>conversions</b></li>
<li>Analyze and understand <b>user behavior</b></li>
<li>Optimize the <b>user experience</b>, the <b>copy (key content)</b>, and <b>affect user behavior</b></li>
</ol>
<p>It is critical to have enough traffic to get statistically meaningful data from the tests.<br />
							You need probably about 100 conversions per bucket or test option.<br />
							So assuming different conversion rates you need quite a lot of users entering the funnel:</p>
<ul>
<li>a 2% conversion rate requires 5000 users</li>
<li>a 5% conversion rate requires 2000 users</li>
<li>etc.</li>
</ul>
<h3>Supporting Tools</h3>
<style>
						#tools_table {border: 1px solid #f0f0f0;border-spacing: 1px;background-color:#eee;margin:10px 0px 0px 40px;border: 1px solid black;}
						#tools_table tr {vertical-align: top;border-bottom: 1px solid #eee;}
						.tools_table_section {background-color:lightgray;}
						#tools_table th {background-color:lightgray;}
						#tools_table td {border-bottom: 1px solid #eee;}</p>
</style>
<table id="tools_table" style="">
<tr>
<th>Product</th>
<th>Comments</th>
</tr>
<tr>
<td class="tools_table_section" colspan='2'>Tools to tracking and analyze conversions</td>
</tr>
<tr>
<td><a href="http://getclicky.com">Clicky</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://www.google.com/websiteoptimizer">Google web site optimizer</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://www.crazyegg.com">Crazyegg</a></td>
<td>Includes  heatmap</td>
</tr>
<tr>
<td><a href="http://mixpanel.com">Mixpanel</a></td>
<td>Great for tracking business/user events</td>
</tr>
<tr>
<td><a href="http://www.performable.com">Performable</a></td>
<td>Full customer experience and revenue tracking, reverse funnel analysis</td>
</tr>
<tr>
<td><a href="http://www.omniture.com">Omniture</a></td>
<td>The Cadillac option for large enterprises</td>
</tr>
<tr>
<td  class="tools_table_section" colspan='2'>Tools to survey and understand user behavior</td>
</tr>
<tr>
<td><a href="http://www.iperceptions.com">iperceptions</a></td>
<td>Define quick short surveys to understand user motivations and success</td>
</tr>
<tr>
<td><a href="http://www.kissinsights.com">KissInsights</a></td>
<td>Prompt users for one quick simple question</td>
</tr>
<tr>
<td><a href="http://www.4qsurvey.com">4Q Survey</a></td>
<td>Prompts users for the 4 essential questions about their experience</td>
</tr>
<tr>
<td><a href="http://www.foreseeresults.com">ForeseeResults</a></td>
<td>Focuses on complete web effectiveness</td>
</tr>
<tr>
<td><a href="http://www.opinionlab.com">Opinionlab</a></td>
<td>More sophisticated option with survey modules, reports, <etc></etc></p>
<div class=""></div>
</td>
</tr>
<tr>
<td class="tools_table_section" colspan='2'>Getting input from real testers</td>
</tr>
<tr>
<td><a href="http://www.usertesting.com">UserTesting</a></td>
<td>Testers narrate their test using video</td>
</tr>
<tr>
<td><a href="http://www.feedbackarmy.com">FeedbackArmy</a></td>
<td>You submit 4-6 questions about your site and you receive 10 answers</td>
</tr>
<tr>
<td><a href="http://fivesecondtest.com">5secondtest</a></td>
<td>Testers have 5 seconds to get an impression of your landing page</td>
</tr>
<tr>
<td class="tools_table_section" colspan='2'>Tools to optimize the site</td>
</tr>
<tr>
<td><a href="http://www.google.com/websiteoptimizer">Google web site optimizer</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://www.sumooptimize.com">SumoOptimize</a></td>
<td>Recent entrant</td>
</tr>
<tr>
<td><a href="http://www.optimizely.com">Optimizely</a></td>
<td>Great wysiwyg editing of your own pages</td>
</tr>
<tr>
<td><a href="http://unbounce.com">Unbounce</a></td>
<td>Great for testing different landing pages and starting A/B tests</td>
</tr>
<tr>
<td><a href="http://visualwebsiteoptimizer.com">Visual website optimizer</a></td>
<td>Rich functionality with a great wysiwyg interface</td>
</tr>
</table>
<p><i>Note: the list above and associated comments are just based on the show, not on an exhaustive analysis of all vendors and products.</i></p>
<h3>So What? </h3>
<p>So if you put all the concepts together you get the following approach synopsis:</p>
<p>					<img src='./wp-content/media/conversion-optimization/conversion-optimization-2.png' width='100%'></p>
<p>Web conversion optimization is not &#8220;black magic&#8221;, try to follow the process highlighted above as well as the tools.<br/><br />
					Providing you can generate enough traffic to your site to run multiple iterations, over time you will most likely see a positive change in your conversions.</p>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>A/B Testing</h5>
<ul>
<li><a name='abwp' href='http://en.wikipedia.org/wiki/A/B_Testing'>A/B Testing Definition on Wikipedia</a></li>
<li><a name='abbasics' href='http://elem.com/~btilly/effective-ab-testing/'>Effective A/B Testing Basics (by Ben Tilly)</a></li>
</ul>
<p>					<a name="tzshows"></a></p>
<h5>TechZing</h5>
<ul>
<li><a name='tz' 	href='http://techzinglive.com'>TechZing Podcast for web startup entrepreneurs</a></li>
<li><a name='tzjr' 	href='http://www.codusoperandi.com/'>Jason Robert&#8217;s blog</a></li>
<li><a name='tzjv' 	href='http://justinvincent.com/'>Justin Vincent&#8217;s blog</a></li>
<li><a name='tz98' 	href='http://techzinglive.com/page/606/98-tz-interview-lance-jones-conversion-optimization/'>TechZing 98: TZ Interview – Lance Jones / Conversion Optimization</a></li>
<li><a name='tz92' 	href='http://techzinglive.com/page/544/92-tz-interview-ilya-lichtenstein-insight-io'>TechZing 92: TZ Interview – Ilya Lichtenstein / insight.io</a></li>
<li><a name='tz89' 	href='http://techzinglive.com/page/528/89-tz-interview-david-cancel-performable'>TechZing 89: TZ Interview – David Cancel / Performable</a></li>
<li><a name='tz87' 	href='http://techzinglive.com/page/522/87-tz-interview-luke-wroblewski-the-user-interface-is-the-product'>TechZing 87: TZ Interview – Luke Wroblewski / The User Interface Is The Product</a></li>
<li><a name='tz79' 	href='http://techzinglive.com/page/479/79-tz-interview-%e2%80%93-patrick-mckenzie-optimize-this'>TechZing 79: Patrick McKenzie / The Long Tail of Optimization</a></li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a href='http://blog.monnet-usa.com/?p=223'>Visualize Application Metrics on NewRelic for your Ruby Camping Application</a></li>
<li><a href='http://blog.monnet-usa.com/?p=322'>A/B Test Your Ruby Camping Web App Using ABingo</a></li>
</ul>
<div class="blog-msm-ad">
<div class="blog-msm-ad1">
							If you enjoyed this post, I would love it if you could check out <a href="http://bit.ly/myskillsmap">mySkillsMap</a>, my skills management app.
						</div>
<div class="blog-msm-ad2">
								<a href="http://www.myskillsmap.com/take-charge-of-your-skills-development"><br />
									<img src='./wp-content/media/msm/start-your-free-trial-now.png'  /><br />
								</a>
						</div>
</p></div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/AxZHQY7jtQE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=337</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=337</feedburner:origLink></item>
		<item>
		<title>A/B Test Your Ruby Camping Web App Using ABingo (Part 2)</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/R_H-HYQKvmg/</link>
		<comments>http://blog.monnet-usa.com/?p=330#comments</comments>
		<pubDate>Tue, 14 Dec 2010 07:00:16 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=330</guid>
		<description><![CDATA[Intro 
In &#8220;A/B Test Your Ruby Camping Web App Using ABingo (Part 1)&#8221;, I introduced  the ABingo A/B testing framework and the new Camping ABingo plugin. In this article I will cover the following topics:
					

Look under the ABingo Hood to understand its API, object model, and underlying database tables
Create a draft of the ABingo [...]]]></description>
			<content:encoded><![CDATA[<h3>Intro </h3>
<p>In <a href="http://blog.monnet-usa.com/?p=322">&#8220;A/B Test Your Ruby Camping Web App Using ABingo (Part 1)&#8221;</a>, I introduced  the <a href="#abpmk">ABingo A/B testing framework</a> and the new <a href="#tacaab">Camping ABingo plugin</a>. In this article I will cover the following topics:
					</p>
<ol>
<li>Look under the ABingo Hood to understand its API, object model, and underlying database tables</li>
<li>Create a draft of the ABingo Test Application</li>
<li>Integrate ABingo into our test app</li>
<li>Run and analyze experiments</li>
</ol>
<h3>Under The ABingo Hood</h3>
<p>Before we can dive in the integration of the <a href='#tacaab'>Camping ABingo plugin</a> with our prototype application, here is a quick overview of the basics of the ABingo framework.</p>
<h4>ABingo API</h4>
<p>The two most important APIs are <a href="http://camping-abingo.monnet-usa.com/classes/ABingoCampingPlugin/Helpers.html#M000050">ab_test</a> and <a href="http://camping-abingo.monnet-usa.com/classes/Abingo.html#M000006">bingo!</a>:<br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-api.png'  width="90%" />
					</p>
<table class='details_table'>
<tr>
<th>API</th>
<th>Parameters</th>
<th>Context</th>
<th>Purpose/Usage</th>
</tr>
<tr>
<td><a name='api_ab_test'><br />
		</a>ab_test</td>
<td>
<ul class="api_parm">
<li>test name</li>
<li><i>optional:</i> array of alternatives</li>
<li><i>optional:</i> conversion name</li>
</ul>
</td>
<td>View or Controller</td>
<td>Select an alternative for the current user based on the alternatives specified for this test. If no alternatives are specified a boolean value is returned. Tracks the execution using the conversion name if provided otherwise use the test name.</td>
</tr>
<tr>
<td><a name='api_bingo'></a>bingo!</td>
<td>
<ul  class="api_parm">
<li>conversion name (or test name)</li>
</ul>
</td>
<td>Controller</td>
<td>Tracks a conversion for the current user and the conversion specified. The test name is the fallback option.</td>
</tr>
</table>
<p>					<br/></p>
<p>Note: these 2 main APIs are implemented in Camping in a helper module being included in both controllers and views. The <b>ab_test</b>  is <i>syntactic sugar</i> over the <b>test</b> method provided by the core <a href="http://camping-abingo.monnet-usa.com/classes/Abingo.html" target=”_blank”>Abingo class</a>.</p>
<h4  style="page-break-before:always;">Model</h4>
<p>The basic object model for the ABingo framework looks like this:<br/><br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-uml.png' width='100%'/><br/>
					</p>
<p><a name='abmo'></a></p>
<table class='details_table'>
<tr>
<th>Model</th>
<th>Responsibilities</th>
</tr>
<tr>
<td><a name='abus'></a>User</td>
<td>The user account on the prototype app</td>
</tr>
<tr>
<td><a name='abapi'></a>Abingo</td>
<td>ABingo&#8217;s main API class</td>
</tr>
<tr>
<td><a name='abexp'></a>Experiment</td>
<td>Represents a specific test based on multiple alternatives</td>
</tr>
<tr>
<td><a name='abalt'></a>Alternative</td>
<td>Tracks participants and conversions for a given alternative</td>
</tr>
</table>
<p>					<br/></p>
<h4>ABingo Database Tables</h4>
<p>ABingo will need to track executions of your <a href="#abexp">Experiments</a> and their corresponding <a href="#abalt">Alternatives</a> in the database associated with your application. So the ABingo Camping plugin will include the needed migration to add 2 tables to your schema. We&#8217;ll see this in more details later.</p>
<h3>Create An ABingo Test Application</h3>
<h4>Install Camping-ABingo</h4>
<p>First let&#8217;s install the gem. (If you don&#8217;t have Camping or any of its dependent gem they will be installed)</p>
<pre class="brush: ruby; gutter: false; toolbar: false;">
gem install camping-abingo
</pre>
<p>Note: You will find the fully functional test application under the <b>examples/camping-abingo-test</b> folder in the camping-abingo gem folder. If you want to start using it right away, skip the next sections and go straight to <b><a href="#caabtest">Setting Up Our First A/B Test</a></b>. Otherwise follow along.</p>
<h4>Running the Skeleton pre-ABingo Test Application</h4>
<p>In the next sections I will show you how to integrate ABingo with the skeleton test app. But before let&#8217;s get the skeleton application up and running.</p>
<ol class="blog-post-list">
<li>Locate the <b>examples/camping-abingo-test</b> folder under your camping-abingo gem folder.<br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-cmd-1.png' ><br/><br />
					There are two versions of the test app: </p>
<ul>
<li>the skeleton (without ABingo support)</li>
<li>the fully implemented version</li>
</ul>
</li>
<li>Open <b>camping-abingo-test-skeleton.rb</b> in an editor. </li>
<li>Then let&#8217;s start the <b>Camping</b> server with our skeleton:
<pre class="brush: ruby; gutter: false; toolbar: false;">
camping camping-abingo-test-skeleton.rb
</pre>
</li>
<li>Open a browser and access the skeleton from the browser at the following url:
<pre class="brush: ruby; gutter: false; toolbar: false;">

http://localhost:3001/
</pre>
<p>						<span  style="page-break-before:always;">Camping will run the first migration to create the table for our User model:</span><br/><br/><br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-cmd-migration1.png' width="610px"><br/><br/></p>
<p>						And the basic test app should now come up:<br/><br/><br />
						<img src='./wp-content/media/camping-abingo/camping-abingo-tester.png' ><br/>
						</li>
<li>You can now test the basic flow of the application. When viewing the landing page, the sign-up button should always be labeled &#8220;Sign-Up Now!&#8221;. Once ABingo is integrated we will be experimenting with different alternatives.</li>
</ol>
<p>					<a name="addabprsu" ></a></p>
<h3>Adding ABingo Support To The Skeleton Test App</h3>
<p>The ABingo plugin is composed of several modules mirroring the standard modules a typical Camping application would contain.<br />
					Integrating the plugin will consist of linking the various modules using a combination of <b>include</b> and/or <b>extend</b> statements where appropriate. Here is a high-level diagram of the integration approach:</p>
<p>					<img src='./wp-content/media/camping-abingo/camping-abingo.png' width="600px" style="margin-left: 40px"><br/><br />
					<br/></p>
<p  style="page-break-before:always;">Here are the steps we will be following:</p>
<p><a name='caoatodo'></a></p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
</tr>
<tr>
<td><a href='#caabtodoa'>A</a></td>
<td>Reference and require the needed gems</td>
</tr>
<tr>
<td><a href='#caabtodob'>B</a></td>
<td>Customize the main module</td>
</tr>
<tr>
<td><a href='#caabtodod'>C</a></td>
<td>Plugging in the ABingo common helpers module</td>
</tr>
<tr>
<td><a href='#caabtodoc'>D</a></td>
<td>Plugging in the ABingo Experience and Alternative models</td>
</tr>
<tr>
<td><a href='#caabtodoe'>E</a></td>
<td>Plugging in the ABingo Dashboard controllers</td>
</tr>
<tr>
<td><a href='#caabtodof'>F</a></td>
<td>Plugging in the ABingo Dashboard views</td>
</tr>
<tr>
<td><a href='#caabtodog'>G</a></td>
<td>Add code to manage the ABingo user identity in our controllers</td>
</tr>
</table>
<p>	</p>
<p>					<a name='caabtodoa'></a></p>
<h5>A. Reference and require the needed gems</h5>
<p>We will need to reference 2 gems: <b>filtering_camping</b> and <b>camping-abingo</b>. Also we will require the corresponding files we need: filtering_camping and camping-abingo.So now the top of the source should look like this:</p>
<pre class="brush: ruby">
gem 'camping' , '>= 2.0'
gem 'filtering_camping' , '>= 1.0'
gem 'camping-abingo'

%w(rubygems active_record erb  fileutils json markaby md5 redcloth
camping camping/session filtering_camping camping-abingo
).each { |lib| require lib }

Camping.goes :CampingABingoTest
</pre>
<p>					<a name='caabtodob'></a></p>
<h5>B.Customizing the main module</h5>
<p>Ok, so now we&#8217;re ready to enhance the main app module. First we&#8217;ll make sure to include the Camping::Session and CampingFilters modules, and to extend the app module with ABingoCampingPlugin and its Filters submodule, like so:</p>
<pre class="brush: ruby">
module CampingABingoTest
	include Camping::Session
	include CampingFilters

	extend  ABingoCampingPlugin
	include ABingoCampingPlugin::Filters

	# ...
end
</pre>
<p>We can also associate the logger with our <a href='#tacaab'>camping-abingo plugin</a>.</p>
<pre class="brush: ruby">
	Camping::Models::Base.logger = app_logger
	ABingoCampingPlugin.logger   = app_logger
</pre>
<p>Now let&#8217;s customize the <b>create</b> method by adding a call to ABingoCampingPlugin.create, so we can get the plugin to run any needed initialization.</p>
<pre class="brush: ruby">
	def CampingABingoTest.create
		ABingoCampingPlugin.create
	end
</pre>
<p>We need to more things: let&#8217;s link our logger to the ABingo cache logger (to make it easier to debug issues), and let&#8217;s define which User id represent the administrator who will have access to the ABingo Dashboard. Now the final version of the create method looks like this:</p>
<pre class="brush: ruby">
	def CampingABingoTest.create
		dbconfig = YAML.load(File.read('config/database.yml'))
		environment = ENV['DATABASE_URL'] ? 'production' : 'development'
		Camping::Models::Base.establish_connection  dbconfig[environment]

		ABingoCampingPlugin.create
		Abingo.cache.logger = Camping::Models::Base.logger
		Abingo.options[:abingo_administrator_user_id] = 1

		CampingABingoTest::Models.create_schema :assume => (CampingABingoTest::Models::User.table_exists? ? 1.1 : 0.0)
	end
</pre>
<p>Ok, at this point we have a minimally configured application module. </p>
<p>					<span  style="page-break-before:always;"></span><br />
					<a name='caabtodod'></a></p>
<h5>C.Plugging in the ABingo common helpers module</h5>
<p>The Helpers module is used in <a href='#rc'>Camping</a> to provide common utilities to both the Controllers and Views modules. Enhancing our Helpers module is very easy, we need to add both an <b>extend</b> and an <b>include</b> of the ABingoCampingPlugin::Helpers module so we can enhance both instance and class sides:</p>
<pre class="brush: ruby">
module CampingABingoTest::Helpers
	extend ABingoCampingPlugin::Helpers
	include ABingoCampingPlugin::Helpers
end</pre>
<p>					<a name='caabtodoc'></a></p>
<h5>D.Plugging in the ABingo Experience and Alternative models</h5>
<p>First, we&#8217;ll include the include ABingoCampingPlugin::Models module so we can get all the <a href='#abmo'>ABingo-specific models</a>. Our model will look like this:</p>
<pre class="brush: ruby">
module CampingABingoTest::Models
	include ABingoCampingPlugin::Models

	# ...
end
</pre>
<p>Now we&#8217;ll enhance the CreateUserSchema migration class to plug in our ABingo model migration.</p>
<ul>
<li>We&#8217;ll bump up the migration version number of the CreateUserSchema class to 1.1</li>
<li>In the <b>up</b> method we will add a call to <b>ABingoCampingPlugin::Models.up</b> so that the <a href='#abexp'>Experience</a>, <a href='#abalt'>Alternative</a> tables can be created.</li>
<li>In the <b>down</b> method we will add a call to <b>ABingoCampingPlugin::Models.down</b> to drop the ABingo tables.</li>
</ul>
<pre class="brush: ruby">
	class CreateUserSchema < V 1.1
		def self.up
			create_table :CampingABingoTest_users, :force => true do |t|
				# ...
			end

			# ...

			ABingoCampingPlugin::Models.up
		end

		def self.down
			ABingoCampingPlugin::Models.down

			drop_table :CampingABingoTest_users
		end
	end
</pre>
<p>Now if we restart the application, our version 1.1 migration should be executed:</p>
<p>					<img src='./wp-content/media/camping-abingo/camping-abingo-cmd-migration2.png' /></p>
<p>					<span  style="page-break-before:always;"></span><br />
					<a name='caabtodoe'></a></p>
<h5>E.Plugging in the ABingo Dashboard controllers</h5>
<p>We will need to extend our app <b>Controllers</b> module with the <b>ABingoCampingPlugin::Controllers</b> module using the <b>extend</b> statement. Then just before the end of the Controllers module, we&#8217;ll add a call to the <b>include_abingo_controllers</b> method. This is how <a href='#tacaab'>camping-abingo</a> will inject and plugin the ABingo Dashboard controllers and helpers. It is important that this call <u>always remaining the last statement of the module</u>, even when you add new controller classes. So the module should look like so:</p>
<pre class="brush: ruby">
module CampingABingoTest::Controllers
	extend ABingoCampingPlugin::Controllers

	# ...

	include_abingo_controllers
end #Controllers
</pre>
<p>					<a name='caabtodof'></a></p>
<h5>F.Plugging in the ABingo Dashboard views</h5>
<p>We will need to extend our app <b>Views</b> module with the <b>ABingoCampingPlugin::Views</b> module using the <b>extend</b> statement. Then just before the end of the Views module, we&#8217;ll add a call to the <b>include_abingo_views</b> method. This is how <a href='#tacaab'>camping-abingo</a> will inject and plugin the ABingo Dashboard views. It is important that this call <u>always remaining the last statement of the module</u>, even when you add new view methods. So the module should look like so:</p>
<pre class="brush: ruby">
module CampingABingoTest::Views
	extend ABingoCampingPlugin::Views

	# ...

	include_abingo_views
end
</pre>
<p>					<a name='caabtodog'></a></p>
<h5>G.Add code to manage the ABingo user identity in our controllers</h5>
<p>ABingo tracks the selected experiment alternatives and potential conversions for a <b>given user</b> using a property named <a href="http://camping-abingo.monnet-usa.com/classes/Abingo.html#M000003">identity</a>. Currently the <b>ABingoCampingPlugin::Filters</b> we included in our main module provides a <b>filter</b> that executes <b>before all</b> controllers. That filter is responsible for ensuring the <b>Abingo.identity</b> is set using either a large random integer if the user is anonymous, or the actual id of an existing user. Here is what the filter looks like:</p>
<pre class="brush: ruby">
	before :all do
		set_abingo_identity
	end
</pre>
<p>To handle non-anonymous users and for our integration with our controllers to be complete we will need to:</p>
<ol class="blog-post-list">
<li>Set the identity to the new user&#8217;s id once signup is complete.<br/><br />
							So in the <b>post</b> action of our <b>SignUp</b> controller, let&#8217;s set the <b>@state.abingo_identity</b> to our user&#8217;s id before rendering the Welcome view &#8211; see line 14:</p>
<pre class="brush: ruby">
	class SignUp < R '/signup'
		# get ...

		def post
			@user = User.find_by_username(input.username)
			if @user
				@info = 'A user account already exist for this username.'
			else
				@user = User.new :username => input.username,
					:password => input.password
				@user.save
				if @user
					@state.user_id = @user.id
					@state.abingo_identity = @user.id
					redirect R(Welcome)
				else
					@info = @user.errors.full_messages unless @user.errors.empty?
				end
			end
			render :signup
		end
	end
</pre>
</li>
<li>Replace the <b>abingo_identity</b> with the user&#8217;s id (<b>@user.id</b>) when someone signs-in. See line 9:
<pre class="brush: ruby">
	class SignIn < R '/signin'
		# ...

		def post
			@user = User.find_by_username_and_password(input.username, input.password)

			if @user
				@state.user_id = @user.id
				@state.abingo_identity = @user.id

				if @state.return_to.nil?
					redirect R(Welcome)
				else
					return_to = @state.return_to
					@state.return_to = nil
					redirect(return_to)
				end
			else
				@info = 'Wrong username or password.'
			end

			render :signin
		end
	end
</pre>
</li>
<li>Generate a new random identity when the current user has signed-out.<br/><br />
						So let's set the <b>@state.abingo_identity</b> to another large random integer in the <b>get</b> action of our <b>SignOut</b> controller. See line 4:</p>
<pre class="brush: ruby">
	class SignOut < R '/signout'
		def get
			@state.user_id = nil
			@state.abingo_identity = Abingo.identity = rand(10 ** 10).to_i

			render :index
		end
	end
</pre>
</li>
<ol>
<p>Now our integration steps are complete. We're now ready to do some A/B testing!</p>
<p>					<a name='caabtest'></a></p>
<h3>Setting Up Our First A/B Test</h3>
<h5>Selecting A Random Alternative For a Given Experience</h5>
<p>For our first experiment named <b>call_to_action</b> we'll vary the text for our <b>signup_btn</b> button by selecting one of 3 alternatives based on the user.<br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-abtests-funnel-2.png'  width="90%" /><br/></p>
<p>					So let's modify the <b>landing</b> view of our test application. We'll change the assignment of the <b>signup_text</b> variable to the result of the <a href="http://camping-abingo.monnet-usa.com/classes/ABingoCampingPlugin/Helpers.html#M000050">ab_test</a> call. So our code will look like the following (with the ab_test call on line 9):</p>
<pre class="brush: ruby">
	def landing
		div.xyz do
			h1 'XYZ SAAS Application'

			div.marketing! do
				# benefits ...

				div.actnow! do
					signup_text = ab_test("call_to_action",
											[ 	"Sign-Up Now!",
												"Try It For Free Now!",
												"Start Your Free Trial Now!",
											])

					a :href=>"/signup" do
						div.signup_btn!  signup_text
					end
				end
			end
		end
	end
</pre>
<h5>Recording A User Conversion</h5>
<p>If we ran the application now ABingo would choose an alternative and keep track of it in terms of user <b>participation</b>.<br />
					So now we just need to <b>record</b> an actual <b>conversion</b> for the <b>call_to_action</b> test when the user clicks on the <b>signup_btn</b> button.<br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-abtests-funnel-3.png'  width="90%" /><br/>					</p>
<p>					To do that, we'll enhance the <b>get</b> action of our <b>SignUp</b> controller by calling the <a href="http://camping-abingo.monnet-usa.com/classes/Abingo.html#M000006">bingo!</a> API with <b>call_to_action</b> as the name of the test. See line 3 below:</p>
<p>At this stage, we have a basic Camping ABingo-enabled application, now let's test it!</p>
<h3  style="page-break-before:always;">Running Our First A/B Test</h3>
<p>So let's refresh the browser - if you stopped the Camping server then restart it (as a note Camping automatically reloads your changes). You have two in three chances to get a different alternatives than our original hard-coded text:<br/><br/><br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-test5.png' width="575px" ></p>
<p>Let's look at the content of our <b>camping-abingo-test.db</b> SQLite database (preferably with <a href='#lita'>Lita</a>, an AIR-based SQLite administration tool):</p>
<p>					<img src='./wp-content/media/camping-abingo/camping-abingo-test6.png' width="575px" ><br />
					Note that the number of participants for the displayed alternative is 1.
					</p>
<p>If you are using FireBug with FireCookie, delete the <b>campingabingotest.state</b> and refresh the page. You should notice that the <b>abingo_identity</b> should change as well as the button text. Repeat the process several times. And occasionally click on the button to cause a conversion to occur.<br/><br />
					Let's refresh our table contents in Lita:<br/><br/><br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-test7.png'  width="575px" ><br />	<br />
					Note that the number of participants and conversions have increased across alternatives.
					</p>
<h3>Viewing A/B Test Results With The ABingo Dashboard</h3>
<p>Checking the database for our results is quite tedious (even with Lita!), luckily ABingo has a built-in <b>Dashboard</b>. Our Camping ABingo plugin has already defined a couple controllers and routes. We just need to expose the main <b>/abingo/dashboard</b> route.</p>
<p>So let's go to the <b>layout</b> method of our ABingo Test app. Right below the link for <b>Sign-Out</b> let's add a code fragment to only show a link to <b></b> if the id of the current signed-in user is the id of the allowed ABingo Administrator (using the <b>abingo_administrator_user_id</b> ABingo helper method). See lines 7-10:</p>
<pre class="brush: ruby">
def layout
	html do
		# ...

						a "Sign-Out",	:href=>'/signout'

						if @state.user_id == abingo_administrator_user_id
							span " | "
							a "ABingo Dashboard", :href=>"/abingo/dashboard"
						end

		# ...
	end
end
</pre>
<p>Now let's sign-in as the default administrator for our app. Use <b>admin</b> for the id and <b>camping</b> as the password. You should now see a <b>"ABingo Dashboard"</b> link in the top right of the navigation bar. Click on it. The dashboard should now show you the results:</p>
<p>					<img src='./wp-content/media/camping-abingo/camping-abingo-dashboard-2.png'   >	</p>
<p>Now it is easy to see the results and even terminate a given alternative if we want to.<br/><br />
					Note: each experiment you have defined will be listed with its corresponding details. </p>
<h5>Choosing Your Caching Mechanism</h5>
<p>By default the ABingo Plugin initialize its cache based on a <b>:memory_store</b>. This is fine and easy to troubleshoot our simple test app. But for your application you should consider a more advanced caching mechanisms - see the <a href="http://api.rubyonrails.org/classes/ActiveSupport/Cache.html">ActiveSupport Cache</a> documentation. One suggestion is to use Memcached if possible (e.g. on Heroku).</p>
<h3>So What? </h3>
<ol>
<li>Patrick McKenzie's <a href='#abpmk'>ABingo</a> is a powerful A/B testing framework for Ruby apps.</li>
<li><a href='#abpmk'>ABingo</a> makes it easy to define and execute experiments with multiple alternatives.</li>
<li>The ABingo Dashboard makes interpreting test results a breeze!</li>
</ol>
<p>So hopefully this second post on ABingo (see <a href="http://blog.monnet-usa.com/?p=322">here for the first post</a> of the serie) will have given you a feel for how easy it is to <b>A/B test-enable</b> a Ruby <a href='#rc'>Camping</a>-based web application using the <a href='#tacaab'>Camping ABingo plugin</a>.</p>
<p>					Happy ABingo A/B experiments!!!<br/><br/></p>
<p>					<i>Note: You can try the demo app yourself at: <a href='http://camping-abingo.heroku.com/'>camping-abingo.heroku.com</a> (including the ABingo Dashboard if you sign in as admin / camping).</i><br/><br/><br />
					In a subsequent post I will cover some advanced topics (caching, troubleshooting, multi-variates, etc.) for Camping ABingo. Stay tuned!</p>
<div  style="page-break-before:always;"></div>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>A/B Testing</h5>
<ul>
<li><a name='abwp' href='http://en.wikipedia.org/wiki/A/B_Testing'>A/B Testing Definition on Wikipedia</a></li>
<li><a name='abbasics' href='http://elem.com/~btilly/effective-ab-testing/'>Effective A/B Testing Basics (by Ben Tilly)</a></li>
<li><a name='abgg' href='https://www.google.com/analytics/siteopt/siteopt/help/overvw.html'>Google Website Optmizer</a></li>
<li><a name='abpmk' href='http://www.bingocardcreator.com/abingo'>ABingo A/B Testing Framework (by Patrick McKenzie)</a></li>
<li><a name='pmk' href='http://www.kalzumeus.com/'>Patrick McKenzie's Blog</a></li>
<li><a name='abpmktz' href='http://techzinglive.com/page/479/79-tz-interview-%e2%80%93-patrick-mckenzie-optimize-this'>Patrick McKenzie Interview On TechZing Podcast</a></li>
</ul>
<h5>Camping</h5>
<ul>
<li><a name='rc' href='http://github.com/camping/camping'>Ruby Camping Framework</a></li>
<li><a name='tacaab' href='http://github.com/techarch/camping-abingo'>Camping-ABingo repository on GitHub</a></li>
<li><a name='tacaabdo' href='http://camping-abingo.heroku.com/'>Camping-ABingo Demo On Heroku</a></li>
</ul>
<h5>Miscellaneous</h5>
<ul>
<li><a name='tz' 	href='http://techzinglive.com'>TechZing Podcast for web startup entrepreneurs</a></li>
<li><a name='lita' href='http://www.dehats.com/drupal/?q=node/58'>Lita, a SQLite administration tool</a></li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a href='http://blog.monnet-usa.com/?p=322'>A/B Test Your Ruby Camping Web App Using ABingo (Part 1)</a></li>
<li><a href='http://blog.monnet-usa.com/?p=223'>Visualize Application Metrics on NewRelic for your Ruby Camping Application</a></li>
</ul>
<p>					<a name='abcasrc'></a></p>
<h5>Source Code</h5>
<div   class='download_panel'>All source is available on GitHub:</p>
<ul>
						<a href='http://bit.ly/camping-abingo'>Camping ABingo <b>Plugin</b> library</a><br />
						<a href='http://bit.ly/cgabtst'>Camping ABingo <b>Test</b> Example</a>
					</div>
<div class="blog-msm-ad">
<div class="blog-msm-ad1">
							If you enjoyed this post, I would love it if you could check out <a href="http://bit.ly/myskillsmap">mySkillsMap</a>, my skills management app.
						</div>
<div class="blog-msm-ad2">
								<a href="http://www.myskillsmap.com/signup?opt=trial&#038;origin=tabg"><br />
									<img src='./wp-content/media/msm/start-your-free-trial-now.png'  /><br />
								</a>
						</div>
</p></div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/R_H-HYQKvmg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=330</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=330</feedburner:origLink></item>
		<item>
		<title>A/B Test Your Ruby Camping Web App Using ABingo (Part 1)</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/sOD3LOGicHk/</link>
		<comments>http://blog.monnet-usa.com/?p=322#comments</comments>
		<pubDate>Thu, 02 Dec 2010 05:13:31 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[A/B Testing]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Camping]]></category>
		<category><![CDATA[a/b testing]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=322</guid>
		<description><![CDATA[
						h3 {	text-decoration: underline; }
						h4
						{
							font-size: 1.1em;
							margin:0 50px 0 15px;
						}
						h5 
						{
							margin:0 50px 0 50px;
						}
						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}
						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}
						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.details_table th
						{
						background-color:lightgray;
						}
						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.blog-msm-ad {
							background-color: #919191;
							border-top: 6px solid #E2E2E2;
							color: white;
							display: block;
							height: 40px;
							margin-left: 12px;
							margin-top: 20px;
							padding: 10px;
							width: 537px;							
						}
						.blog-msm-ad1 {
							float: left;
							width: 310px;
						}
						.blog-msm-ad2 {
							float: right;
							width: 225px;
						}
						.blog-msm-ad a {
							color: [...]]]></description>
			<content:encoded><![CDATA[<style>
						h3 {	text-decoration: underline; }</p>
<p>						h4
						{
							font-size: 1.1em;
							margin:0 50px 0 15px;
						}</p>
<p>						h5 
						{
							margin:0 50px 0 50px;
						}</p>
<p>						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}</p>
<p>						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}</p>
<p>						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.details_table th
						{
						background-color:lightgray;
						}</p>
<p>						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.blog-msm-ad {
							background-color: #919191;
							border-top: 6px solid #E2E2E2;
							color: white;
							display: block;
							height: 40px;
							margin-left: 12px;
							margin-top: 20px;
							padding: 10px;
							width: 537px;							
						}</p>
<p>						.blog-msm-ad1 {
							float: left;
							width: 310px;
						}</p>
<p>						.blog-msm-ad2 {
							float: right;
							width: 225px;
						}</p>
<p>						.blog-msm-ad a {
							color: #A0D1F1;
							font-weight: bold;
						}</p>
</style>
<h3>Intro </h3>
<p>Over the past few months, while listening to <a href='#tz'>TechZing</a>, a fantastic podcast for web startup entrepreneurs, the concept of <a href='#abwp'>A/B Testing</a> keeps coming up as key technique to track and <b>measure conversion</b> of site <b>visitors</b> into potential or true <b>customers</b>. Performing A/B testing implies:
					</p>
<ol>
<li>Selecting <b>content variations</b> or <b>use case variations</b> to test</li>
<li>Identifying a couple <b>alternatives</b> for each test (a.k.a. experiments)<br/><br/><br />
						<i>Example of an experiment on the wording of a call to action button:</i><br />
						<img src='./wp-content/media/camping-abingo/camping-abingo-abtests-call-to-action-button.png'  width="90%" />
						</li>
<li><b>Trigger</b> a test on a given page by <b>selecting an alternative</b> for a given user</li>
<li><b>Track</b> any resulting <b>conversion for a given user</b> on a targetted page</li>
<li>Measure the <b>participation</b> in our tests</li>
<li>Measure the <b>conversion</b> in our tests</li>
</ol>
<div  class='download_panel'>Click <a href='#abcasrc'>here</a> if you want to skip straight to the <a href='#abcasrc'>ABingo Camping Plugin source code</a></div>
<h3>A/B Test Solutions</h3>
<p>Google provides very basic A/B Testing capabilities as part of the Google Analytics <a href="#abgg">Website Optimizer</a>. The downsides of that approach are:</p>
<ul>
<li>The tests (experiments), their alternatives, and corresponding urls have to be defined on the Google site</li>
<li>The resulting &#8220;test tracking Javascript snippets&#8221; have to be copy/pasted inside your own site</li>
<li>All the data remains locked in Google&#8217;s databases (although you can export it)</li>
</ul>
<p>If your web application is built on Ruby on Rails, you are in luck, as <a href="#pmz">Patrick McKenzie</a> has created <a href="#abingo">ABingo</a>, an excellent A/B testing framework plugin. ABingo even includes a dashboard to view the test participations and conversions. </p>
<p>Since I am a big fan of the lightweight Ruby <a href='#rc'>Camping Micro-Framework</a>, what I needed was an <a href='#tacaab'>ABingo Camping plugin</a>. Since none existed I emailed Patrick McKenzie to get his blessing and started to <a href='#abcasrc'>adapt</a> his plugin!</p>
<h3 style="page-break-before:always;">Starting With The End In Mind</h3>
<h4>ABingo Test Application</h4>
<p>To illustrate the usage of ABingo, we&#8217;ll use a simple tester representing a fictitious <b>SAAS Application</b>. From the <b>home</b> page we&#8217;ll be able to access the <b>landing</b> and corresponding <b>sign-up</b> pages that we want to <b>experiment with</b>.<br />
							<img src='./wp-content/media/camping-abingo/camping-abingo-test-nav-flow.png'  width="80%" /><br/><br />
							We&#8217;ll also provide sign-in/sign-out options and a  link to the <b>ABingo dashboard</b> if the signed in user is the administrator.
					</p>
<h4>Objective: Increasing Our Sign-Ups</h4>
<p>To increase our sign-ups we will be experimenting first with different <b>calls to action</b> in our sign-up button.<br />
					Our experiment named <b>call_to_action</b> will randomly vary the text of the button. We track the selected option and track the conversion on our sign-up page. After running our experiment for a while we will be able to see on the dashboard which option generated the most conversion!</p>
<h4>The Conversion Funnel</h4>
<p>The <b>path</b> taken by a group of customers from the various options (A/B/C) of the <b>landing</b> page to our <b>sign-up </b> page is called a <b>conversion funnel</b>:<br />
					<img src='./wp-content/media/camping-abingo/camping-abingo-abtests-funnel.png'  width="90%" />
					</p>
<h3 style="page-break-before:always;">High-Level Implementation Synopsis</h3>
<p>Once ABingo is integrated in your application, tracking and measuring the conversion funnel will consist of 2 basic steps:</p>
<h4>Selecting an alternative for a given experiment</h4>
<p>In the <b>landing view</b> code we will invoke the ABingo <b>ab_test</b> API to choose an alternative for the <b>call_to_action</b> experiment based on an array of text options:</p>
<pre class="brush: ruby">
	def landing
		# ...

		signup_text = ab_test("call_to_action",
								[ 	"Sign-Up Now!",
									"Try It For Free Now!",
									"Start Your Free Trial Now!",
								])

		a :href=>"/signup" do
			div.signup_btn!  signup_text
		end

		# ...
	end
</pre>
<p>It&#8217;s that easy! And as a side note an experiment alternative can be a simple boolean, an array of arbitrary values, or even a hash of options.</p>
<p><br/></p>
<h4>Tracking the conversion for our experiment</h4>
<p>In the <b>SignUp</b> controller, before rendering the signup view we will invoke the <b>abingo!</b> API to indicate that a conversion just occurred on our <b>call_to_action</b> experiment:</p>
<pre class="brush: ruby">
	class SignUp < R '/signup'
		def get
			bingo! "call_to_action"

			render :signup
		end
	end
</pre>
<h4>Fun With Experiments!</h4>
<p>Now that you have seen how ridiculously simple it is to setup and track an experiment you'll want to try to run different types of experiments such as for example:</p>
<ul>
<li>different styles (size, color) for the sign-up button</li>
<li>special offers</li>
<li>different ways to present pricing options</li>
<li>etc.</li>
</ul>
<p>Example of a landing page with a <b>special_promo</b> experiment:<br/><br />
						<img src='./wp-content/media/camping-abingo/camping-abingo-abtests-multiple-content-areas.png'  width="70%" />
					</p>
<h3>Reviewing A/B Test Results With The ABingo Dashboard</h4>
<p>The dashboard consists of a couple routes built using Camping controllers and views. Although we will walk through the setup of such a dashboard in our prototype app in a later article, here is a teaser screenshot:</p>
<p>					<img src='./wp-content/media/camping-abingo/camping-abingo-dashboard.png' /><br/><br />
					<br/></p>
<p>The conclusions we can draw from these experiments are:</p>
<ol>
<li>For the <b>special_promo</b> experiment, the "true" alternative results in the most conversions (%)</li>
<li>For the <b>call_to_action</b> experiment, the "Start Your Free Trial Now!" alternative results in the most conversions (%)</li>
</ol>
<p>You can try the demo app yourself at: <a href="http://camping-abingo.heroku.com/">http://camping-abingo.heroku.com/</a>.</p>
<h3  style="page-break-before:always;">So What? </h3>
<ol>
<li>A/B testing is a key practice to improve usability as well as user conversion on a web application.</li>
<li>Patrick McKenzie's <a href='#abpmk'>ABingo</a> is a powerful A/B testing framework for Ruby apps.</li>
<li><a href='#abpmk'>ABingo</a> makes it easy to define and execute experiments with multiple alternatives.</li>
</ol>
<p>This introduction to ABingo should have given you a feel for how easy it is to add A/B testing capabilities to a Ruby <a href='#rc'>Camping</a> web application using the <a href='#tacaab'>ABingo Camping plugin</a>. <br />
					In a subsequent post I will cover the specific implementation steps to add ABingo to our test application. Stay tuned!
					</p>
<p>					<a name='abcasrc'></a></p>
<h5>Source Code</h5>
<div   class='download_panel'>All source is available on GitHub:</p>
<ul>
						<a href='http://bit.ly/camping-abingo'>Camping ABingo <b>Plugin</b> library</a><br />
						<a href='http://bit.ly/cgabtst'>Camping ABingo <b>Test</b> Example</a>
					</div>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>A/B Testing</h5>
<ul>
<li><a name='abwp' href='http://en.wikipedia.org/wiki/A/B_Testing'>A/B Testing Definition on Wikipedia</a></li>
<li><a name='abbasics' href='http://elem.com/~btilly/effective-ab-testing/'>Effective A/B Testing Basics (by Ben Tilly)</a></li>
<li><a name='abgg' href='https://www.google.com/analytics/siteopt/siteopt/help/overvw.html'>Google Website Optmizer</a></li>
<li><a name='abpmk' href='http://www.bingocardcreator.com/abingo'>ABingo A/B Testing Framework (by Patrick McKenzie)</a></li>
<li><a name='pmk' href='http://www.kalzumeus.com/'>Patrick McKenzie's Blog</a></li>
<li><a name='abpmktz' href='http://techzinglive.com/page/479/79-tz-interview-%e2%80%93-patrick-mckenzie-optimize-this'>Patrick McKenzie Interview On TechZing Podcast</a></li>
</ul>
<h5>Camping</h5>
<ul>
<li><a name='rc' href='http://github.com/camping/camping'>Ruby Camping Framework</a></li>
<li><a name='tacaab' href='http://github.com/techarch/camping-abingo'>Camping-ABingo repository on GitHub</a></li>
</ul>
<h5>Miscellaneous</h5>
<ul>
<li><a name='tz' 	href='http://techzinglive.com'>TechZing Podcast for web startup entrepreneurs</a></li>
<li><a name='lita' 	href='http://www.dehats.com/drupal/?q=node/58'>Lita, a SQLite administration tool</a></li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a href='http://blog.monnet-usa.com/?p=223'>Visualize Application Metrics on NewRelic for your Ruby Camping Application</a></li>
</ul>
<div class="blog-msm-ad">
<div class="blog-msm-ad1">
							If you enjoyed this post, I would love it if you could check out <a href="http://bit.ly/myskillsmap">mySkillsMap</a>, my skills management app.
						</div>
<div class="blog-msm-ad2">
								<a href="http://www.myskillsmap.com/signup?opt=trial&#038;origin=tabg"><br />
									<img src='./wp-content/media/msm/start-your-free-trial-now.png'  /><br />
								</a>
						</div>
</p></div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/sOD3LOGicHk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=322</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=322</feedburner:origLink></item>
		<item>
		<title>Implementing Ruby Camping REST Services With RESTstop</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/GC7jYbOFrX0/</link>
		<comments>http://blog.monnet-usa.com/?p=298#comments</comments>
		<pubDate>Wed, 23 Jun 2010 04:50:47 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[REST]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Camping]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[camping]]></category>
		<category><![CDATA[reststop]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=298</guid>
		<description><![CDATA[Intro 
It is pretty common nowadays for web applications and sites to expose a developer API to allow consumers to integrate their data with other application. Examples: Twitter, LinkedIn, Bit.ly, etc. 
Although there are various options for implementing web services, as of 2010, the REST protocol seems to have achieved a comfortable lead over other [...]]]></description>
			<content:encoded><![CDATA[<h3>Intro </h3>
<p>It is pretty common nowadays for web applications and sites to expose a developer API to allow consumers to integrate their data with other application. Examples: Twitter, LinkedIn, Bit.ly, etc. </p>
<p>Although there are various options for implementing web services, as of 2010, the <a href='#rest'>REST</a> protocol seems to have achieved a <b>comfortable lead</b> over other approaches for <b>Internet</b>-based <b>resource-oriented</b> services.</p>
<p><a href='#rs'>RESTstop</a> is a Ruby library making it easy to implement <a href='#rest'>REST</a> services<br />
					on top of the <a href='#rc'>Camping framework</a>.</p>
<p>					<img src='./wp-content/media/camping-reststop/reststop.png' style='margin-left:60px;'></p>
<h3>Web Services Implementation Options</h3>
<p>Before jumping to <a href='#rs'>RESTstop</a> (if you insist click <a href='#reststop-plugin'>here</a>), let&#8217;s do a brief review of the few options,<br />
					developers have historically leveraged to build web services:</p>
<ol>
<li><a href='#soap-svcs'>SOAP services</a>:  the API is <b>formally defined</b> using the WSDL format. API messages use a specific XML representation.<br />
						Additional services can be composed on top of the basic protocol to provide authentication, authorization, etc.<br />
						Although powerful, SOAP has proven <b>too complex</b> and <b>too heavy</b> for web developer APIs .<br />
						Also they require a full <b>SOAP-compatible client stack</b> for making them more difficult to call especially in the case of AJAX applications.<br />
						As a consequence, SOAP services tend to have been relegated to <b>intra-enterprise cross-application services</b>. </li>
<p></p>
<li><a href='#xml-svcs'>XML services</a>: the API is <b>not formally defined</b> but end-points and their inputs and outputs are usually documented on a developer site.<br />
						Each service has a given url and uses XML to represent messages. As such an <b>XML parser</b> is required to provide robust processing<br />
						especially if the data structures are complex and rely on namespaces.</li>
<p></p>
<li><a href='#json-svcs'>JSON services</a>: similarly to the XML services the API is also <b>not formally defined</b>.<br />
						Messages are represented as <a href='#json'>JSON</a> structures.<br />
						<a href='#json'>JSON</a> services lend themselves very well to <b>AJAX</b> calls from browser applications since<br />
						<a href='#json'>JSON</a> structures can be easily processed using basic Javascript.</li>
<p></p>
<li>APIs for web sites mostly need to expose &#8220;<a href='#resource'>resources</a>&#8221; as opposed to behaviors (e.g. : CRUD operations on Posts) </li>
</ol>
<h3>Camping for Web Services</h3>
<p>Since <a href='#rc'>Camping</a> is a generic Ruby web application framework, you can define service <a href='#routes'>endpoints as url routes</a>,<br />
					each mapped to a given <b>controller</b>.<br />
					An HTML-based view is not necessary obviously, so instead one option is to render the model<br />
					using the desired format: <b>XML</b> or <a href='#json'>JSON</a>.<br />
					Example:
					</p>
<pre class="brush: ruby">
gem 'camping' , '>= 2.0'
%w(rubygems active_support active_support/json active_record camping camping/session markaby erb ).each { | lib | require lib }

Camping.goes :CampingJsonServices

module CampingJsonServices
	include Camping::Session

	def CampingJsonServices.create
	end

	module CampingJsonServices::Controllers

		class APIDateToday < R '/datetoday'
			def get
				@result = {:today=>Date.today.to_s}

				@headers['Content-Type'] = "application/json"
				@result.to_xml(:root=>'response')
			end
		end

		class APITimeNow < R '/timenow'
			def get
				@result = {:now=>Time.now.utc.to_s}

				@headers['Content-Type'] = "application/json"
				@result.to_json
			end
		end

	end
end
</pre>
<p>Such as an approach is fine for <i>function-oriented APIs</i> but if we want to provide CRUD access to <a href='#resource'>resources</a>,<br />
					then a <a href='#rest'>REST</a> approach provides more structure. You can of course implement a <a href='#rest'>REST</a>-style API on your own<br />
					by overriding the route dispatch mechanism and mapping the HTTP verbs such as PUT and DELETE<br />
					to the appropriate route controller methods.
					</p>
<p>					<a name='reststop-plugin'></a>	</p>
<h3>RESTstop, a REST plugin for Camping</h3>
<p><a href='#mz'>Matt Zukowski</a> wrote the <a href='#rs'>RESTstop</a> library to easily provide access to <a href='#resource'>REST resources</a> using the underlying Camping route engine and controllers.<br />
					The idea was powerful yet simple, as a developer you would create a controller per <a href='#resource'>resource</a><br />
					and specify the <a href='#rest'>REST</a> nature of the route like so:</p>
<pre class="brush: ruby">
module Blog::Controllers
  extend Reststop::Controllers

	class Posts < REST 'posts'
	end
end
</pre>
<p>Then similarly to the standard <b>get</b> and <b>post</b> methods of Camping controllers, you would create <b>CRUD-style</b> action methods<br />
					such as: <b>create</b>, <b>read</b>, <b>update</b>, <b>delete</b>, and <b>list</b>:</p>
<pre class="brush: ruby">
class Posts < REST 'posts'
      # POST /posts
      def create
      end

      # GET /posts/1
      # GET /posts/1.xml
      def read(post_id)
      end

      # PUT /posts/1
      def update(post_id)
      end

      # DELETE /posts/1
      def delete(post_id)
      end

      # GET /posts
      # GET /posts.xml
      def list
	end
end
</pre>
<p>Then once you had a controller, you would implement a <b>special type of view</b> appropriate for the format of the data you wanted to expose.<br />
					For example you could create views to render the data as XML or <a href='#json'>JSON</a> or any other format you liked.</p>
<pre class="brush: ruby">
module Blog::Views
  extend Reststop::Views

  module HTML
    include Blog::Controllers
    include Blog::Views

    def index
      if @posts.empty?
        p 'No posts found.'
      else
        for post in @posts
          _post(post)
        end
      end
      p { a 'Add', :href => R(Posts, 'new') }
    end

  end

  module XML
    include Blog::Controllers
    include Blog::Views

    def index
      @posts.to_xml(:root => 'blog')
    end

  end

  module JSON
    include Blog::Controllers
    include Blog::Views

    def index
      @posts.to_json
    end
  end
</pre>
<h3>The Inner Plumbing Of RESTstop</h3>
<p><a href='#rs'>RESTstop</a> is an interesting plugin to dissect as it is a good illustration of <a href='#metaprog'>meta-programming</a> in Ruby.<br />
					<a href='#mz'>Matt</a> took the following approach:</p>
<ol>
<li>Alias and override the base <b>service</b> method to save off the HTTP verb</li>
<li>Add a new route creation method called <b>REST</b> to replace the base <b>r</b> route creation method.<br />
							The new method will register all the expected REST resource routes and wire them up to the controller.</li>
<li>Default or decode the rendering format specified in the url (e.g. /posts.xml vs. /posts.json)</li>
<li>Structure the Views module according to the various formats to specify: HTML vs. XML vs. JSON</li>
<li>Render the controller output using the specified format</li>
</ol>
<p>I would definitely recommend that your read the plugin's source. At 449 lines with many comments<br />
					it is pretty easy to see how it actually works. This will also make it easier for you to troubleshoot your code when needed.</p>
<h3>Let's Create The REST Version Of The Blog Sample</h3>
<p>Here is an outline of the approach:</p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
<th>Area (Module)</th>
</tr>
<tr>
<td><a href='#todo1'>1</a></td>
<td>Plug in RESTstop into the app</td>
<td>Main app</td>
</tr>
<tr>
<td><a href='#todo2'>2</a></td>
<td>Plug in RESTstop into the Base</td>
<td>Base</td>
</tr>
<tr>
<td><a href='#todo3'>3</a></td>
<td>Plug in RESTstop into the Controllers</td>
<td>Controllers</td>
</tr>
<tr>
<td><a href='#todo4'>4</a></td>
<td>Create the REST <b>Sessions</b> controller</td>
<td>Controllers</td>
</tr>
<tr>
<td><a href='#todo5'>5</a></td>
<td>Plug in RESTstop into the Helpers</td>
<td>Helpers</td>
</tr>
<tr>
<td><a href='#todo6'>6</a></td>
<td>Plug in RESTstop into the Views</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo7'>7</a></td>
<td>Finish the REST <b>Sessions</b> controller</td>
<td>Controllers</td>
</tr>
<tr>
<td><a href='#todo8'>8</a></td>
<td>Add <b>JSON</b> support</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo9'>9</a></td>
<td>Create the REST <b>Posts</b> controller</td>
<td>Controllers</td>
</tr>
<tr>
<td><a href='#todo10'>10</a></td>
<td>Add an HTML view module for Posts</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo11'>11</a></td>
<td>Add an XML view module for Posts</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo12'>12</a></td>
<td>Add a JSON view module for Posts</td>
<td>Views</td>
</tr>
</table>
<p></p>
<p>					<a name='todo1'></a></p>
<h5>1. Plug In RESTstop</h5>
<p>Our first step is to install the gem and add a require for RESTstop:</p>
<pre class="brush: ruby">
gem install reststop
</pre>
<p>Now let's create a new Ruby source file and name it <b>camping-svcs.rb</b>.<br />
					Then let's require RESTstop and include its main module in the blog's main module.</p>
<pre class="brush: ruby">
require 'reststop'

Camping.goes :Blog

module Blog
  include Camping::Session
  include Reststop
end
</pre>
<p>					<a name='todo2'></a></p>
<h5>2.Plug in RESTstop into the Base</h5>
<p>Now we need to enhance the Base module, so let's specify it.<br />
					This is the place where we'll add most of the extensions code taking care of:</p>
<ul>
<li>Aliasing 3 methods: render, lookup, and service so RESTstop can "insert" its magic</li>
<li>Including Reststop::Base in the Base</li>
<li>Adapt the Camping lookup method to look for view methods inside the RESTstop-specific Views::HTML module</li>
</ul>
<p>So add the following code:</p>
<pre class="brush: ruby">
module Blog::Base
  alias camping_render render
  alias camping_lookup lookup	# @techarch: required if camping > 2.0
  alias camping_service service
  include Reststop::Base
  alias service reststop_service
  alias render reststop_render

	# Overrides the new Tilt-centric lookup method In camping
	# RESTstop needs to have a first try at looking up the view
	# located in the Views::HTML module.
    def lookup(n)
      T.fetch(n.to_sym) do |k|
        t = Blog::Views::HTML.method_defined?(k) || camping_lookup(n)
      end
    end
end
</pre>
<p>					<a name='todo3'></a></p>
<h5>3. Plug in RESTstop into the Controllers</h5>
<p>Here we'll add an extend for the Reststop::Controllers.</p>
<pre class="brush: ruby">
module Blog::Controllers
  extend Reststop::Controllers
end
</pre>
<p>This will add 2 new methods</p>
<ul>
<li><b>determine_format</b> : will extract the service data format from the request url - e.g json from /posts.json</li>
<li><b>REST</b> : will allow definition of REST resources in our controller declarations - e.g. class Posts < REST 'posts'</li>
</ul>
<p>					<a name='todo4'></a></p>
<h5>4. Create the REST Sessions controller</h5>
<p>The <a href='#rcb'>Camping Blog example</a> has a simple <b>login system</b> built on top of the Camping session.<br />
					For our REST blog, we'll want to support both an interactive web app login (like in the original blog)<br />
					as well as a service-based login so that only authenticated applications can call our services.</p>
<p>So we'll expose a new REST resource called <b>Session</b>. Applications will be able to <b>create</b> and <b>delete</b> sessions -<br />
					to mirror the login and logout behavior. So let's create our first REST controller and name it <b>Sessions</b>:</p>
<pre class="brush: ruby">
    class Sessions < REST 'sessions'
	end
</pre>
<p>Now we just need to declare only a subset of the standard <b>CRUD</b> REST methods: <b>create</b>, and <b>delete</b>.<br />
					For now, let's just create the shell:</p>
<pre class="brush: ruby">
        # POST /sessions
        def create
        end   

        # DELETE /sessions
        def delete
        end
</pre>
<p>For the <b>create</b> method, we will lookup the user based on the user id and password.<br />
					If not found we'll return a 401 (unauthorized) error with a message.<br />
					If found, we'll create a Camping session and render a view we'll create in a bit called <b><a href='#todo6b'>user</a></b>.<br />
					Here is the code:</p>
<pre class="brush: ruby">
        # POST /sessions
        def create
          @user = User.find_by_username_and_password(input.username, input.password)

          if @user
            @state.user_id = @user.id
            render :user
          else
			r(401, 'Wrong username or password.')
          end
        end
</pre>
<p>Let's test the error scenario. For that we'll use the following 2 tools:</p>
<ol>
<li>The <a href='#restr'>restr</a> gem. This is another nice library created by <a href='#mz'>Matt</a>.
<pre class="brush: ruby">gem install restr</pre>
<p>							We'll use the library from IRB as a simple REST client.</p>
</li>
<li>Pocket Soap's <a href='#tcpt'>TcpTrace</a>, a tool to inspect the contents of Tcp messages.<br />
						This will really help us troubleshoot the various interactions between client and service.</li>
</ol>
<p>Ok so let's start our camping app on the default 3301 port:</p>
<pre class="brush: ruby">
camping camping-svcs.rb
</pre>
<p>Now let's run <a href='#tcpt'>TcpTrace</a> and start a new trace listening on port 8080 and forwarding to port 3301. <br />
					<i>Note: we'll set our IRB-based client to post to port 8080).</i><br />
					<img src='./wp-content/media/camping-reststop/tcptrace-start.png'></p>
<p>Then start IRB and run the following statements to invoke <b>create</b> on the <b>Sessions</b> resource:</p>
<pre class="brush: ruby">
gem 'xml-simple'
gem 'restr'
require 'restr'

# Set the url of our resource (via port 8080 for TcpTrace)
u0 =  "http://localhost:8080/sessions.xml"

# Set the user name and incorrect password
o = { :username=>'admin', :password=>'wrong'}

# Post to the Sessions resource
p0 = Restr.post(u0,o)
</pre>
<p>In <a href='#tcpt'>TcpTrace</a> you should see the request and the response:<br />
				<img src='./wp-content/media/camping-reststop/tcptrace-session-create-error.png'>
				</p>
<p>In IRB you should also see the 401 error:<br />
				<img src='./wp-content/media/camping-reststop/restr-session-create-error.png' width='570px'>
				</p>
<p>So now we have successfully tested the error scenario!<br />
					Let's go back to our code and continue setting up our RESTstop code so we can then define our <b><a href='#todo6b'>user</a></b> view.</p>
<p>					<a name='todo5'></a></p>
<h5>5. Plug in RESTstop into the Helpers</h5>
<p>We'll explicitly define our Helpers module so we can:</p>
<ol>
<li>alias the R method since RESTstop will need to intercept it to provide a way to create routes to resources (e.g. R(Posts/1)</li>
<li>include the Reststop::Helpers module</li>
</ol>
<pre class="brush: ruby">
module CampingRestServices::Helpers
  alias_method :_R, :R
  remove_method :R
  include Reststop::Helpers
end
</pre>
<p>					<a name='todo6'></a></p>
<h5>6. Plug in RESTstop into the Views</h5>
<p>In the Views module, we'll first add an extend for the RESTstop Views module</p>
<pre class="brush: ruby">
module CampingRestServices::Views
  extend Reststop::Views
end
</pre>
<p>Then we'll create 3 sub-modules, one for each type of format we'll support: HTML, XML, and JSON.<br />
					We'll also indicate that HTML is the default format.<br />
					For the moment we'll just create shells:</p>
<pre class="brush: ruby">
module CampingRestServices::Views
  extend Reststop::Views

  module HTML
  end

  module XML
  end

  module JSON
  end

  default_format :HTML
end
</pre>
<p>					<a name='todo6b'></a></p>
<p>Since we needed to create a <b>user</b> view when successfully creating a Session resource,<br />
					let's create a user view method in the XML submodule. The code will just serialize the @user object to XML.</p>
<pre class="brush: ruby">
  module XML

	def user
		@user.to_xml(:root => 'user')
	end

  end
</pre>
<p>We're now ready to test the happy path!<br />
						So go back to your IRB session and evaluate the following statements:</p>
<pre class="brush: ruby">
# Set the user name and correct password
o = { :username=>'admin', :password=>'camping'}

# Post to the Sessions resource
p0 = Restr.post(u0,o)
</pre>
<p>In <a href='#tcpt'>TcpTrace</a> you should see the request and the response containing the serialized user:<br />
				<img src='./wp-content/media/camping-reststop/tcptrace-session-create.png'>
				</p>
<p>In IRB you should also see the returned user instance, deserialized from XML<br />
				<img src='./wp-content/media/camping-reststop/restr-session-create.png' width='570px'>
				</p>
<p>					<a name='todo7'></a></p>
<h5>7. Finish the REST <b>Sessions</b> controller</h5>
<p>The remaining part of our Sessions controller is the <b>delete</b> method.<br />
					Delete will terminate the session and return a 200 message to that effect:</p>
<pre class="brush: ruby">
    class Sessions < REST 'sessions'
        # ...   

        # DELETE /sessions
        def delete
          @state.user_id = nil
          r(200, 'Session terminated')
        end
    end
</pre>
<p>Let's test this out from IRB by evaluating the following statement to DELETE the current session:</p>
<pre class="brush: ruby">
p0=Restr.delete(u0,{})
</pre>
<p>In <a href='#tcpt'>TcpTrace</a> you should see the request and the response containing the session termination message:<br />
				<img src='./wp-content/media/camping-reststop/tcptrace-session-delete.png'>
				</p>
<p>In IRB you should also see the same message:<br />
				<img src='./wp-content/media/camping-reststop/restr-session-delete.png' width='570px'></p>
<p>				So here is a recap for what we have accomplished so far:</p>
<ol>
<li>We have plugged in RESTstop in the following modules:
<ul>
<li><a href='#todo1'>Main app</a></li>
<li><a href='#todo2'>Base</a></li>
<li><a href='#todo3'>Controllers</a></li>
<li><a href='#todo5'>Helpers</a></li>
<li><a href='#todo6'>Views</a></li>
</ul>
</li>
<li>We have created our first REST controller: <a href='#todo4'>Sessions</a> implementing the <a href='#todo4'>create</a> and <a href='#todo7'>delete</a> methods</li>
<li>We have created an XML submodule in our Views module to render the <a href='#todo6b'>user</a> XML view</li>
<li>We have monitored the message protocol using <a href='#tcpt'>TcpTrace</a></li>
<li>We tested the API using the <a href='#restr'>restr</a> client library</li>
</ol>
<p>					<a name='todo8'></a></p>
<h5>8. Add JSON Support</h5>
<p>Our Session resource can currently only be accessed via an XML REST interface.<br />
					So let's add <a href='#json'>JSON</a> support by adding a <b>user</b> view to the JSON submodule (within our Views module):</p>
<pre class="brush: ruby">
  module JSON

	def user
		@user.to_json
	end

  end
</pre>
<p>Let's go back to your IRB session and evaluate the following statements:</p>
<pre class="brush: ruby">
# Set the url for the JSON Resource format
u0b =  "http://localhost:8080/sessions.json"

# Post to the Sessions resource
p0=Restr.post(u0b,o)
</pre>
<p>In <a href='#tcpt'>TcpTrace</a> you should see the request and the response containing the serialized user in JSON format:<br />
				<img src='./wp-content/media/camping-reststop/tcptrace-session-create-json.png'>
				</p>
<p>In IRB you should also see the returned user instance, deserialized from JSON:<br />
				<img src='./wp-content/media/camping-reststop/restr-session-create-json.png' width='570px'>
				</p>
<p>At this stage, our service can provide authentication via the <b><a href='#todo4'>Sessions</a></b> resource using either an XML or JSON protocol.<br />
				I will leave the HTML implementation for the reader. The approach would include re-using the existing Login controller,<br />
				but the login view would be moved to the HTML submodule and could be modified to POST to the Sessions resource.</p>
<p>So we now have the basic building authentication block for the rest of the functionality for our service.<br />
				Although this would work fine, this approach is not very robust for industrial-strength services.<br />
				I would recommend using <b><a href='#caoauth'>OAuth</a></b> as it provides more features such as:</p>
<ul>
<li>per-user consumer app registration</li>
<li>token-based authorization</li>
<li>explicit user-based authorization of tokens</li>
</ul>
<p>I recently created an <b><a href='#caoauth'>OAuth plugin for Camping</a></b> so check out the details on this post <u><a href='#caoauth'>here</a></u>.</p>
<p>					<a name='todo9'></a></p>
<h5>9. Create the REST Posts controller</h5>
<p>We will model the <b>Posts</b> REST controller after the <b><a href='#todo4'>Sessions</a></b> controller, with a few new twists such as the<br />
					<b>read</b>, <b>update</b> and <b>list</b> methods.</p>
<p>Currently, in the <a href='#rcb'>Camping Blog example</a>, there are several controllers responsible for managing posts: Index, PostNew, PostN, and Edit.<br />
					We will combine them into a brand new REST controller called <b>Posts</b>. So let's define a <b>Posts controller</b> with a REST route of <u><b>'posts'</b></u>:</p>
<pre class="brush: ruby">
class Posts < R 'posts'
end
</pre>
<p>Now we just need to declare the standard <b>CRUD</b> REST methods: <b>create</b>, <b>read</b>, <b>update</b>, <b>delete</b>, and <b>list</b>.<br />
					For now, let's just create the shell:</p>
<pre class="brush: ruby">
class Posts < R 'posts'
      # POST /posts
      def create
      end

      # GET /posts/1 or
      # GET /posts/1.xml or
      # GET /posts/1.json
      def read(post_id)
      end

      # PUT /posts/1
      def update(post_id)
      end

      # DELETE /posts/1
      def delete(post_id)
      end

      # GET /posts or
      # GET /posts.xml or
      # GET /posts.json
      def list
      end
end
</pre>
<p>					<a name='todo-list-c'></a>					</p>
<p>Let's start with the simplest method: <b>list</b>.<br />
					We will just take the code from the old <b>Index</b> controller's <b>get</b> method<br />
					(and later we'll move the <b><a href='#todo-index-v'>index</a></b> view method into the <b>HTML</b> submodule).</p>
<pre class="brush: ruby">
      # GET /posts
      # GET /posts.xml
      def list
        @posts = Post.all(:order => 'updated_at DESC')
        render :index
      end
</pre>
<p>					<a name='todo-create-c'></a>					</p>
<p>Now for the <b>create</b> method, we will start with the code from the old <b>PostNew</b> controller's <b>post</b> method.<br />
					But we will tweak the Post.create parameters list to accept either <b>input.post_title</b> (when coming from an HTML form)<br />
					or <b>input.title</b> (when coming from a REST service call). We'll do the same for the <b>body</b> input parameter. <br />
					Then we will adjust the redirect call to use the RESTstop-enhanced <b>R</b> route creation method as opposed<br />
					to redirecting to the old <b>PostN</b> controller.<br />
					So all in all the code will now look like this:</p>
<pre class="brush: ruby">
      # POST /posts
      def create
          require_login!
          @post = Post.create :title => (input.post_title || input.title),
		  :body => (input.post_body || input.body),
          :user_id => @state.user_id

        redirect R(@post)
      end
</pre>
<p>					<a name='todo-read-c'></a>					</p>
<p>The <b>read</b> method is easy as it is a straight copy paste from the old <b>PostN</b> controller's <b>get</b> method<br />
					(and later we'll move the <b><a href='#todo-view-v'>view</a></b> view method into the <b>HTML</b> submodule).</p>
<pre class="brush: ruby">
      # GET /posts/1
      # GET /posts/1.xml
      def read(post_id)
        @post = Post.find(post_id)

        render :view
      end
</pre>
<p>					<a name='todo-update-c'></a>					</p>
<p>For the <b>update</b> method, we'll use the same technique as for the <b>create</b> method:<br />
					we'll start with the code from the old <b>Edit</b> controller's <b>post</b> method and allow for the<br />
					variations in the input parameters (depending on whether we come from an HTML post or a REST post).<br />
					We'll also adapt the redirect to use the new <b>R</b> method. So the code should look like this:</p>
<pre class="brush: ruby">
      # PUT /posts/1
      def update(post_id)
        require_login!
        @post = Post.find(post_id)
        @post.update_attributes :title => (input.post_title || input.title),
			:body => (input.post_body || input.body)								

		redirect R(@post)
      end
</pre>
<p>					<a name='todo-delete-c'></a>					</p>
<p>The original Camping blog does not have code to delete a post, but the code for our <b>delete</b> method<br />
					is pretty straightforward:</p>
<pre class="brush: ruby">
      # DELETE /posts/1
      def delete(post_id)
        require_login!
        @post = Post.find post_id

        if @post.destroy
          redirect R(Posts)
        else
          _error("Unable to delete post #{@post.id}", 500)
        end
      end
</pre>
<p>					<a name='todo-new-c'></a>					</p>
<p>We will need a route to create new blog entries via HTML, so let's add a <b>new</b> action method<br />
					to instantiate a new Post and render the <b><a href='#todo-add-v'>add</a></b> view method:</p>
<pre class="brush: ruby">
      # GET /posts/new
      def new
        require_login!
		@user = User.find @state.user_id
        @post = Post.new
        render :add
      end
</pre>
<p>					<a name='todo-edit-c'></a>					</p>
<p>Then finally we will need a route to edit an existing blog entry via HTML, so let's add an <b>edit</b> action method<br />
					to lookup an existing Post by id and render it using the <b><a href='#todo-edit-v'>edit</a></b> view method:</p>
<pre class="brush: ruby">
      # GET /posts/1/edit
      def edit(post_id)
        require_login!
 		@user = User.find @state.user_id
        @post = Post.find(post_id)
        render :edit
      end
</pre>
<p>					<a name='todo-utility-c'></a>					</p>
<p>To finish up the application, there a few more "utility" controllers we'll need such as:</p>
<ol>
<li>an Index controller for the "home"/"index" page</li>
<li>a Login controller</li>
<li>a Logout controller</li>
</ol>
<p>					<a name='todo-index-c'></a>					</p>
<p>So first let's copy but change the original Index controller so that it just redirects to the <u><b>/posts</b></u> route<br />
					since the logic is now in the <b>list</b> method of the new <b>Posts</b> REST controller.</p>
<pre class="brush: ruby">
    class Index
		def get
			redirect '/posts'
		end
	end
</pre>
<p>					<a name='todo-login-c'></a></p>
<p>Then, we need a <b>Login</b> controller to render the <b><a href='#todo-login-v'>login</a></b> HTML view:</p>
<pre class="brush: ruby">
	class Login < R '/login'
		def get
			render :login
		end
	end
</pre>
<p>					<a name='todo-logout-c'></a></p>
<p>And we also need a <b>Logout</b> controller to render the <b><a href='#todo-logout-v'>logout</a></b> HTML view:</p>
<pre class="brush: ruby">
	class Logout < R '/logout'
		def get
			render :logout
		end
	end
</pre>
<p>You can also migrate the original <b>Styles controller</b>, as well as the <b>CSS declarations</b> (located at the end of the original Camping blog source).</p>
<p>Before we start working on the views, let's define a couple login-related helper methods in our CampingRestServices::Helpers module:</p>
<ul>
<li>logged_in? : to test if we have a logged in user</li>
<li>require_login! : to force a redirect to the login page if we don't have a valid user session</li>
</ul>
<pre class="brush: ruby">
module CampingRestServices::Helpers
  # ...

  def logged_in?
    !!@state.user_id
  end

  def require_login!
    unless logged_in?
      redirect(R(CampingRestServices::Controllers::Login))
      throw :halt
    end
  end
end
</pre>
<p>We're now officially done with our Controllers module! :-)</p>
<p>					<a name='todo10'></a></p>
<h5>10. Add an HTML view module for Posts</h5>
<p>OK now that we have a functional Posts REST controller, we need to create the corresponding views<br />
					in the appropriate Views submodule (HTML vs. XML vs. JSON).</p>
<p>Let's start by migrating the old HTML views by copying the contents of the old Views module <u>into</u><br />
					the new <b>HTML</b> submodule</p>
<pre class="brush: ruby">
module CampingRestServices::Views
  extend Reststop::Views

  module HTML
	# PLACE THE OLD Views CODE HERE
  end

  # ...

  default_format :HTML
end
</pre>
<p>We will leave the <b>layout</b> view method unchanged.</p>
<p>Our first edit will be in the <b>index</b> method where we'll change the code to<br />
					create a route for the "<u><b>add one</b></u>" link to route to the '"<b>new</b>" action of our new <b>Posts</b> REST resource<br />
					as opposed to routing to the old <b>PostNew</b> controller.</p>
<p>					<a name='todo-index-v'></a>					</p>
<pre class="brush: ruby">
    def index
      if @posts.empty?
        h2 'No posts'
        p do
          text 'Could not find any posts. Feel free to '
          a 'add one', :href => R(Posts, 'new')
          text ' yourself. '
        end
      else
        @posts.each do |post|
          _post(post)
        end
      end
    end
</pre>
<p>					<a name='todo-login-v'></a>					</p>
<p>The next view method to change is <b>login</b>. In the original Camping version the form will post to the Login controller.<br />
					We now need it to post to the new <b>Sessions</b> REST resource. So let's adapt the code as follows:</p>
<pre class="brush: ruby">
    def login
      h2 'Login'
      p.info @info if @info

      form :action => R(Sessions), :method => 'post' do
        input :name => 'to', :type => 'hidden', :value => @to if @to

        label 'Username', :for => 'username'
        input :name => 'username', :id => 'username', :type => 'text'

        label 'Password', :for => 'password'
        input :name => 'password', :id => 'password', :type => 'password'

        input :type => 'submit', :class => 'submit', :value => 'Login'
      end
    end
</pre>
<p>Once the user has logged in we need to render the <b>user</b> HTML view<br />
					(if you remember we created an XML and JSON version but not an HTML one).<br />
					So let's add a quick view to greet the user and provide a link to the Posts page:</p>
<pre class="brush: ruby">
    def user
      h2 "Welcome #{@user.username}!"
      a 'View Posts', :href => '/posts'
    end
</pre>
<p>					<a name='todo-logout-v'></a>					</p>
<p>And we need to create a <b>logout</b> view too, with a form which once submitted<br />
					would invoke the <b>DELETE</b> HTTP verb on the <b>Sessions</b> REST controller:</p>
<pre class="brush: ruby">
    def logout
      h2 'Logout'

      form :action => R(Sessions), :method => 'delete' do
        input :type => 'submit',
				:class => 'submit',
				:value => 'Logout'
      end
    end
</pre>
<p>					<a name='todo-add-v'></a>					</p>
<p>For the <b>add</b> view, we'll only adjust the posting route<br />
					from the old <b>PostNew</b> controller to the new <b>Posts</b> REST controller:</p>
<pre class="brush: ruby">
    def add
      _form(@post, :action => R(Posts))
    end
</pre>
<p>					<a name='todo-edit-v'></a>					</p>
<p>For the <b>edit</b> view, we'll also adjust the posting route<br />
					from the old <b>Edit</b> controller to an item-specific action (using the post id) on the<br />
					new <b>Posts</b> REST controller using the <b>PUT</b> HTTP verb:</p>
<pre class="brush: ruby">
    def edit
      _form(@post, :action => R(@post), :method => :put)
    end
</pre>
<p>					<a name='todo-view-v'></a>					</p>
<p>We will copy the <b>view</b> view as-is:</p>
<pre class="brush: ruby">
    def view
      _post(@post)
    end
</pre>
<p>For the <b>_post</b> partial view, we'll adjust the h2 title link<br />
					from the old <b>PostN</b> controller to an item-specific action (using the post id) on the<br />
					new <b>Posts</b> REST controller. And we'll add a statement to display the post's body:</p>
<pre class="brush: ruby">
    def _post(post)
      h2 { a post.title, :href => R(Posts, post.id) }
	  p { post.body }

      p.info do
        text "Written by <strong>#{post.user.username}</strong> "
        text post.updated_at.strftime('%B %M, %Y @ %H:%M ')
        _post_menu(post)
      end
      text post.html_body
    end
</pre>
<p>The next partial view to update is <b>_admin_menu</b>, where we'll adjust the link<br />
					from the old <b>PostNew</b> controller to the <b>new</b> action of the new <b>Posts</b> REST controller:</p>
<pre class="brush: ruby">
    def _admin_menu
      text [['Log out', R(Logout)], ['New', R(Posts, 'new')]].map { |name, to|
        capture { a name, :href => to}
      }.join(' &ndash; ')
    end
</pre>
<p>The last partial view to update is <b>_post_menu</b>, where we'll adjust the edit link<br />
					from the old <b>Edit</b> controller to an item-specific <b>edit</b> action (using the post id) on the<br />
					new <b>Posts</b> REST controller. And we'll also add a link to delete the blog post using<br />
					an item-specific <b>delete</b> action.</p>
<pre class="brush: ruby">
    def _post_menu(post)
      if logged_in?
        a '(edit)',   :href => R(Posts, post.id, 'edit')
		span ' | '
        a '(delete)', :href => R(Posts, post.id, 'delete')
      end
    end
</pre>
<p>The <b>_form</b> partial view will most remain the same, except for a few visual tweaks:</p>
<pre class="brush: ruby">
    def _form(post, opts)
      form({:method => 'post'}.merge(opts)) do
        label 'Title:', :for => 'post_title'
        input :name => 'post_title', :id => 'post_title', :type => 'text',
              :value => post.title
		br

        label 'Body:', :for => 'post_body'
        textarea post.body, :name => 'post_body', :id => 'post_body'
		br

        input :type => 'hidden', :name => 'post_id', :value => post.id
        input :type => 'submit', :class => 'submit', :value => 'Submit'
      end
    end
</pre>
<p>We're now officially done with our Views::HTML module!<br />
					So we should be able to test it out: start the Camping server and navigate to the app.<br />
					You should get the home/index page.<br />
					<img src='./wp-content/media/camping-reststop/ff-home.png' width='570px'>
					</p>
<p>At this point you should be able to "exercise" all aspects of the app, from login to add, edit, delete, and logout.<br />
					<img src='./wp-content/media/camping-reststop/ff-new.png' width='570px'>
					</p>
<p></p>
<p>					<a name='todo11'></a></p>
<h5>11. Add REST XML and JSON view modules for Posts</h5>
<p>The HTML submodule was the most complicated believe it or not! Adding the XML view support is very straightforward and consists of:</p>
<ol>
<li>a layout method whose only job is to yield the content</li>
<li>a <b>user</b> view which we already created earlier when testing the Sessions controller</li>
<li>an <b>index</b> view to return the list of posts formatted as XML</li>
<li>a <b>view</b> view to return the details of a given posts formatted as XML</li>
</ol>
<p>
						The submodule will look like this:
					</p>
<pre class="brush: ruby">
module CampingRestServices::Views
  extend Reststop::Views

  # ...

  module XML
    def layout
      yield
    end

	def user
		@user.to_xml(:root => 'user')
	end

    def index
      @posts.to_xml(:root => 'blog')
    end

    def view
      @post.to_xml(:root => 'post')
    end
  end

  # ...

end
</pre>
<p>To test the API you can either:</p>
<ol>
<li>Navigate to:
<pre class="brush: ruby">

http://localhost:3301/posts.xml
</pre>
<p>					<img src='./wp-content/media/camping-reststop/ff-list-xml.png' width='570px'>
							</li>
<li>Or use IRB and the RESTR client, by evaluating the following statements:
<pre class="brush: ruby">
u1="http://localhost:8080/posts.xml"

# Get all Posts resources
p1 = Restr.get(u1,o)
</pre>
<p>					<img src='./wp-content/media/camping-reststop/tcptrace-posts-list-xml.png' width='570px'></p>
</li>
</ol>
<p>Here are a few other examples to try out from IRB to test the create, read, update, delete methods:</p>
<pre class="brush: ruby">
p2={ :title=>'Brand new REST-issued post',
	:body=>'RESTstop makes it happen!!!'} 

# Create a new resource
p2b=Restr.post(u1,p2)

# -----------------------------------------------------

u3 = "http://localhost:8080/posts/1.xml"
p3 = Restr.get(u3,o)

# Modify the title
p3['title']='UPDATED: ' + p3['title']

# Update the resource
p3b = Restr.put(u2,p3,o)

# -----------------------------------------------------

# Delete a resource
p4=Restr.delete(u3)
</pre>
<p>You have now successfully implemented the XML rendering!</p>
<p>					<a name='todo12'></a></p>
<h5>12. Add a JSON view module for Posts</h5>
<p>The JSON submodule will be as simple as the XML submodule and will look near identical except for the JSON serialization code:</p>
<pre class="brush: ruby">
module CampingRestServices::Views
  extend Reststop::Views

  # ...

  module JSON
    def layout
      yield
    end

	def user
		@user.to_json
	end

    def index
      @posts.to_json
    end

    def view
      @post.to_json
    end
  end

  # ...

end
</pre>
<p>Again, to test the JSON API you can either:</p>
<ol>
<li>Navigate to the JSON version of the url:
<pre class="brush: ruby">

http://localhost:3301/posts.json
</pre>
<p>					<img src='./wp-content/media/camping-reststop/ff-list-json.png' width='570px'>
							</li>
<li>Or use IRB and the RESTR client, by evaluating the following statements:
<pre class="brush: ruby">
u1="http://localhost:8080/posts.json"

# Get all Posts resources
p1 = Restr.get(u1,o)
</pre>
<p>					<img src='./wp-content/media/camping-reststop/tcptrace-posts-list-json.png' width='570px'></p>
</li>
</ol>
<p>You have now successfully implemented the JSON rendering!</p>
<p></p>
<hr />
<h5>Overall Recap</h5>
<p>So when you need to implement your own REST Camping app, here are the basic steps to remember:</p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
<th>Area (Module)</th>
</tr>
<tr>
<td><a href='#todo1'>1</a></td>
<td>Plug in RESTstop into the app</td>
<td>Main app</td>
</tr>
<tr>
<td><a href='#todo2'>2</a></td>
<td>Plug in RESTstop into the Base</td>
<td>Base</td>
</tr>
<tr>
<td><a href='#todo3'>3</a></td>
<td>Plug in RESTstop into the Controllers</td>
<td>Controllers</td>
</tr>
<tr>
<td><a href='#todo5'>4</a></td>
<td>Plug in RESTstop into the Helpers</td>
<td>Helpers</td>
</tr>
<tr>
<td><a href='#todo6'>5</a></td>
<td>Plug in RESTstop into the Views</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo4'>6</a></td>
<td>Create your REST resource controller</td>
<td>Controllers</td>
</tr>
<tr>
<td><a href='#todo10'>7</a></td>
<td>Add an HTML view module for your controller</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo11'>8</a></td>
<td>Add an XML view module for your controller</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo12'>9</a></td>
<td>Add a JSON view module for your controller</td>
<td>Views</td>
</tr>
<tr>
<td><a href='#todo4'>10</a></td>
<td>Either create a REST <b>Sessions</b> controller or implement OAuth</td>
<td>Controllers</td>
</tr>
</table>
<p>					<a name='sowhat'></a></p>
<h3>So What?</h3>
<p>Although you can create REST services "by hand" using either basic Ruby web server or using the Camping framework,<br />
					<a href='#rs'>RESTstop</a> brings you the following benefits:</p>
<ol>
<li>makes it easy to define REST controllers using <b>minimal syntax</b> like:
<pre class="brush: ruby">
class Posts < REST 'posts'
end
</pre>
</li>
<li>provides a simple <b>convention</b> for <b>CRUD</b> resource operations</li>
<li>delegates the API output format to the appropriate <b>format-specific view submodule</b></li>
<li>fits nicely within the overall Camping framework architecture</li>
</ol>
<p>So if you have been hesitant to provide a REST api in your Camping web application due to the anticipated complexity,<br />
					or if you want to create REST API separate from your web app, <a href='#rs'>RESTstop</a> is the right solution for you!</p>
<p>The only additional suggestion I would have is to consider using <a href='#caoauth'>OAuth</a> authorization framework<br />
					in conjunction with your REST API. This will increase the robustness and security of your service.</p>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>REST</h5>
<ul>
<li><a name='rest' href='http://en.wikipedia.org/wiki/Representational_State_Transfer'>REST Definition on Wikipedia</a></li>
<li><a name='resource' href='http://en.wikipedia.org/wiki/Representational_State_Transfer#Guiding_principles_of_a_REST_interface'>REST resource</a></li>
<li><a name='dissertation' href='http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm'>Roy Fielding's dissertation on REST</a></li>
<li><a name='wife' href='http://tomayko.com/writings/rest-to-my-wife'>Ryan Tomayko's "How I explained REST to my wife"</a></li>
<li><a name='json' href='http://www.json.org/'>JSON</a></li>
</ul>
<h5>Camping</h5>
<ul>
<li><a name='rc' href='http://github.com/camping/camping'>Ruby Camping Framework</a></li>
<li><a name='rcb' href='http://github.com/camping/camping/examples/blog.rb'>Original Camping Blog example</a></li>
<li><a name='rcroutes' href='http://camping.rubyforge.org/book/02_getting_started.html#routes'>Camping controller routes</a></li>
<li><a name='json' href='http://www.json.org/'>JSON</a></li>
<li><a name='rs' href='http://bit.ly/bsCcsS'>RESTstop library on GitHub</a></li>
<li><a name='tacaoa' href='http://github.com/techarch/camping-oauth'>Camping-OAuth repository on GitHub</a></li>
</ul>
<h5>Tools</h5>
<ul>
<li><a name='jsonvrpn' href='https://addons.mozilla.org/firefox/addon/10869'>JSON Viewer plugin for FireFox</a></li>
<li><a name='jsonvr' href='http://jsonviewer.codeplex.com/'>JSON Viewer client</a></li>
<li><a name='restr' href='http://github.com/zuk/restr'>Matt's RESTr client</a></li>
<li><a name='tcpt' 	href='http://www.pocketsoap.com/tcptrace/'>TCP Trace</a></li>
</ul>
<p>					<a name="contributors" ></a></p>
<h5>Contributors/Ruby-ists</h5>
<ul>
<li><a name='mh' href='http://judofyr.net/'>Magnus Holm (@judofyr)</a> - Camping, ...</li>
<li><a name='mz' href='http://matt.zukowski.ca/'>Matt Zukowski</a> - RESTstop, RESTr, ...</li>
</ul>
<p>					<a name="metaprog" ></a></p>
<h5>Metaprogramming</h5>
<ul>
<li><a name='inex' href='http://railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/'>Include vs. Extend in Ruby (by John Nunemaker)</a></li>
<li><a name='momi' href='http://ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html#S2'>[Module] Mixins (in Programming Ruby)</a></li>
<li><a name='clex' href='http://ruby-doc.org/docs/ProgrammingRuby/html/classes.html#UD'>Extending Objects (in Programming Ruby)</a></li>
<li><a name='moev' href='http://www.ruby-doc.org/docs/ProgrammingRuby/ref_c_module.html#Module.module_eval'>Adding module behavior with module_eval (in Programming Ruby)</a></li>
<li><a name='iece' href='http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/'>Fun with Ruby’s instance_eval and class_eval (by Brian Morearty)</a></li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a name='caoauth' href='http://blog.monnet-usa.com/?p=293'>Easily Transform Your Ruby Camping App Into An OAuth Provider</a></li>
<li><a href='http://blog.monnet-usa.com/?p=288'>Camping light (nosql) with MongoDB</a></li>
<li><a href='http://blog.monnet-usa.com/?p=223'>Visualize Application Metrics on NewRelic for your Ruby Camping Application</a></li>
<li><a href='http://blog.monnet-usa.com/?p=166'>Running the Camping Microframework on IronRuby</a></li>
</ul>
<p>					<a name='oacasrc'></a></p>
<h5>Full Source Of The RESTstop Camping REST Services App</h5>
<p>Here is the full source (you can also download it from GitHub <a href='http://bit.ly/campingsvcs'>here</a>)</p>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/GC7jYbOFrX0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=298</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=298</feedburner:origLink></item>
		<item>
		<title>Transform Your Ruby Camping Web App Into An OAuth Provider</title>
		<link>http://feedproxy.google.com/~r/the-tech-arch/~3/0gFqR-IU7EE/</link>
		<comments>http://blog.monnet-usa.com/?p=293#comments</comments>
		<pubDate>Mon, 07 Jun 2010 11:16:26 +0000</pubDate>
		<dc:creator>techarch</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Camping]]></category>
		<category><![CDATA[camping]]></category>

		<guid isPermaLink="false">http://blog.monnet-usa.com/?p=293</guid>
		<description><![CDATA[
						h3 {	text-decoration: underline; }
						h5 
						{
							margin:0 50px 0 50px;
						}
						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}
						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}
						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}
						.details_table th
						{
						background-color:lightgray;
						}
						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}

Intro 
Over the last year OAuth or Open Authorization has really been gaining ground as a mechanism to open up/free your data hosted on various [...]]]></description>
			<content:encoded><![CDATA[<style>
						h3 {	text-decoration: underline; }</p>
<p>						h5 
						{
							margin:0 50px 0 50px;
						}</p>
<p>						.download_panel
						{
						background-color: #EDD6AD; 
						color: #555555; 
						font-weight:bold;
						text-align:center;
						margin:0 50px 0 50px;
						padding:6px;
						}</p>
<p>						.details_table 
						{border: 1px solid #f0f0f0;
						border-spacing: 1px;
						background-color:white;
						margin-left: 40px;
						}</p>
<p>						.details_table tr
						{
						vertical-align: top;
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
<p>						.details_table th
						{
						background-color:lightgray;
						}</p>
<p>						.details_table td
						{
						border-bottom: 1px solid LightGoldenRodYellow;
						}</p>
</style>
<h3>Intro </h3>
<p>Over the last year <a href='#oawp'>OAuth</a> or <b>Open Authorization</b> has really been gaining ground as a mechanism to open up/free your data hosted on various web sites and let you share that data across sites. The surge in interest can be attributed to a couple developments:
					</p>
<ol>
<li>Wider availability of OAuth libraries on a wide array of platforms</li>
<li>Twitter declaring its intention to switch from Basic Authentication to OAuth</li>
<li>Google announcing OAuth for GMail</li>
<li>Other high-profile such as NetFlix providing OAuth support</li>
</ol>
<p>Although a new <a href='oaspec2'>2.0</a> version of the OAuth specification is in development,<br />
					I wanted to have my Ruby <a href='#rc'>Camping</a>-based web applications act as <a href='#oa'>OAuth providers</a> now with <a href='oaspec1a'>1.0a</a>.<br />To make that happen I needed some kind of <a href='#tacaoa'>Camping OAuth plugin</a>. Since none existed it was time to build one!</p>
<div  class='download_panel'>Click <a href='#oacasrc'>here</a> if you want to skip straight to the <a href='#oacasrc'>source code</a></div>
<h3>Synopsis of an OAuth Flow</h3>
<p>Before we can dive in the making of the <a href='#tacaoa'>Camping OAuth plugin</a> here is a quick overview of the basics of the OAuth functionality.</p>
<p>First, an OAuth provider has the responsibility to manage <a href='#oaca'>client applications</a> (<b>OAuth consumers</b>) and associated <b>tokens</b> for a given <b>user</b>. The overall model looks like this:<br />
					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-model.png' width='540px'/>
					</p>
<p><a name='oamo'></a></p>
<table class='details_table'>
<tr>
<th>Model</th>
<th>Responsibilities</th>
</tr>
<tr>
<td><a name='oaus'></a>User</td>
<td>The user account on the service provider app</td>
</tr>
<tr>
<td><a name='oaca'></a>ClientApplication</td>
<td>The registration of a specific consumer app needing data from the service provider app</td>
</tr>
<tr>
<td><a name='oatn'></a>OauthToken</td>
<td>Authorization tokens are exchanged between the consumer and the provider.<br />
	There are 2 types of tokens:</p>
<table  class='details_table'>
<tr><a name='oart'></a>
<td><b>Request</b>Token</td>
<td>The Request Token is a temporary credential token used to authenticate the <a href='#oaca'>Client Application</a> (consumer app) at the provider site. This token typically includes the key and secret issued by the provider for the consumer.</p>
<p>			Once a Request Token has been authorized, an <a name='oave'>OAuth Verifier</a> is issued. The verifier is a verification code which will be passed back to the client application for use in subsequent requests.</td>
</tr>
<tr><a name='oaat'></a>
<td><b>Access</b>Token</td>
<td>The Access Token is the authorized token the <a href='#oaca'>Client Application</a> (consumer app) needs to pass to the provider every time it wants to invokes a given API on the provider site. The Access Token is issued once the <a href='#oart'>Request Token</a> has been explicitly authorized by the user logged in at the provider site.</td>
</tr>
</table>
</td>
</tr>
<tr>
<td><a name='oane'></a>OauthNonce</td>
<td>A combination of a number used only once and a timestamp. The <a href='http://en.wikipedia.org/wiki/Cryptographic_nonce'>nonce</a> is used to prevent replay attacks during during an <a href='#oawp'>OAuth</a> exchange.</td>
</tr>
</table>
<h3>OAuth Provider API</h3>
<p>In addition to having the data infrastructure in place to manage <a href='#oaca'>client application</a> and <a href='#oatn'>tokens</a> for users, a provider also needs to expose a <b>specific OAuth API</b> in the form of <b>URL routes</b>:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-routes.png' style='margin-left: 50px;'/></p>
<p><a name='routes'></a></p>
<table class='details_table'>
<tr>
<th>Route</th>
<th>Usage</th>
</tr>
<tr>
<td>oauth/register</td>
<td>Allows a user to register an OAuth <b>consumer</b> to access data (on its behalf) from an OAuth <b>provider</b></td>
</tr>
<tr>
<td>oauth/request_token</td>
<td>Allows the consumer app to provide the <b>key</b> and <b>secret</b> associated with the user&#8217;s registration so that an OAuth <a href='#oart'>RequestToken</a> can be provided.</td>
</tr>
<tr>
<td>oauth/authorize</td>
<td>Allows the user to explicitly <b>grant access</b> to the <b>consumer</b> app on the <b>provider</b> site</td>
</tr>
<tr>
<td>callback</td>
<td>Allows the OAuth provider to <b>pass</b> data (OAuth <a href='#oave'>verifier</a>) back to the consumer app</td>
</tr>
<tr>
<td>oauth/revoke</td>
<td>Allows the user to explicitly <b>revoke access</b> to the <b>consumer app</b> on the provider site</td>
</tr>
<tr>
<td>oauth/access_token</td>
<td>Allows the consumer app to obtain an OAuth <a href='#oaat'>AccessToken</a>, based on an OAuth <a href='#oart'>RequestToken</a> and an OAuth <a href='#oave'>verifier</a>. The OAuth <a href='#oaat'>AccessToken</a> can then be passed to the provider when invoking provider APIs.</td>
</tr>
</table>
<p>And now here is the scenario illustrating models and routes together:
					</p>
<ol>
<li>User U registers consumer application C with provider application P</li>
<li>User U logs in to consumer C</li>
<li>User U invokes functionality in C requiring data (e.g. list of contacts) from provider P</li>
<li>Consumer C asks provider P for an OAuth <a href='#oart'>Request Token</a> based on its key and secret</li>
<li>Provider P validates that the user&#8217;s <a href='#oaca'>client application</a> is valid (based on its key and secret)</li>
<li>Provider P returns an OAuth <a href='#oart'>Request Token</a> R containing an authorization url</li>
<li>Consumer C redirects user U to the authorization url at Provider P</li>
<li>User U authorizes the <a href='#oart'>request token</a> R</li>
<li>Provider P redirects user U to Consumer C and provides an OAuth <a href='#oave'>verifier</a> V</li>
<li>Consumer C asks provider P for an OAuth <a href='#oaat'>Access Token</a> based on the OAuth <a href='#oart'>request token</a> ID and the OAuth <a href='#oave'>verifier</a> V</li>
<li>Provider P verifies the validitity of the <a href='#oave'>verifier</a> V for the token R</li>
<li>Provider P returns an OAuth <a href='#oaat'>Access Token</a> A to consumer C</li>
<li>Consumer C invokes an API on provider P using the OAuth <a href='#oaat'>Access Token</a> A</li>
<li>Provider P verifies the validity of the OAuth <a href='#oaat'>access token</a> A</li>
<li>Provider P executes the invoked API and returns the data to Consumer C</li>
<li>Consumer C leverages the data for the desired functionality</li>
</ol>
<h3>OAuth in Ruby</h3>
<p><a href='#pb'>Pelle Braendgaard</a> created an awesome implementation of <a href='#oarb'>OAuth for Ruby</a>. You can find the library on GitHub <a href='http://github.com/mojodna/oauth'>here</a>, and you can install it as a gem:</p>
<pre class="brush: ruby">
gem install oauth
</pre>
<p>The gem contains:</p>
<ol>
<li>The types of OAuth consumer tokens: <a href='#oart'>RequestToken</a>, <a href='#oaat'>AccessToken</a></li>
<li>The signing components</li>
<li>The communication components to request/exchange/process tokens</li>
</ol>
<p>Ruby-OAuth is primarily used for an OAuth consumer application or site to request access to data hosted by an OAuth provider.<br />
					So how do we actually build a provider?<br />
					Well there is another gem called the <a href=''>oauth-plugin</a>, which was primarily designed to easily add OAuth provider capabilities to a Rails web application. Let&#8217;s install it too.</p>
<pre class="brush: ruby">
gem install oauth-plugin
</pre>
<h5>A.Rails</h5>
<p>So assuming you have a Rails web app, you can use the <a href=''>oauth-plugin</a> to generate:</p>
<ol>
<li>The database migration script to create the new tables (ClientApplication, <a href='#oart'>RequestToken</a>, <a href='#oaat'>AccessToken</a>, Nonce) as well as to extend the existing user table</li>
<li>The models you need to track <a href='#oaat'>access tokens</a> for a given user at a given <a href='#oaca'>client application</a></li>
<li>The controller needed to manage access to a given user&#8217;s data by a <a href='#oaca'>client application</a></li>
<li>The views, forms and partials needed to register/manage access</li>
</ol>
<h5>B._why&#8217;s Camping</h5>
<p>Although you can use the <a href='#oarb'>Ruby-OAuth</a> gem to act as an OAuth consumer, there was no provider plugin like for Rails. So I stated thinking: &#8220;What would _why do?&#8221;. If the OAuth Plugin&#8217;s approach is based on generation to fit the Rails approach (with script/generate), then the <a href='#rc'>Camping</a> approach would have to be based on meta-programming. Let&#8217;s dive in the approach (or <a href='#addoaprsu'>skip</a> to the next section on how to add OAuth provider support).</p>
<h3>Implementing An OAuth Plugin In Camping Using Metaprogramming</h3>
<p>I decided to try to leverage as much as possible the templates and utility code from the oauth-plugin, but without duplicating the code. Pelle was also gracious to allow me to do so.</p>
<p>In the &#8220;<a href='#rc'>Camping</a> way of [dev] life&#8221;, adding features through metaprogramming means:</p>
<ol>
<li>including common OAuthCampingPlugin behaviors in the application&#8217;s main module:
<ul>
<li>Common helper methods related to user management, logging, etc.</li>
<li>Common controller filters</li>
</ul>
<p>
						</li>
<li>extending modules with new class utility behaviors &#8211; such as logging
</li>
<li>including the common <a href='#oamo'>OAuth models</a> in the application&#8217;s Models module with new desired instance features in other classes or in other modules &#8211; such as:
<ul>
<li><a href='#oaca'>ClientApplication</a></li>
<li><a href='#oatn'>OauthToken</a></li>
<li><a href='#oane'>OauthNonce</a></li>
<li><a href='#oart'>RequestToken</a></li>
<li><a href='#oaat'>AccessToken</a></li>
</ul>
<p>							These classes are &#8220;mixed in&#8221; by reading the oauth-plugin model templates and applying them using module_eval.</p>
</li>
<li>extending the application&#8217;s Controllers module with new meta definitions for the standard <a href='#routes'>OAuth routes</a>:
<ul>
<li>/oauth/register</li>
<li>/oauth/request_token</li>
<li>/oauth/authorize</li>
<li>/oauth/revoke</li>
<li>/oauth/access_token</li>
</ul>
<p>
						</li>
<li>including the OAuthCampingPlugin::OAuth and OAuthCampingPlugin::Helpers modules in each of the Camping controllers using class_eval.
</li>
<li>extending the application&#8217;s Controllers module with new meta definitions for common views/partials:
<ul>
<li>Application registration</li>
<li>Token authorization</li>
<li>Token revocation</li>
<li>Errors</li>
</ul>
<p>
						</li>
<li>including the OAuthCampingPlugin view methods in the application&#8217;s Views module using module_eval. </li>
</ol>
<p><i>Note: if you are interested in Ruby <b>metaprogramming</b>, check-out the <a href='#'>reference</a> section.</i></p>
<p>Here is a diagram illustrating the parallel between modules in your provider web app and the modules in the <a href='#tacaoa'>camping-oauth plugin</a>:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-layers.png' style='margin-left: 50px;'/>
					</p>
<p>					<a name="addoaprsu" ></a></p>
<h3>Adding OAuth Provider Support To Your App</h3>
<p>Here is the approach we will be taking:</p>
<p><a name='caoatodo'></a></p>
<table class='details_table'>
<tr>
<th>#</th>
<th>To Do</th>
</tr>
<tr>
<td><a href='#caoatodoa'>A</a></td>
<td>Start with a basic Camping shell</td>
</tr>
<tr>
<td><a href='#caoatodob'>B</a></td>
<td>Customize the main module</td>
</tr>
<tr>
<td><a href='#caoatodoc'>C</a></td>
<td>Plug in the OAuth models</td>
</tr>
<tr>
<td><a href='#caoatodod'>D</a></td>
<td>Create a common helpers module</td>
</tr>
<tr>
<td><a href='#caoatodoe'>E</a></td>
<td>Plug in the OAuth controllers</td>
</tr>
<tr>
<td><a href='#caoatodof'>F</a></td>
<td>Plug in the OAuth common views</td>
</tr>
<tr>
<td><a href='#caoatodog'>G</a></td>
<td>Add basic login and registration capabilities</td>
</tr>
<tr>
<td><a href='#caoatodoh'>H</a></td>
<td>Protect our API(s) using OAuth filters</td>
</tr>
</table>
<p>	</p>
<p>					<a name='caoatodoa'></a></p>
<h5>A. Let&#8217;s start with a basic Camping shell</h5>
<p>Create an camping-oauth-provider.rb file and let&#8217;s create a basic traditional <a href='#rc'>Camping</a> shell for an application named CampingOAuthProvider:</p>
<pre class="brush: ruby">
gem 'camping' , '>= 2.0'
%w(rubygems active_record camping camping/session markaby json erb).each { |lib| require lib }

Camping.goes :CampingOAuthProvider

module CampingOAuthProvider
	include Camping::Session

	def CampingOAuthProvider.create
	end
end

module CampingOAuthProvider::Models
end

module CampingOAuthProvider::Helpers
end

module CampingOAuthProvider::Controllers
	class Index
		def get
			render :index
		end
	end
end

module CampingOAuthProvider::Views
	def index
		h1 'My CampingOAuthProvider App'
		div 'To be continued ...'
	end
end

CampingOAuthProvider.create
</pre>
<p>Now we have a skeletal <a href='#rc'>Camping</a> app that we can run as follows:</p>
<pre class="brush: ruby">
camping camping-oauth-provider.rb
</pre>
<p>Access the app from the browser at the following url:</p>
<pre class="brush: ruby">

http://localhost:3001/
</pre>
<p>For our controllers we will leverage Magnus Holm&#8217;s (a.k.a. @judofyr) excellent <a href='http://github.com/judofyr/filtering_camping'>filtering_camping</a> gem, which provides a <b>controller filter mechanism</b> similar to Rails filters, but in more basic and simpler way. So let&#8217;s install it:</p>
<pre class="brush: ruby">
gem install filtering_camping
</pre>
<p>We will need to reference the four gems: filtering_camping oauth, oauth-plugin, and camping-oauth. Also we will require the various files we need: oauth, oauth/server, oauth/request_proxy, oauth/request_proxy/rack_request, camping-oauth, as well as the filtering_camping plugin.So now the top of the source should look like this:</p>
<pre class="brush: ruby">
gem 'camping' , '>= 2.0'
gem 'filtering_camping'
gem 'oauth'
gem 'oauth-plugin'

%w(rubygems active_record camping camping/session markaby json erb
oauth
oauth/server
oauth/request_proxy
oauth/request_proxy/rack_request
filtering_camping
camping-oauth
).each { |lib| require lib }

Camping.goes :CampingOAuthProvider
</pre>
<p>					<a name='caoatodob'></a></p>
<h5>B.Customizing the main module</h5>
<p>Ok, so now we&#8217;re ready to enhance the main app module. First we&#8217;ll make sure to include the Camping::Session and CampingFilters modules, and to extend the app module with OAuthCampingPlugin, like so:</p>
<pre class="brush: ruby">
module CampingOAuthProvider
	include Camping::Session
	include CampingFilters
	extend  OAuthCampingPlugin

	# ...
end
</pre>
<p>This gives us the ability to leverage a logger for the <a href='#tacaoa'>camping-oauth plugin</a>.</p>
<pre class="brush: ruby">
	OAuthCampingPlugin.logger = Logger.new(File.dirname(__FILE__) + '/CampingOAuthProvider.log');
	OAuthCampingPlugin.logger.level = Logger::DEBUG
</pre>
<p>Now let&#8217;s customize the create method by adding a call to OAuthCampingPlugin.create, so we can give the plugin to run any needed initialization.</p>
<pre class="brush: ruby">
	def CampingOAuthProvider.create
		OAuthCampingPlugin.create
	end
</pre>
<p>Ok, at this point we have a minimally configured application module. Our next step is to move on to the Models module.</p>
<p>					<a name='caoatodoc'></a></p>
<h5>C.Plugging in the OAuth models</h5>
<p>First, we&#8217;ll include the include OAuthCampingPlugin::Models module so we can get all the <a href='#oamo'>OAuth-specific models</a>. Then we&#8217;ll define a <a href='#oaus'>User</a> model. The User will need to keep track of the <a href='#oaca'>client applications</a> it provided access to. It will also manage the <a href='#oatn'>tokens</a> associated with these applications. Our model will look like this:</p>
<pre class="brush: ruby">
class User < Base;
	has_many :client_applications
	has_many :tokens,
		:class_name=>"OauthToken",
		:order=>"authorized_at desc",
		:include=>[:client_application]

end
</pre>
<p>Now we need a CreateUserSchema migration class to define our database tables for User, and <a href='#oamo'>OAuth models</a>. In the up and down methods we will plugin a call to the corresponding method from the OAuthCampingPlugin::Models module to create the tables for <a href='#oaca'>ClientApplication</a>, <a href='#oatn'>OAuthToken</a>, and <a href='#oane'>OauthNonce</a>.</p>
<pre class="brush: ruby">
class CreateUserSchema < V 1.0
	def self.up
		create_table :CampingOAuthProvider_users, :force => true do |t|
			t.integer 	:id, :null => false
			t.string		:username
			t.string		:password
		end

		User.create :username => 'admin', :password => 'camping'

		OAuthCampingPlugin::Models.up
	end

	def self.down
		OAuthCampingPlugin::Models.down
		drop_table :CampingOAuthProvider_users
	end
end
</pre>
<p>At this point we can go back to the main module and add the code to configure the ActiveRecord connection and invoke our new schema migration if the <a href='#oaus'>User</a> table does not exist yet. This code will be added to the create method:</p>
<pre class="brush: ruby">
module CampingOAuthProvider
	# ...	

	def CampingOAuthProvider.create
		dbconfig = YAML.load(File.read('config/database.yml'))
		Camping::Models::Base.establish_connection  dbconfig['development']		

		OAuthCampingPlugin.create

		CampingOAuthProvider::Models.create_schema :assume => (CampingOAuthProvider::Models::User.table_exists? ? 1.1 : 0.0)
	end
end
</pre>
<p>You probably noticed that the database configuration is loaded from a database.yml file. So let&#8217;s create a subfolder named config and a file named <b>database.yml</b>, then let&#8217;s configure the yaml file as follows:</p>
<pre class="brush: ruby">
development:
  adapter: sqlite3
  database: campingoauthprovider.db
</pre>
<p>Now if we restart the application, our migration should be executed:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-migration.png' width='570px'/></p>
<p>					<a name='caoatodod'></a></p>
<h5>D.Creating a common helpers module</h5>
<p>The Helpers module is used in <a href='#rc'>Camping</a> to provide common utilities to both the Controllers and Views modules. Enhancing our Helpers module is very easy, we need to add both and extend and an include of the OAuthCampingPlugin::Helpers module so we can enhance both instance and class sides:</p>
<pre class="brush: ruby">
module CampingOAuthProvider::Helpers
	extend OAuthCampingPlugin::Helpers
	include OAuthCampingPlugin::Helpers
end</pre>
<p>					<a name='caoatodoe'></a></p>
<h5>E.Plugging in the OAuth controllers</h5>
<p>We will need to extend our app <b>Controllers</b> module with the <b>OAuthCampingPlugin::Controllers</b> module using the extend statement. Then just before the end of the Controllers module, we&#8217;ll add a call to the <b>include_oauth_controllers</b> method. This is how <a href='#tacaoa'>camping-oauth</a> will inject and plugin the common OAuth controllers and helpers. It is important that this call <u>always remaining the last statement of the module</u>, even when you add new controller classes. So the module should look like so:</p>
<pre class="brush: ruby">
module CampingOAuthProvider::Controllers
	extend OAuthCampingPlugin::Controllers

	# ...

	include_oauth_controllers
end #Controllers
</pre>
<p>Before we continue fleshing out the logic of our controllers, let&#8217;s finish hooking up the Views module.</p>
<p>					<a name='caoatodof'></a></p>
<h5>F.Plugging in the OAuth common views</h5>
<p>We will need to extend our app <b>Views</b> module with the <b>OAuthCampingPlugin::Views</b> module using the extend statement. Then just before the end of the Views module, we&#8217;ll add a call to the <b>include_oauth_views</b> method. This is how <a href='#tacaoa'>camping-oauth</a> will inject and plugin the common OAuth views. It is important that this call <u>always remaining the last statement of the module</u>, even when you add new view methods. So the module should look like so:</p>
<pre class="brush: ruby">
module CampingOAuthProvider::Views
	extend OAuthCampingPlugin::Views

	# ...

	include_oauth_views
end
</pre>
<p>					<a name='caoatodog'></a></p>
<h5>G.Adding basic login and registration capabilities</h5>
<p>Let&#8217;s add a Login controller class to our Controllers module:</p>
<pre class="brush: ruby">
	class Login < R '/login'
		def get
			render :login
		end

		def post
			@user = User.find_by_username_and_password(input.username, input.password)

			if @user
				@state.user_id = @user.id

				if @state.return_to.nil?
					redirect R(Index)
				else
					return_to = @state.return_to
					@state.return_to = nil
					redirect(return_to)
				end
			else
				@info = 'Wrong username or password.'
			end
			render :login
		end
	end
</pre>
<p>And now add the corresponding login view in the Views module"</p>
<pre class="brush: ruby">
	def login
		div @info if @info
		form :action => R(Login), :method => 'post' do
			label 'Username', :for => 'username'; br
			input :name => 'username', :type => 'text'; br

			label 'Password', :for => 'password'; br
			input :name => 'password', :type => 'text'; br

			input :type => 'submit', :name => 'login', :value => 'Login'
		end
	end
</pre>
<p>Let's verify we can login by accessing the following url:</p>
<pre class="brush: ruby">

http://localhost:3301/login
</pre>
<p>Now that login support is in place you can test out one of the OAuth controllers by navigating to the following url:</p>
<pre class="brush: ruby">

http://localhost:3301/oauth/register
</pre>
<p>Since the <a href='#tacaoa'>camping-oauth plugin</a> installed a :before filter on the OAuthRegisterApplication controller requiring user login, you should be redirected first to the login page.<br />
					Since we created a default account when running the migration, login as <b>admin</b> with <b>camping</b> as the password. Once logged in you should be redirected back to the OAuth Application Registration page.</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-app-reg.png'  width='200px'  style='margin-left: 50px;'></p>
<p>As a side note, you can style all common OAuth views later using CSS.<br />
					We'll let you add the SignUp controller and its signup view on your own.</p>
<p>					<a name='caoatodoh'></a></p>
<h5>H.Adding our custom API, protected by OAuth</h5>
<p>Since the premise of this post was to make it easy for web apps to consume an OAuth-protected service, let's create a very simple controller (no view needed) to expose some data as JSON.</p>
<pre class="brush: ruby">
	class APITimeNow < R '/api/timenow'
		def get
			@result = {:now=>Time.now.utc.to_s}
			@result[:username] = @user.username if @user

			@headers['Content-Type'] = "application/json"
			log_debug @result.to_json
			@result.to_json
		end
	end
</pre>
<p>Now we can test it by navigating to the following url (after installing the <a href='#jsnvw'>JSONview</a> plugin for FireFox to make it easier to see the returned JSON data):</p>
<pre class="brush: ruby">

http://localhost:3301/api/timenow
</pre>
<p><img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-api.png'  /><br />
					Note that at this point this controller is NOT YET protected by OAuth. For that we need to declare a before filter for the APITimeNow controller requiring to be either logged in or OAuth-authenticated. So let's add this code snippet to our main module:</p>
<pre class="brush: ruby">
module GatedCampingSite
	# ...

	before [:APITimeNow] do
		login_or_oauth_required
	end

	# ...
end
</pre>
<p>So now if we logged out (by deleting the session cookies since we have not implemented logoff) and refreshed our browser we would be redirected to the login page.</p>
<h3>Testing And Troubleshooting</h3>
<p>At this stage, we have a basic Camping OAuth provider, now let's test it! The first thing is to register a new OAuth consumer named camping-oauth-consumer. We'll assume that:</p>
<ol>
<li>it is located at http://localhost:3000/ (fictitious for now)</li>
<li>it exposes a url: http://localhost:3000/callback to accept an <a href='#oaat'>OAuth Access token</a> <a href='#oave'>verifier</a> once authorized</li>
</ol>
<p><img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-reg1.png'   width='200px'  style='margin-left: 50px;'><br />
					Once you register you should see the following results page:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-reg2.png'   width='350px'  style='margin-left: 50px;'><br />
					The key and secret will be used by our consumer as credentials when accessing our OAuth provider, so copy/paste them into a notepad. <br />
					Here is what has been stored in our SQLite database:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-reg3.png' width='540px' ><br />
					<i>Note: if you are interested in <a href='#lita'>Lita</a>, an AIR-based SQLite administration tool, see <a href='#lita'>here</a>.</i></p>
<p>For our first test consumer will use IRB, so open up a session and let's define 3 variables for: url of our provider, key and secret (use your own values) of our registered consumer:</p>
<pre class="brush: ruby">
@site={:site=>"http://localhost:3301"}
@mykey="SQnIXDQyhFB5q3wfZyMY"
@mysecret="PmW02FNs7rXG97sAVXMWhFoJVZ98cnj21vv6p1ad"
</pre>
<p>Now let's require oauth and let's instantiate an OAuth consumer:</p>
<pre class="brush: ruby">
require 'oauth'
@consumer = OAuth::Consumer.new(@mykey,@mysecret,@site)
</pre>
<p>You should get an instance back:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-ico.png' width='540px'>
					</p>
<p>Our next step is to request an OAuth <a href='#oart'>RequestToken</a> like so:</p>
<pre class="brush: ruby">
@request_token = @consumer.get_request_token
</pre>
<p>You should get a <a href='#oart'>request token</a> back:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-rt.png' width='540px'>
					</p>
<p>Let's see how and where we should authorize this <a href='#oart'>request token</a>:</p>
<pre class="brush: ruby">
@request_token.authorize_url
</pre>
<p>You should get back the url to authorize the specific <a href='#oart'>request token</a> you just obtained.</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-rtu.png' width='540px'>
					</p>
<p>So let's copy this url and let's paste it back in the browser:</p>
<pre class="brush: ruby">

http://localhost:3301/oauth/authorize?oauth_token=0Qd6g3SjWHQEM6sUTcd9
</pre>
<p>We should be prompted by the OAuth Authorization controller of our provider:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-auth.png'   width='299px'  style='margin-left: 50px;'></p>
<p>If you click on the checkbox and the Authorize button, the provider will redirect you to the callback url we defined during registration passing back the Oauth token id and and a <a href='#oave'>verifier</a> code. Since we don't have a consumer web app up and running, we will get a navigation error. Here is what the target (redirection) url looks like:</p>
<pre class="brush: ruby">

http://localhost:3000/callback?oauth_token=0Qd6g3SjWHQEM6sUTcd9&#038;oauth_verifier=71Jt3GhiwvHlZYO9zA8c
</pre>
<p>This <a href='#oave'>verifier</a> acts as a sort of session id we need to pass to get an OAuth <a href='#oaat'>Access Token</a>. So from our IRB session, let's evaluate the following statement:</p>
<pre class="brush: ruby">
@verifier = '71Jt3GhiwvHlZYO9zA8c'
@access_token = @request_token.get_access_token(:oauth_verifier=>@verifier)
</pre>
<p>You should get an <a href='#oaat'>access token</a> back:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-at.png' width='540px'>
					</p>
<p>So now let's call our provider api:</p>
<pre class="brush: ruby">
@response = @access_token.get('/api/timenow')
@info = @response.body
</pre>
<p>You should get back a json object:</p>
<p>					<img src='./wp-content/media/camping-oauth-provider/camping-oauth-provider-atr.png' width='540px'><br />
					Yippee!!!
					</p>
<p></p>
<h5>Recap</h5>
<p>So this concludes our whirlwind tour of <a href='#oawp'>OAuth</a> from a provider and consumer side. I am leaving the following enhancements for you to do on your own:</p>
<ol>
<li>provider logout</li>
<li>provider user registration</li>
<li>provider view of all registered applications for a given user</li>
<li>provider view of all tokens for a given user's registered application</li>
<li>consumer sample web app</li>
<li>consumer callback route</li>
</ol>
<p>Also if you look in the examples folder of the <a href='#tacaoa'>camping-oauth</a> gem you will find the full source for both a provider (the one we have been working on) and a consumer app (to be run on port 3302).</p>
<h3>So What? </h3>
<ol>
<li><a href='#oawp'>OAuth</a> has become a key enabler in authorizing data sharing across web sites. <a href='#oawp'>OAuth</a> also "plays nice" with identity and authentication solutions such as for example OpenID.<br />&nbsp;</li>
<li>Ruby and <a href='#rc'>Camping</a> make it very easy to develop web applications and web services (whether you support JSON, XML, with or without REST).<br />
						<i>Note: if you're interested in REST support for Camping web services check out <a href='http://github.com/camping/reststop'>RESTstop</a>.</i><br />&nbsp;</li>
<li>With the <a href='#tacaoa'>camping-oauth plugin</a> you can easily and quickly allow your services or web app to be accessed from other services.</li>
</ol>
<p>So hopefully this post will have given you a feel for how easy it is to make a Ruby <a href='#rc'>Camping</a>-based web app act as an <a href='#oa'>OAuth provider</a> using the <a href='#tacaoa'>Camping OAuth plugin</a>.</p>
<p>					Happy OAuth experimentations!!!</p>
<p><img src='http://hueniverse.com/wp-content/uploads/2007/12/My-Endpoints.png' title='Cartoon from the hueniverse.com site' /></p>
<p>					<a name="referencesandresources" ></a></p>
<h3>References and Resources</h3>
<h5>OAuth</h5>
<ul>
<li><a name='oawp' href='http://en.wikipedia.org/wiki/Oauth'>OAuth Definition on Wikipedia</a></li>
<li><a name='oaspec1a' href='http://oauth.net/core/1.0a/'>OAuth Core 1.0a</a></li>
<li><a name='oapr' href='http://wiki.oauth.net/ServiceProviders'>OAuth Providers Catalog</a></li>
<li><a name='oan' href='http://oauth.net/'>OAuth.net site</a></li>
<li><a name='oau' href='http://hueniverse.com/'>OAuth Universe site</a></li>
<li><a name='oarb' href='http://oauth.rubyforge.org/'>OAuth Ruby repository on GitHub</a></li>
<li><a name='oarails' href='http://stakeventures.com/articles/2007/11/26/how-to-turn-your-rails-site-into-an-oauth-provider/'>How to turn your rails site into an OAuth Provider</a></li>
<p></a></li>
<li><a name='oaspec2' href='https://svn.tools.ietf.org/html/draft-hammer-oauth2-00'>Upcoming OAuth 2.0 Protocol</a></li>
</ul>
<h5>Camping</h5>
<ul>
<li><a name='rc' href='http://github.com/camping/camping'>Ruby Camping Framework</a></li>
<li><a name='tacaoa' href='http://github.com/techarch/camping-oauth'>Camping-OAuth repository on GitHub</a></li>
<li><a name='tacaoa' 'http://github.com/camping/reststop'>Camping RESTstop framework on GitHub</a></li>
</ul>
<p>					<a name="contributors" ></a></p>
<h5>Contributors/Ruby-ists</h5>
<ul>
<li><a name='jf' href='http://judofyr.net/'>Magnus Holm (@judofyr) - Camping, ...</a></li>
<li><a name='pb' href='http://stakeventures.com/'>Pelle Braendgaard (@pelleb) - OAuth, ...</a></li>
</ul>
<p>					<a name="metaprog" ></a></p>
<h5>Metaprogramming</h5>
<ul>
<li><a name='inex' href='http://railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/'>Include vs. Extend in Ruby (by John Nunemaker)</a></li>
<li><a name='momi' href='http://ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html#S2'>[Module] Mixins (in Programming Ruby)</a></li>
<li><a name='clex' href='http://ruby-doc.org/docs/ProgrammingRuby/html/classes.html#UD'>Extending Objects (in Programming Ruby)</a></li>
<li><a name='moev' href='http://www.ruby-doc.org/docs/ProgrammingRuby/ref_c_module.html#Module.module_eval'>Adding module behavior with module_eval (in Programming Ruby)</a></li>
<li><a name='iece' href='http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/'>Fun with Ruby’s instance_eval and class_eval (by Brian Morearty)</a></li>
</ul>
<h5>OAuth Integrations</h5>
<ul>
<li><a name='oagg' href='http://code.google.com/apis/accounts/docs/OAuth.html'>Google OAuth for Web Applications</a></li>
<li><a name='oatw' href='http://apiwiki.twitter.com/Authentication'>Twitter OAuth</a></li>
<li><a name='oanf' href='http://developer.netflix.com/docs/Security'>NetFlix OAuth</a></li>
</ul>
<h5>Tools</h5>
<ul>
<li><a name='jsnvw' href='https://addons.mozilla.org/en-US/firefox/addon/10869/?src=api'>JSONview plugin for FireFox</a></li>
<li><a name='oadan' href='http://github.com/episod/oauth-dancer'>Taylor Singletary's (@episod) OAuth Dancer Tool</a></li>
<li><a name='lita' 	href='http://www.dehats.com/drupal/?q=node/58'>Lita, a SQLite administration tool</a></li>
<li><a name='tcpt' 	href='http://www.pocketsoap.com/tcptrace/'>TCP Trace</a></li>
</ul>
<h5>My Other Related Posts:</h5>
<ul name="myotherrelatedposts">
<li><a href='http://blog.monnet-usa.com/?p=288'>Camping light (nosql) with MongoDB</a></li>
<li><a href='http://blog.monnet-usa.com/?p=223'>Visualize Application Metrics on NewRelic for your Ruby Camping Application</a></li>
<li><a href='http://blog.monnet-usa.com/?p=166'>Running the Camping Microframework on IronRuby</a></li>
</ul>
<p>					<a name='oacasrc'></a></p>
<h5>Source Code</h5>
<div   class='download_panel'>All source is available on GitHub:</p>
<ul>
						<a href='http://bit.ly/campingoauth'>Camping OAuth <b>Plugin</b> library</a><br />
						<a href='http://bit.ly/cgoapreg'>Camping OAuth <b>Provider</b> Example</a><br />
						<a href='http://bit.ly/cgoacoeg'>Camping OAuth <b>Consumer</b> Example</a>
					</div>
<img src="http://feeds.feedburner.com/~r/the-tech-arch/~4/0gFqR-IU7EE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.monnet-usa.com/?feed=rss2&amp;p=293</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.monnet-usa.com/?p=293</feedburner:origLink></item>
	</channel>
</rss>

