<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Christophe Coenraets</title>
	<atom:link href="http://coenraets.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://coenraets.org/blog</link>
	<description>Mobile, Cloud, HTML, JavaScript, Java, PHP, Flex</description>
	<lastBuildDate>Mon, 06 Feb 2012 17:27:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Sample Mobile App with Backbone.js and PhoneGap</title>
		<link>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-and-phonegap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sample-mobile-app-with-backbone-js-and-phonegap</link>
		<comments>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-and-phonegap/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 17:27:53 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2987</guid>
		<description><![CDATA[I recently blogged a tutorial (part 1, part 2, part 3, and postface) that takes you through the process of building a CRUD application using HTML and the Backbone.js framework. The application used in this tutorial is a Wine Cellar management app, and I thought it would be fun to create a Mobile version using [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Sample Mobile App with Backbone.js and PhoneGap http://coenraets.org/blog/?p=2987" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F02%2Fsample-mobile-app-with-backbone-js-and-phonegap%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p>I recently blogged a tutorial (<a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">part 1</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">part 2</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/">part 3</a>, and <a href="http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/">postface</a>) that takes you through the process of building a CRUD application using HTML and the <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> framework. The application used in this tutorial is a Wine Cellar management app, and I thought it would be fun to create a Mobile version using <a href="http://phonegap.com/">PhoneGap</a>.</p>
<p>PhoneGap &#8212; if you are not familiar with it &#8212; is an open source platform that allows you develop cross-platform Mobile applications using HTML and JavaScript. Specifically, it allows you to:</p>
<ol>
<li>Package an HTML application as a native app on all the key mobile platforms (iOS, Android, BlackBerry, Windows Phone, WebOS, Symbian, Bada).</li>
<li>Access your device capabilities (Camera, GPS, database, accelerometer, etc) using a cross-platform JavaScript API.</li>
</ol>
<p>Backbone.js is a great framework to give structure to your web application regardless of where it is running: in a traditional Web Browser, or as an app packaged with PhoneGap. </p>
<p>So, here is the app&#8230;<br />
<span id="more-2987"></span></p>
<p>
<img src="http://coenraets.org/blog/wp-content/uploads/2012/02/wine4.jpg" alt="" title="wine4" width="300" height="450" style="float: left;" /></p>
<p><img src="http://coenraets.org/blog/wp-content/uploads/2012/02/wine3.jpg" alt="" title="wine3" width="300" height="450" style="float: right;margin-top:-20px;"/>
</p>
<p style="clear: both;">&nbsp;</p>
<p>The UI is intentionally plain to keep the focus on the architectural framework. This is a simple &#8216;consumer&#8217; version of the application: It allows you to look for wines in your Wine Cellar. The tutorial application mentioned above is an &#8216;admin&#8217; version: You can create, update, delete wines in your Wine Cellar. Most of the code is shared between the Mobile &#8216;consumer&#8217; version and the browser-based &#8216;admin&#8217; version.</p>
<p>In this version, the application gets the data from RESTful services hosted on my server. In my next post, I will provide another version of the application that gets the data using a local database on your device.</p>
<h4>Download</h4>
<p>I added the source code for the mobile application to the <a href="https://github.com/ccoenraets/backbone-cellar">backbone-cellar GitHub repository</a>. You can download the zip file <a href="https://github.com/ccoenraets/backbone-cellar/zipball/master">here</a>. For your convenience, I created an <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/ios">iOS directory</a> with the Xcode project and an <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/android">Android directory</a> with the Eclipse project. The core application is in www directory and it is the same code for both iOS and Android.</p>
<p>If you want to run the application on your Android device without installing the project, you can also download the apk file available in the <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/android/BackboneCellarAndroid/bin">bin directory</a>.</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Sample Mobile App with Backbone.js and PhoneGap http://coenraets.org/blog/?p=2987" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F02%2Fsample-mobile-app-with-backbone-js-and-phonegap%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-and-phonegap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sample Application with Angular.js</title>
		<link>http://coenraets.org/blog/2012/02/sample-application-with-angular-js/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sample-application-with-angular-js</link>
		<comments>http://coenraets.org/blog/2012/02/sample-application-with-angular-js/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 20:33:32 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Angular.js]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2889</guid>
		<description><![CDATA[After I blogged a three-part Backbone.js tutorial (part 1, part 2, part 3), a number of people asked me to try Angular.js. So I decided to take it for a test drive. I thought it would be interesting to rebuild with Angular.js the Wine Cellar application I had built with Backbone. If you are new [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Sample Application with Angular.js http://coenraets.org/blog/?p=2889" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F02%2Fsample-application-with-angular-js%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p>After I blogged a three-part Backbone.js tutorial (<a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">part 1</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">part 2</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/">part 3</a>), a number of people asked me to try <a href="http://angularjs.org/">Angular.js</a>. So I decided to take it for a test drive. I thought it would be interesting to rebuild with Angular.js the Wine Cellar application I had built with Backbone.<br />
<span id="more-2889"></span></p>
<p><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/cellar2.jpg" alt="" title="cellar2" width="640" height="496" class="alignnone size-full wp-image-2392" /></p>
<p>If you are new to my Wine Cellar application, it is a simple CRUD app that allows you to manage (create, update, delete) wines in a Wine Cellar. The data is stored in a MySQL database that the client application accesses through a simple RESTful API. This seemed to be a good fit since CRUD applications are often positioned as the sweet spot for Angular.js.</p>
<p>You can run the application <a href="http://coenraets.org/angular-cellar">here</a>. The UI is intentionally plain to keep the focus on the key learning points. For obvious reasons, this online version is &#8220;read-only&#8221;. You can download the fully enabled version <a href="https://github.com/ccoenraets/angular-cellar">here</a>. </p>
<h4>Application Walkthrough</h4>
<p>The best way to get started with Angular.js is to go through the <a href="http://docs.angularjs.org/#!/tutorial">excellent tutorial</a> that is part of the documentation, so I&#8217;ll only provide a high level overview of my code here. </p>
<p>Like the Backbone.js implementation, the Angular.js version is a deep-linkable single page application. index.html is defined as follows:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE HTML&gt;
&lt;html xmlns:ng=&quot;http://angularjs.org&quot;&gt;
&lt;head&gt;
&lt;title&gt;Angular Cellar&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;css/styles.css&quot; /&gt;
&lt;/head&gt;

&lt;body ng:controller=&quot;RouteCtrl&quot;&gt;

&lt;div id=&quot;header&quot;&gt;
    Angular Cellar
    &lt;button ng:click=&quot;addWine()&quot;&gt;New Wine&lt;/button&gt;
&lt;/div&gt;

&lt;div id=&quot;sidebar&quot;&gt;
    &lt;ng:include src=&quot;'tpl/wine-list.html'&quot;&gt;&lt;/ng:include&gt;
&lt;/div&gt;

&lt;div id=&quot;content&quot;&gt;
    &lt;ng:view&gt;&lt;/ng:view&gt;
&lt;/div&gt;

&lt;script src=&quot;lib/angular-0.9.19.min.js&quot; ng:autobind&gt;&lt;/script&gt;
&lt;script src=&quot;js/services.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/controllers.js&quot;&gt;&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;
</pre>
<p>The application is driven by a set of <strong>Controllers</strong> that I defined in controllers.js as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
function RouteCtrl($route) {

    var self = this;

    $route.when('/wines', {template:'tpl/welcome.html'});

    $route.when('/wines/:wineId', {template:'tpl/wine-details.html', controller:WineDetailCtrl});

    $route.otherwise({redirectTo:'/wines'});

    $route.onChange(function () {
        self.params = $route.current.params;
    });

    $route.parent(this);

    this.addWine = function () {
        window.location = &quot;#/wines/add&quot;;
    };

}

function WineListCtrl(Wine) {

    this.wines = Wine.query();

}

function WineDetailCtrl(Wine) {

    this.wine = Wine.get({wineId:this.params.wineId});

    this.saveWine = function () {
        if (this.wine.id &gt; 0)
            this.wine.$update({wineId:this.wine.id});
        else
            this.wine.$save();
        window.location = &quot;#/wines&quot;;
    }

    this.deleteWine = function () {
        this.wine.$delete({wineId:this.wine.id}, function() {
            alert('Wine ' + wine.name + ' deleted')
            window.location = &quot;#/wines&quot;;
        });
    }

}
</pre>
<p><strong>RouteCtrl</strong> defines the routes of the application. Each route is defined by a template that is rendered in &lt;ng:view&gt; inside index.html. There can only be one &lt;ng:view&gt; in a document (more on that later). For example, here is the wine-list.html template:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;ul ng:controller=&quot;WineListCtrl&quot;&gt;
    &lt;li ng:repeat=&quot;wine in wines&quot;&gt;
        &lt;a href='#/wines/{{ wine.id }}'&gt;{{ wine.name }}&lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>The <strong>WineListCtrl</strong> and <strong>WineDetailCtrl</strong> controllers provide access to the data using a service defined in services.js as follows: </p>
<pre class="brush: jscript; title: ; notranslate">
angular.service('Wine', function ($resource) {
    return $resource('api/wines/:wineId', {}, {
        update: {method:'PUT'}
    });
});
</pre>
<p>Services provide a great way to abstract your data access logic, and to easily change it without impacting the rest of the application. For example, you could easily change the Wine service to use a Mock service instead of a RESTful service.</p>
<h4>Impressions</h4>
<p>I was able to build this application in a very limited amount of time with no prior knowledge of the framework. The data-binding implementation is nice, and, in general, the amount of boilerplate code you have to write is very limited. Frameworks are often a matter of style and personal preferences. Angular.js takes a more declarative approach than other frameworks. Based on this initial experience, I would also describe it as more prescriptive: I didn&#8217;t have to spend a lot of time wondering what was the best way to do things as Angular.js tends to have clear utilization patterns. I haven&#8217;t spend enough time with the framework to determine if that comes at the cost of less control, and I&#8217;d love to hear what other people are thinking.</p>
<p>The only problem I ran into while building the application is the &#8220;one route / one view&#8221; coupling I alluded to above. As suggested in <a href="http://groups.google.com/group/angular/browse_thread/thread/c482321a95bc2949/2e5c9074485c102d?hide_quotes=no">this thread</a>, you can use &lt;ng:include&gt; to bind partials in the page. The same thread also indicates that multiple &lt;ng:views&gt; per route definition will be supported in the future. I was able to handle the simple UI requirements of this app using one &lt;ng:view&gt; and one &lt;ng:include&gt;. For more complex applications, I&#8217;d love the routing infrastructure to allow me to easily and arbitrarily add, remove, change, or animate different elements of the DOM when the route changes in order to support deeper UI transformations. I&#8217;m sure there are ways to do this. If Angular.js folks are reading this post, I&#8217;d love to hear what they think and what&#8217;s coming.</p>
<h4>Download</h4>
<p>The application is available on GitHub <a href="https://github.com/ccoenraets/angular-cellar">here</a>. </p>
<p>You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download. If you want to test the application with a Java back-end, you can download the Backbone version <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>, and reuse its JAX-RS back-end.</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Sample Application with Angular.js http://coenraets.org/blog/?p=2889" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F02%2Fsample-application-with-angular-js%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/02/sample-application-with-angular-js/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Backbone.js Lessons Learned and Improved Sample App</title>
		<link>http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=backbone-js-lessons-learned-and-improved-sample-app</link>
		<comments>http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 16:06:42 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2810</guid>
		<description><![CDATA[A few weeks ago, I posted a three-part Backbone.js tutorial (part 1, part 2, part 3). Since then, I spent more time building a real-life application with Backbone. I ran into a number of interesting problems, spent time thinking about solutions, and decided to write them down in this post. These are not definitive answers, [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Backbone.js Lessons Learned and Improved Sample App http://coenraets.org/blog/?p=2810" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F01%2Fbackbone-js-lessons-learned-and-improved-sample-app%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, I posted a three-part Backbone.js tutorial (<a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">part 1</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">part 2</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/">part 3</a>). Since then, I spent more time building a real-life application with Backbone. I ran into a number of interesting problems, spent time thinking about solutions, and decided to write them down in this post. These are not definitive answers, just my current thoughts&#8230; and as always, I value your input.</p>
<p>Based on this new experience, I revisited the Wine Cellar application used in my tutorial. You can find the improved version <a href="https://github.com/ccoenraets/backbone-cellar">here</a> (PHP back-end) or <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a> (Java back-end).  </p>
<h4>Externalizing Templates</h4>
<p>In the initial implementation of my wine cellar app, I &#8220;inlined&#8221; my templates in a succession of &lt;script&gt; tags like the one below inside index.html.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script type=&quot;text/template&quot; id=&quot;wine-list-item&quot;&gt;
	&lt;li&gt;&lt;a href='#wines/&lt;%= id %&gt;'&gt;&lt;%= name %&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/script&gt;
</pre>
<p>This approach works fine for a simple application with a limited number of templates. In a larger project, it makes templates hard to maintain. It also makes it difficult for multiple developers to work on different templates at the same time. Removing the script body and adding a src attribute to point to an external file didn’t seem to work to load HTML templates.<br />
<span id="more-2810"></span><br />
In <a href="http://stackoverflow.com/questions/8366733/external-template-in-underscore">this</a> StackOverflow thread, Brian Genisio suggests loading external templates as string variables in a .js file. Using this approach, a template definition looks like this:</p>
<pre class="brush: jscript; title: ; notranslate">
app.templates.view = &quot; \
    &lt;h3&gt;something code&lt;/h3&gt; \
&quot;;
</pre>
<p>That’s certainly a valid approach, but depending on your circumstances, it may still not be the ideal solution: long string concatenation is painful (especially for larger templates). In addition, if you define HTML in string variables, you will probably not be able to benefit from the HTML capabilities of your editor.  </p>
<p>Other people load external templates using <a href="http://requirejs.org/">Require.js</a> and the text plugin, which is definitely an approach worth considering for larger projects. In my case, I didn’t feel that the size of my project mandated it.</p>
<p>In the end, I decided to write my own simple template loader. It is implemented as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
tpl = {

    // Hash of preloaded templates for the app
    templates: {},

    // Recursively pre-load all the templates for the app.
    // This implementation should be changed in a production environment:
    // All the template files should be concatenated in a single file.
    loadTemplates: function(names, callback) {

        var that = this;

        var loadTemplate = function(index) {
            var name = names[index];
            console.log('Loading template: ' + name);
            $.get('tpl/' + name + '.html', function(data) {
                that.templates[name] = data;
                index++;
                if (index &lt; names.length) {
                    loadTemplate(index);
                } else {
                    callback();
                }
            });
        }

        loadTemplate(0);
    },

    // Get template by name from hash of preloaded templates
    get: function(name) {
        return this.templates[name];
    }

};
</pre>
<p>I use it to preload all my templates before bootstrapping Backbone:</p>
<pre class="brush: jscript; title: ; notranslate">
tpl.loadTemplates(['header', 'wine-details', 'wine-list-item'], function() {
    app = new AppRouter();
    Backbone.history.start();
});
</pre>
<p>Loading templates separately is great during development: you can modify and test individual templates without requiring a “build” or the concatenation of multiple template files. In production however, loading dozens of templates as separate HTTP requests can be a serious bottleneck. So when you are ready to move to production, it&#8217;s a good idea to somehow combine all your templates in a single file so that you can load them all with a single HTTP request.</p>
<h4> Decouple Views from other DOM elements</h4>
<p>In the initial version of my application, I didn’t pay much attention to the way I chose the &#8220;el&#8221; or &#8220;tagName&#8221; of my Views. I often assigned the View’s &#8220;el&#8221; to an existing element of the document.</p>
<p>&#8220;Before&#8221; code:</p>
<pre class="brush: jscript; title: ; notranslate">
window.WineView = Backbone.View.extend({

    el: $('#content'),

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    }

});
</pre>
<p>&#8230; and here is the Router&#8217;s code that instantiated and displayed a WineView:</p>
<pre class="brush: jscript; title: ; notranslate">
new WineView().render();
</pre>
<p>After more careful consideration, I realized that this approach wasn’t very good. The View is not fully encapsulated: it “reaches out” to an attribute (element) of the containing document (&#8216;#mainArea&#8217;), creating an undesirable dependency. A better approach is to make sure a View doesn’t know about its hosting document. It should not know about (or assume the presence) of other elements in the document. The knowledge of the View should be limited to the elements in its own template.  That will make the view reusable in many different contexts. The corollary of this rule is that a View shouldn’t attach itself to a DOM element in its render() method. The render() method should be limited to populating its own &#8220;detached&#8221; el attribute. The code that invokes the View’s render() method can then decide what to do with the View’s HTML fragment: attach it, append it, etc. The View is therefore more reusable and more versatile.</p>
<p>&#8220;After&#8221; code:</p>
<pre class="brush: jscript; title: ; notranslate">
window.WineView = Backbone.View.extend({

    tagName: &quot;div&quot;, // Not required since 'div' is the default if no el or tagName specified

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    }

});
</pre>
<p>&#8230; and here is the Router’s code that instantiates and displays a WineView defined as above:</p>
<pre class="brush: jscript; title: ; notranslate">
$('#content').html( new WineView().render().el );
</pre>
<p>&nbsp;</p>
<h4>Cleaning Up: Avoiding Memory Leaks and Ghost Views</h4>
<p>Before getting rid of a view, you need to clean up, which mainly consists of removing the bindings that could prevent the View from being properly destroyed. A View that is not properly destroyed becomes a “Ghost View”: you don’t see it, you think it’s gone,  but it still manifests itself in some unpleasant ways: its events are still firing and it still uses memory (memory leaks). Ghost Views often first manifest themselves in the form of events firing multiple times. </p>
<p>In my initial implementation, I provided views with a close() method that took care of cleaning up. There was nothing wrong with that approach except that you had to remember to call the close() method! </p>
<p>Derick Bailey has a <a href="http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/">great post</a> on this topic and provides a more generalized approach: It consists of adding a generic close() method to the Backbone View prototype. I borrowed Derick’s approach and implemented my generic close() method as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
Backbone.View.prototype.close = function () {
    if (this.beforeClose) {
        this.beforeClose();
    }
    this.remove();
    this.unbind();
};
</pre>
<p>The call to beforeClose() (if it exists in the view) is a hook to add some view-specific cleanup code if required.</p>
<p>In your Router, you then create new Views by invoking a custom showView() method that invokes close() on the currentView before replacing it with the new View. </p>
<pre class="brush: jscript; title: ; notranslate">
showView: function(selector, view) {
    if (this.currentView)
        this.currentView.close();
    $(selector).html(view.render().el);
    this.currentView = view;
    return view;
}
</pre>
<p>Note that this is only part of the solution. For example, if you have composite views (views containing other views), you still have to make sure you close the “child” views when the parent view is closed. A good approach here is for the parent view to keep track of its child views so that it can call their respective close() methods when its own close() method is invoked. The beforeClose() method (explained above) of the parent View is a good place to close the child Views.</p>
<h4>Route pre-processing (aka Filters)</h4>
<p>Backbone’s Router is great at routing requests to the important/stateful/bookmarkable locations in your application. </p>
<p>When defining the routes in my application, I sometimes find myself in a situation where a pre-condition has to be met before a route can be taken.</p>
<p>For example: </p>
<ul>
<li>Some routes may require the user to be authenticated.</li>
<li>Some routes may require some data to be loaded.</li>
</ul>
<p>It’s easy to verify the pre-condition in the method that implements a specific route. That’s what I did in the initial version of my application. But in a larger application, this approach will quickly start cluttering your route methods.</p>
<p>My instinct was to look for a “Filter” feature in the Backbone Router API, but it doesn’t currently exist out-of-the-box, and in <a href="https://github.com/documentcloud/backbone/pull/299">this thread</a>, Jeremy makes the case that the same result can be achieved using underscore’s _.wrap() method.</p>
<p>_.wrap() didn’t work for me because my pre-condition involved asynchronous processing and I can only pass control back to the routing method after the successful completion of my async code.</p>
<p>In the end, I implemented a simple/low-tech before() method that is somewhat similar to wrap() but supports async chaining. </p>
<pre class="brush: jscript; title: ; notranslate">
var AppRouter = Backbone.Router.extend({

	routes: {
		&quot;wines/:id&quot;	: &quot;wineDetails&quot;
	},

	wineDetails: function(id) {
        this.before(function() {
			var wine = app.wineList.get(id);
		    app.showView( '#content', new WineView({model: wine}) );
        });
  	},

    showView: function(selector, view) {
        if (this.currentView)
            this.currentView.close();
        $(selector).html(view.render().el);
        this.currentView = view;
        return view;
    },

    before: function(callback) {
        if (this.wineList) {
            if (callback) callback();
        } else {
            this.wineList = new WineCollection();
       		this.wineList.fetch({success: function() {
               $('#sidebar').html( new WineListView({model: app.wineList}).render().el );
               if (callback) callback();
            }});
        }
    }

});
</pre>
<p>This solution is not as “decoupled” as a traditional filter implementation would be, but it allowed me to unclutter my code in a way that was suitable for my requirements. Jake Dempsey<br />
 has built a more traditional filter implementation <a href="https://github.com/angelo0000/backbone_filters">here</a> that you may want to take a look at. </p>
<h4>Download</h4>
<p>The source code for this application is hosted on GitHub. The application uses RESTful services to access the data.</p>
<p>For a version of this application using a PHP back-end, use <a href="https://github.com/ccoenraets/backbone-cellar">this project</a> (use the &#8216;final&#8217; folder for the version of the application discussed in this article.</p>
<p>For a version of this application using a Java back-end (using JAX-RS), use <a href="https://github.com/ccoenraets/backbone-jax-cellar">this project</a>.</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Backbone.js Lessons Learned and Improved Sample App http://coenraets.org/blog/?p=2810" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F01%2Fbackbone-js-lessons-learned-and-improved-sample-app%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using Backbone.js with a RESTful Java Back-End</title>
		<link>http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-backbone-js-with-a-restful-java-back-end</link>
		<comments>http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 17:39:44 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2765</guid>
		<description><![CDATA[In a previous post, RESTful services with jQuery and Java using JAX-RS and Jersey, I demonstrated how to build a RESTful API using JAX-RS and Jersey, and how to build a jQuery application that leverages that API. The application used as an example was a Wine Cellar management application. In follow-up posts, &#8220;Backbone.js Wine Cellar [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Using Backbone.js with a RESTful Java Back-End http://coenraets.org/blog/?p=2765" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F01%2Fusing-backbone-js-with-a-restful-java-back-end%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/01/backbone-java4.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2012/01/backbone-java4.jpg" alt="" title="backbone-java4" width="428" height="148" class="aligncenter size-full wp-image-2792" /></a></p>
<p>In a previous post, <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/">RESTful services with jQuery and Java using JAX-RS and Jersey</a>, I demonstrated how to build a RESTful API using JAX-RS and Jersey, and how to build a jQuery application that leverages that API. The application used as an example was a Wine Cellar management application.</p>
<p>In follow-up posts, &#8220;Backbone.js Wine Cellar Tutorial&#8221; (<a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">part1</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">part 2</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/">part 3</a>), I showed how to add structure to the client-side of the Wine Cellar application using <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>. But that three-part tutorial was provided with a PHP back-end.</p>
<p>By popular demand, here is a version of the Backbone.js Wine Cellar application powered by a Java / JAX-RS back-end using Jersey. The server-side of the application provides an example of building a complete RESTful API in Java using the different HTTP methods:<br />
<span id="more-2765"></span></p>
<ul>
<li><strong>GET</strong> to retrieve and search wines</li>
<li><strong>POST</strong> to add a wine</li>
<li><strong>PUT</strong> to update a wine</li>
<li><strong>DELETE</strong> to delete a wine</li>
</ul>
<p>As already mentioned, the client-side of the application provides an example of adding structure to your JavaScript code using the Backbone.js Model, View and Router components. To learn more about the Backbone.js implementation, refer to the three part tutorial mentioned above: it is entirely back-end agnostic. </p>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>. It consists of the Eclipse Dynamic Web Project with the source code for both the Java back-end and JavaScript/Backbone.js client.</p>
<p>You can run the application (Part 3) <a href="http://coenraets.org/backbone-cellar/part3/">here</a>. The create/update/delete features are disabled in this online version.</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Using Backbone.js with a RESTful Java Back-End http://coenraets.org/blog/?p=2765" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F01%2Fusing-backbone-js-with-a-restful-java-back-end%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Setting Up WordPress on Amazon EC2 in 5 minutes</title>
		<link>http://coenraets.org/blog/2012/01/setting-up-wordpress-on-amazon-ec2-in-5-minutes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=setting-up-wordpress-on-amazon-ec2-in-5-minutes</link>
		<comments>http://coenraets.org/blog/2012/01/setting-up-wordpress-on-amazon-ec2-in-5-minutes/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 20:45:48 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Amazon EC2]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2672</guid>
		<description><![CDATA[Step 1: Create an AWS Account First things first: you need to create your AWS account. You can sign up here. You&#8217;ll have to provide a credit card and a phone number where you will be called as part of the online registration process for verification purposes. Amazon offers a Free Usage Tier, which is [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Setting Up WordPress on Amazon EC2 in 5 minutes http://coenraets.org/blog/?p=2672" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F01%2Fsetting-up-wordpress-on-amazon-ec2-in-5-minutes%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/01/awswp.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2012/01/awswp.jpg" alt="" title="awswp" width="289" height="100" class="aligncenter size-full wp-image-2753" /></a></p>
<h4>Step 1: Create an AWS Account</h4>
<p>First things first: you need to create your AWS account. You can sign up <a href="http://aws.amazon.com/ec2/">here</a>. You&#8217;ll have to provide a credit card and a phone number where you will be called as part of the online registration process for verification purposes. Amazon offers a <em>Free Usage Tier</em>, which is great to explore the services and even host real apps without being charged. Check the details <a href="http://aws.amazon.com/free/">here</a>.<br />
<span id="more-2672"></span></p>
<h4>Step 2: Create an Instance</h4>
<p><em>What type of EC2 instance should you use?</em> I started my experiments with a Micro instance because its price structure is very attractive. However, after a few minutes to a couple of hours, my blog systematically became unresponsive and I had to restart Apache and/or MySQL. I did some research, and found out that other people were reporting similar problems. It may depend on your blog traffic. My blog typically gets a few thousand page views a day. It also hosts live sample applications running with a PHP or a Java back-end running on Tomcat. It looks like that combination was too much for a Micro instance. I tried a Small instance and the problems went away. Greg Wilson has a <a href="http://gregsramblings.com/2011/02/07/amazon-ec2-micro-instance-cpu-steal/">great post</a> on the limitations of the Micro instance.</p>
<p>To create a new instance, access the AWS Management Console and click the EC2 tab:</p>
<ul>
<li>Choose an AMI in the classic instance wizard: I chose the <strong>Basic 32-bit Amazon Linux AMI</strong>.</li>
<li>Instance details: Select the <strong>Instance Type</strong> you want to use. I chose <strong>Small</strong> (m1.small).</li>
<li>Create a new key pair. Enter a name for your key pair (i.e. christophe) and download your key pair (i.e. christophe.pem).</li>
<li>Select the quick start security group.</li>
<li>Launch your instance.</li>
</ul>
<h4>Step 3: SSH into your Instance</h4>
<p>Once your instance is running, you can ssh into it. First, you need to identify the address of your instance: Select the instance in the AWS Management Console, and look for the Public DNS in the instance description (bottom part of the screen).</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2011/11/aws2.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2011/11/aws2.jpg" alt="" title="aws2" width="640" height="578" class="alignnone size-full wp-image-2212" /></a></p>
<p>Use that address (and a path to your .pem file) to ssh into your instance:<br/><span style="font-family:courier;font-weight:bold;color:#000;">ssh ec2-user@ec2-50-17-14-16.compute-1.amazonaws.com -i ~/christophe.pem<br />
</span><br />
If you get a message about your .pem file permissions being too open, chmod your .pem file as follows:<br /><span style="font-family:courier;font-weight:bold;color:#000;">chmod 600 ~/christophe.pem</span></p>
<p>Many of the shell commands below require root access. To avoid having to prefix these commands with sudo, let&#8217;s just switch user once and for all:<br /><span style="font-family:courier;font-weight:bold;color:#000;">sudo su</span></p>
<h4>Step 4: Install the Apache Web Server</h4>
<p>To install the Apache Web Server, type:<br /><span style="font-family:courier;font-weight:bold;color:#000;">yum install httpd</span></p>
<p>Start the Apache Web Server:<br /><span style="font-family:courier;font-weight:bold;color:#000;">service httpd start</span></p>
<p>To test your Web Server, open a browser and access your web site: <a href="">http://ec2-50-17-14-16.compute-1.amazonaws.com</a> (Use your actual public DNS name). You should see a standard Amazon place holder page.</p>
<h4>Step 5: Install PHP</h4>
<p>To install PHP, type:<br /><span style="font-family:courier;font-weight:bold;color:#000;">yum install php php-mysql</span></p>
<p>Restart the Apache Web Server:<br /><span style="font-family:courier;font-weight:bold;color:#000;">service httpd restart</span></p>
<p>Create a page to test your PHP installation:<br /><span style="font-family:courier;font-weight:bold;color:#000;">cd /var/www/html<br />vi test.php</span></p>
<ol>
<li>Type <span style="font-family:courier;font-weight:bold;color:#000;">i</span> to start the insert mode</li>
<li>Type <span style="font-family:courier;font-weight:bold;color:#000;">&lt;?php phpinfo() ?></span></li>
<li>Type <span style="font-family:courier;font-weight:bold;color:#000;">:wq</span> to write the file and quit vi</li>
</ol>
<p>Open a browser and access test.php to test your PHP installation: <a href="">http://ec2-50-17-14-16.compute-1.amazonaws.com/test.php</a> (Use your actual public DNS name).</p>
<h4>Step 6: Install MySQL</h4>
<p>To install MySQL, type:<br /><span style="font-family:courier;font-weight:bold;color:#000;">yum install mysql-server</span></p>
<p>Start MySQL:<br /><span style="font-family:courier;font-weight:bold;color:#000;">service mysqld start</span></p>
<p>Create your &#8220;blog&#8221; database:<br /><span style="font-family:courier;font-weight:bold;color:#000;">mysqladmin -uroot create blog</span></p>
<p>Secure your database:<br /><span style="font-family:courier;font-weight:bold;color:#000;">mysql_secure_Installation</span></p>
<p>Answer the wizard questions as follows:</p>
<ol>
<li>Enter current password for root: Press return for none</li>
<li>Change Root Password: Y</li>
<li>New Password: Enter your new password</li>
<li>Remove anonymous user: Y</li>
<li>Disallow root login remotely: Y</li>
<li>Remove test database and access to it: Y</li>
<li>Reload privilege tables now: Y</li>
</ol>
<h4>Step 7: Install WordPress</h4>
<p>To install WordPress, type:<br /><span style="font-family:courier;font-weight:bold;color:#000;">cd /var/www/html<br />
wget http://wordpress.org/latest.tar.gz<br />
tar -xzvf latest.tar.gzcd<br />
</span></p>
<p>This will uncompress WordPress in its own &#8220;wordpress&#8221; directory. I like having WordPress in a separate directory, but would rather rename it to &#8220;blog&#8221;:<br /><span style="font-family:courier;font-weight:bold;color:#000;">mv wordpress blog</span></p>
<p>Create the WordPress wp-config.php file: <br /><span style="font-family:courier;font-weight:bold;color:#000;">cd blog<br />
mv wp-config-sample.php wp-config.php<br />
vi wp-config.php</span></p>
<ol>
<li>Type <span style="font-family:courier;font-weight:bold;color:#000;">i</span> to start insert mode.</li>
<li>Modify the database connection parameters as follows:<br />
<span style="font-family:courier;font-weight:bold;color:#000;">define(&#8216;DB_NAME&#8217;, &#8216;blog&#8217;);<br />
define(&#8216;DB_USER&#8217;, &#8216;root&#8217;);<br />
define(&#8216;DB_PASSWORD&#8217;, &#8216;YOUR_PASSWORD&#8217;);<br />
define(&#8216;DB_HOST&#8217;, &#8216;localhost&#8217;);</span>
</li>
<li>Type <span style="font-family:courier;font-weight:bold;color:#000;">:wq</span> to write the file and quit vi</li>
</ol>
<p>Open a Browser and access your blog: <a href="">http://ec2-50-17-14-16.compute-1.amazonaws.com/blog</a> (Use your actual public DNS name). This should trigger the WordPress configuration process.</p>
<h4>Step 8: Map IP Address and Domain Name</h4>
<p>To use your blog in production, you will have to:</p>
<ol>
<li>Associate an IP address to your instance</li>
<li>Map your domain name to that IP address</li>
</ol>
<p>To associate an IP address to your instance:</p>
<ol>
<li>In the AWS Management Console, click Elastic IPs (left navigation bar)</li>
<li>Click Allocate New Address, and confirm by clicking the &#8220;Yes, Allocate&#8221; button</li>
<li>Right-click the newly allocated IP address and select &#8220;Associate&#8221; in the popup menu. Select the instance you just created and click &#8220;Yes, Associate&#8221;</li>
</ol>
<p>To map your domain name to your IP address, you will have to use the tools provided by your domain registrar. If you use GoDaddy, specify NS73.DOMAINCONTROL.COM and NS74.DOMAINCONTROL.COM as the name servers for your domain, and use the DNS Manager to modify the A record and point to your IP address. Documentation is available <a href="http://help.godaddy.com/article/680">here</a>.</p>
<p>Once everything is configured and mapped correctly, access the General Settings in the WordPress management console and make sure the WordPress Address and Site Address are specified correctly using your domain name as in the screenshot below.<br />
<a href="http://coenraets.org/blog/wp-content/uploads/2012/01/wp-settings.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2012/01/wp-settings.jpg" alt="" title="wp-settings" width="550" height="240" class="alignnone size-full wp-image-2742" /></a></p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Setting Up WordPress on Amazon EC2 in 5 minutes http://coenraets.org/blog/?p=2672" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2012%2F01%2Fsetting-up-wordpress-on-amazon-ec2-in-5-minutes%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/01/setting-up-wordpress-on-amazon-ec2-in-5-minutes/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Tutorial: HTML Templates with Mustache.js</title>
		<link>http://coenraets.org/blog/2011/12/tutorial-html-templates-with-mustache-js/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tutorial-html-templates-with-mustache-js</link>
		<comments>http://coenraets.org/blog/2011/12/tutorial-html-templates-with-mustache-js/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 15:53:43 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Mustache.js]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2658</guid>
		<description><![CDATA[} When developing modern HTML applications, you often write a lot of HTML fragments programmatically. You concatenate HTML tags and dynamic data, and insert the resulting UI markup into the DOM. Here is a random code example of this approach: The proliferation of this kind of code throughout your application comes with some downsides. The [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Tutorial: HTML Templates with Mustache.js http://coenraets.org/blog/?p=2660" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Ftutorial-html-templates-with-mustache-js%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p><span  style="color:black;-webkit-transform: rotate(-90deg);-moz-transform: rotate(-90deg);display: block;font-size: 250px;font-family: Georgia;text-align: center;margin: 40px;">}</span></p>
<p>When developing modern HTML applications, you often write a lot of HTML fragments programmatically. You concatenate HTML tags and dynamic data, and insert the resulting UI markup into the DOM. Here is a random code example of this approach:</p>
<pre class="brush: jscript; title: ; notranslate">
$.each(messages.reverse(), function(index, message) {
	$('#messageList').append(
		'&lt;li&gt;&lt;span class=&quot;list-title&quot;&gt;' +
		message.userName + '&lt;/span&gt;' +
		'&lt;abbr class=&quot;list-timestamp&quot; title=&quot;' +
		message.datePosted + '&quot;&gt;&lt;/abbr&gt;' +
		'&lt;p class=&quot;list-text&quot;&gt;' + message.messageText + '&lt;/p&gt;&lt;/li&gt;');
	}
});
</pre>
<p>The proliferation of this kind of code throughout your application comes with some downsides. The tight coupling of UI and data logic doesn&#8217;t promote separation of concerns and reuse. It makes your application harder to write and harder to maintain.<br />
<span id="more-2660"></span><br />
HTML templates address this issue by decoupling the UI definition (HTML markup) from the data. There are a number of HTML template solutions out there: jQuery Templates, Underscore.js, and <a href="https://github.com/janl/mustache.js">Mustache.js</a> to name a few. Mustache.js is a popular choice because of its powerful syntax and fast rendering.</p>
<p><a href="http://mustache.github.com/">Mustache</a> is a &#8220;logic-less&#8221; template syntax. &#8220;Logic-less&#8221; means that it doesn&#8217;t rely on procedural statements (if, else, for, etc.): Mustache templates are entirely defined with tags. Mustache is implemented in different languages: Ruby, JavaScript, Python, PHP, Perl, Objective-C, Java, .NET, Android, C++, Go, Lua, Scala, etc. <a href="https://github.com/janl/mustache.js">Mustache.js</a> is the JavaScript implementation.</p>
<p>In this article, we take a quick tour of some of the capabilities of Mustache.js.</p>
<p>To start using Mustache.js, simply add a script tag to your html file pointing to mustache.js which is available <a href="https://github.com/janl/mustache.js/blob/master/mustache.js">here</a>.</p>
<p>You can run all the examples below <a href="http://coenraets.org/tutorials/mustache">here</a>.</p>
<h4>Sample 1: Basic Template</h4>
<p>This is a self-explanatory example. Note that:</p>
<ul>
<li>Instead of being defined in a variable, the data often comes from a service call (see sample 2)</li>
<li>Instead of being defined in a variable, the template is often read from a file (see sample 3)</li>
</ul>
<pre class="brush: jscript; title: ; notranslate">
	var person = {
		firstName: &quot;Christophe&quot;,
		lastName: &quot;Coenraets&quot;,
		blogURL: &quot;http://coenraets.org&quot;
	};
	var template = &quot;&lt;h1&gt;{{firstName}} {{lastName}}&lt;/h1&gt;Blog: {{blogURL}}&quot;;
	var html = Mustache.to_html(template, person);
	$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample1" style='border: solid 1px #ddd;background-color:#ddd;'>
<h1>Christophe Coenraets</h1>
<p>Blog: http://coenraets.org</p></div>
<p>&nbsp;</p>
<h4>Sample 2: Basic Template using Ajax data</h4>
<p>Same as sample 1, except that we get the data from an Ajax service call.</p>
<pre class="brush: jscript; title: ; notranslate">
$.getJSON('json/data.json', function(data) {
	var template = &quot;&lt;h1&gt;{{firstName}} {{lastName}}&lt;/h1&gt;Blog: {{blogURL}}&quot;;
	var html = Mustache.to_html(template, data);
	$('#sampleArea').html(html);
});
</pre>
<p>Result:</p>
<div id="sample2" style='border: solid 1px #ddd;background-color:#ddd;'>
<h1>John Smith</h1>
<p>Blog: http://johnsmith.com</p></div>
<p>&nbsp;</p>
<h4>Sample 3: Externalized Template</h4>
<p>Same as sample 2, except that we read the template from the main HTML file.</p>
<pre class="brush: jscript; title: ; notranslate">
$.getJSON('json/data2.json', function(data) {
	var template = $('#personTpl').html();
	var html = Mustache.to_html(template, data);
	$('#sampleArea').html(html);
});
</pre>
<p>The template is defined as follows in index.html:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script id=&quot;personTpl&quot; type=&quot;text/template&quot;&gt;
&lt;h1&gt;{{firstName}} {{lastName}}&lt;/h1&gt;
&lt;p&gt;Blog URL: &lt;a href=&quot;{{blogURL}}&quot;&gt;{{blogURL}}&lt;/a&gt;&lt;/p&gt;
&lt;/script&gt;
</pre>
<p>Result:</p>
<div id="sample3" style='border: solid 1px #ddd;background-color:#ddd;'>
<h1>Lisa Jones</h1>
<p>Blog URL: <a href="http://lisajones.com">http://lisajones.com</a></p>
</div>
<p>&nbsp;</p>
<p><strong>NOTE:</strong> Sample 3 represents the way templates are being used in many dynamic Web applications:</p>
<ul>
<li>You get data from an Ajax service</li>
<li>You read the template from an external file
</ul>
<p>In the remaining of this article, we declare the data and the template in variables to keep the examples self-contained. Remember to refer to sample 3 for a traditional setup when using templates in a dynamic Web application.</p>
<p>&nbsp;</p>
<h4>Sample 4: Enumerable Section</h4>
<pre class="brush: jscript; title: ; notranslate">
var data = {name: &quot;John Smith&quot;, skills: ['JavaScript', 'PHP', 'Java']};
var tpl = &quot;{{name}} skills:&lt;ul&gt;{{#skills}}&lt;li&gt;{{.}}&lt;/li&gt;{{/skills}}&lt;/ul&gt;&quot;;
var html = Mustache.to_html(tpl, data);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample4" style='border: solid 1px #ddd;background-color:#ddd;'>John Smith skills:
<ul>
<li>JavaScript</li>
<li>PHP</li>
<li>Java</li>
</ul>
</div>
<p>&nbsp;</p>
<h4>Sample 5: Enumerable Section with Objects</h4>
<pre class="brush: jscript; title: ; notranslate">
var data = {
	employees: [
	{	firstName: &quot;Christophe&quot;,
		lastName: &quot;Coenraets&quot;},
	{	firstName: &quot;John&quot;,
		lastName: &quot;Smith&quot;}
	]};
var template = &quot;Employees:&lt;ul&gt;{{#employees}}&quot; +
                            &quot;&lt;li&gt;{{firstName}} {{lastName}}&lt;/li&gt;&quot; +
                            &quot;{{/employees}}&lt;/ul&gt;&quot;;
var html = Mustache.to_html(template, data);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample5" style='border: solid 1px #ddd;background-color:#ddd;'>Employees:
<ul>
<li>Christophe Coenraets</li>
<li>John Smith</li>
</ul>
</div>
<p>&nbsp;</p>
<h4>Sample 6: Nested Objects</h4>
<p>You can use the dot notation to access object properties.</p>
<pre class="brush: jscript; title: ; notranslate">
var person = {
	firstName: &quot;Christophe&quot;,
	lastName: &quot;Coenraets&quot;,
	blogURL: &quot;http://coenraets.org&quot;,
	manager : {
		firstName: &quot;John&quot;,
		lastName: &quot;Smith&quot;
	}
};
var template = &quot;&lt;h1&gt;{{firstName}} {{lastName}}&lt;/h1&gt;&lt;p&gt;{{blogURL}}&lt;/p&gt;&quot; +
               &quot;Manager: {{manager.firstName}} {{manager.lastName}}&quot;;
var html = Mustache.to_html(template, person);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample6" style='border: solid 1px #ddd;background-color:#ddd;'>
<h1>Christophe Coenraets</h1>
<p>http://coenraets.org</p>
<p>Manager: John Smith</p></div>
<p>&nbsp;</p>
<h4>Sample 7: Dereferencing</h4>
<p>Same as sample 6, except that we &#8220;dereference&#8221; the manager object to make it easier to access its properties (without having to use the dot notation).</p>
<pre class="brush: jscript; title: ; notranslate">
var person = {
	firstName: &quot;John&quot;,
	lastName: &quot;Smith&quot;,
	blogURL: &quot;http://johnsmith.com&quot;,
	manager : {
		firstName: &quot;Lisa&quot;,
		lastName: &quot;Jones&quot;
	}
};
var tpl = &quot;&lt;h1&gt;{{firstName}} {{lastName}}&lt;/h1&gt;&lt;p&gt;{{blogURL}}&lt;/p&gt;&quot; +
          &quot;{{#manager}}Manager: {{firstName}} {{lastName}}{{/manager}}&quot;;
var html = Mustache.to_html(tpl, person);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample7" style='border: solid 1px #ddd;background-color:#ddd;'>
<h1>John Smith</h1>
<p>http://johnsmith.com</p>
<p>Manager: Lisa Jones</p></div>
<p>&nbsp;</p>
<h4>Sample 8: Function</h4>
<p>Templates can reference functions like totalPrice in this example.</p>
<pre class="brush: jscript; title: ; notranslate">
var product = {
	name: &quot;FooBar&quot;,
	price: 100,
	salesTax: 0.05,
	totalPrice: function() {
		return this.price + this.price * this.salesTax;
	}
};
var template = &quot;&lt;p&gt;Product Name: {{name}}&lt;/p&gt;Price: {{totalPrice}}&quot;;
var html = Mustache.to_html(template, product);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample8" style='border: solid 1px #ddd;background-color:#ddd;'>
<p>Product Name: FooBar</p>
<p>Price: 105</p></div>
<p>&nbsp;</p>
<h4>Sample 9: Condition</h4>
<p>Templates can include conditional sections. Conditional sections only render if the condition evaluates to true. A conditional section begins with {{#condition}} and ends with {{/condition}}. &#8220;condition&#8221; can be a boolean value or a function returning a boolean.</p>
<pre class="brush: jscript; title: ; notranslate">
var data = {
	employees: [
	{	firstName: &quot;Christophe&quot;,
		lastName: &quot;Coenraets&quot;,
		fullTime: true,
		phone: &quot;617-123-4567&quot;
	},
	{	firstName: &quot;John&quot;,
		lastName: &quot;Smith&quot;,
		fullTime: false,
		phone: &quot;617-987-6543&quot;
	},
	{	firstName: &quot;Lisa&quot;,
		lastName: &quot;Jones&quot;,
		fullTime: true,
		phone: &quot;617-111-2323&quot;
	},
	]};
var tpl = &quot;Employees:&lt;ul&gt;{{#employees}}&lt;li&gt;{{firstName}} {{lastName}}&quot; +
          &quot;{{#fullTime}} {{phone}}{{/fullTime}}&lt;/li&gt;{{/employees}}&lt;/ul&gt;&quot;;
var html = Mustache.to_html(tpl, data);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample9" style='border: solid 1px #ddd;background-color:#ddd;'>Employees:
<ul>
<li>Christophe Coenraets 617-123-4567</li>
<li>John Smith</li>
<li>Lisa Jones 617-111-2323</li>
</ul>
</div>
<p>&nbsp;</p>
<h4>Sample 10: Partials</h4>
<pre class="brush: jscript; title: ; notranslate">
var data = {
	firstName: &quot;Christophe&quot;,
	lastName: &quot;Coenraets&quot;,
	address: &quot;1 Main street&quot;,
	city: &quot;Boston&quot;,
	state: &quot;MA&quot;,
	zip: &quot;02106&quot;
};

var template = &quot;&lt;h1&gt;{{firstName}} {{lastName}}&lt;/h1&gt;{{&gt;address}}&quot;;
var partials = {address: &quot;&lt;p&gt;{{address}}&lt;/p&gt;{{city}}, {{state}} {{zip}}&quot;};
var html = Mustache.to_html(template, data, partials);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample10" style='border: solid 1px #ddd;background-color:#ddd;'>
<h1>Christophe Coenraets</h1>
<p>1 Main street</p>
<p>Boston, MA 02106</p></div>
<p>&nbsp;</p>
<h4>Sample 11: Partials in Enumerable Section</h4>
<pre class="brush: jscript; title: ; notranslate">
var data = { depts: [
	{	name: &quot;Engineering&quot;,
		employees: [
			{firstName: &quot;Christophe&quot;, lastName: &quot;Coenraets&quot;},
			{firstName: &quot;John&quot;, lastName: &quot;Smith&quot;}]
	},
	{	name: &quot;Sales&quot;,
		employees: [
			{firstName: &quot;Paula&quot;, lastName: &quot;Taylor&quot;},
			{firstName: &quot;Lisa&quot;, lastName: &quot;Jones&quot;}]
	}]
};

var tpl = &quot;{{#depts}}&lt;h1&gt;{{name}}&lt;/h1&gt;&quot; +
          &quot;&lt;ul&gt;{{#employees}}{{&gt;employee}}{{/employees}}&lt;/ul&gt;{{/depts}}&quot;;
var partials = {employee: &quot;&lt;li&gt;{{firstName}} {{lastName}}&lt;/li&gt;&quot;};
var html = Mustache.to_html(tpl, data, partials);
$('#sampleArea').html(html);
</pre>
<p>Result:</p>
<div id="sample11" style='border: solid 1px #ddd;background-color:#ddd;'>
<h1>Engineering</h1>
<ul>
<li>Christophe Coenraets</li>
<li>John Smith</li>
</ul>
<h1>Sales</h1>
<ul>
<li>Paula Taylor</li>
<li>Lisa Jones</li>
</ul>
</div>
<p>&nbsp;</p>
<p>You can run all the examples <a href="http://coenraets.org/tutorials/mustache">here</a>.</p>
<p>&nbsp;</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Tutorial: HTML Templates with Mustache.js http://coenraets.org/blog/?p=2660" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Ftutorial-html-templates-with-mustache-js%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/tutorial-html-templates-with-mustache-js/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Fact Check Michele Bachmann with Politifact and Flex</title>
		<link>http://coenraets.org/blog/2011/12/fact-check-michele-bachmann-with-politifact-and-flex/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fact-check-michele-bachmann-with-politifact-and-flex</link>
		<comments>http://coenraets.org/blog/2011/12/fact-check-michele-bachmann-with-politifact-and-flex/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 18:02:03 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2629</guid>
		<description><![CDATA[During the GOP presidential debate last night, Michelle Bachmann said this: After the debate that we had last week, Politifact came out and said that everything I said was true. Did Politifact really give her a &#8220;True&#8221; rating across the board for a performance in the previous debate? The best way to check if you [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Fact Check Michele Bachmann with Politifact and Flex http://coenraets.org/blog/?p=2629" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Ffact-check-michele-bachmann-with-politifact-and-flex%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p>During the GOP presidential debate last night, Michelle Bachmann said this:</p>
<blockquote><p>After the debate that we had last week, Politifact came out and said that everything I said was true.</p></blockquote>
<p>Did Politifact really give her a &#8220;True&#8221; rating across the board for a performance in the previous debate?</p>
<p>The best way to check if you are on the go, is to use Politifact’s mobile application which was built with Flex and runs on the iPhone, the iPad, the BlackBerry PlayBook, the Kindle Fire, the Barnes and Noble Nook, and other Android devices&#8230; using the exact same code. 100% code reusability.<br />
<span id="more-2629"></span></p>
<div style='float:right'>
<a href="http://coenraets.org/blog/wp-content/uploads/2011/12/tom-true.gif"><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/tom-true.gif" alt="" title="tom-true" width="84" height="75" class="alignnone size-full wp-image-2641" /></a>
</div>
<p><strong>100% Code Reusability</strong><br />
I’ll let you check Michelle Bachmann statements in Politifact’s Mobile app, but since I helped build it, I can tell you that the 100% Flex code reusability across devices statement is absolutely “True”!</p>
<p>The Politifact Mobile application is available in the following app stores:</p>
<p><a href="http://itunes.apple.com/us/app/politifact-mobile/id444548650">Apple App Store</a><br />
<a href="https://market.android.com/details?id=air.com.tampabay.Politifact">Android Market</a><br />
<a href="http://www.amazon.com/Times-Publishing-Company-Politifact-Mobile/dp/B005FHP5K8">Amazon App Store</a><br />
<a href="http://appworld.blackberry.com/webstore/content/49265?lang=en">BlackBerry App World</a><br />
<a href="http://www.barnesandnoble.com/s/politifact-mobile?dref=6455">Barnes and Noble Nook Store</a></p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2011/12/photo1.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/photo1.jpg" alt="" title="photo" width="320" height="480" class="alignnone size-full wp-image-2656" /></a></p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Fact Check Michele Bachmann with Politifact and Flex http://coenraets.org/blog/?p=2629" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Ffact-check-michele-bachmann-with-politifact-and-flex%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/fact-check-michele-bachmann-with-politifact-and-flex/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mobile Development with Flex 4.6 and Spring</title>
		<link>http://coenraets.org/blog/2011/12/mobile-development-with-flex-4-6-and-spring/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mobile-development-with-flex-4-6-and-spring</link>
		<comments>http://coenraets.org/blog/2011/12/mobile-development-with-flex-4-6-and-spring/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 17:27:13 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2613</guid>
		<description><![CDATA[My Mobile Development with Flex 4.6 and Spring video (using the Spring BlazeDS Integration project) is available on Adobe TV. You can watch it here. The Flex Spring Mobile Test Drive is hosted on GitHub and documented here.
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Mobile Development with Flex 4.6 and Spring http://coenraets.org/blog/?p=2613" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Fmobile-development-with-flex-4-6-and-spring%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p>My Mobile Development with Flex 4.6 and Spring video (using the <a href="http://www.springsource.org/spring-flex">Spring BlazeDS Integration project</a>) is available on Adobe TV. You can watch it here.</p>
<p><iframe title="AdobeTV Video Player" width="640" height="400" src="http://tv.adobe.com/embed/64/11655/" frameborder="0" allowfullscreen scrolling="no"></iframe></p>
<p>The Flex Spring Mobile Test Drive is hosted on GitHub and documented <a href="http://coenraets.org/blog/2011/08/flex-spring-mobile-test-drive-learn-the-best-way-to-build-java-backed-ios-android-and-playbook-apps/">here</a>.</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Mobile Development with Flex 4.6 and Spring http://coenraets.org/blog/?p=2613" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Fmobile-development-with-flex-4-6-and-spring%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/mobile-development-with-flex-4-6-and-spring/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Backbone.js Wine Cellar Tutorial — Part 3: Deep Linking and Application States</title>
		<link>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states</link>
		<comments>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 21:04:53 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2555</guid>
		<description><![CDATA[UPDATE: I posted a &#8220;Postface&#8221; to this series with some lessons learned and an improved version of the app. Make sure you read it here. In Part 1 of this tutorial, we set up the basic infrastructure for the Wine Cellar application. In Part 2, we added the ability to create, update, and delete (CRUD) [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Backbone.js Wine Cellar Tutorial — Part 3: Deep Linking and Application States http://coenraets.org/blog/?p=2555" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Fbackbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE: I posted a &#8220;Postface&#8221; to this series with some lessons learned and an improved version of the app. Make sure you read it <a href="http://coenraets.org/blog/wp-admin/post.php?post=2810&#038;action=edit">here</a>.</strong></p>
<p>In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">Part 1</a> of this tutorial, we set up the basic infrastructure for the Wine Cellar application. In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">Part 2</a>, we added the ability to create, update, and delete (CRUD) wines.</p>
<p>There are a few remaining issues in the application. They are all related to &#8220;deep linking&#8221;. The application needs to continuously keep its URL in sync with its current state. This allows you to grab the URL from the address bar at any point in time during the course of the application, and re-use or share it to go back to the exact same state.</p>
<p>In this last installment of the tutorial, we add support for deep linking in the Wine Cellar application.<br />
<span id="more-2555"></span></p>
<h4>Problem 1: Linking to a specific wine</h4>
<p><strong>The problem</strong>: Select a specific wine from the list. The URL looks like this: http://www.coenraets.org/backbone-cellar/part2/#wines/<em>[id]</em>. Now do one of these two things:</p>
<ol>
<li>Grab that URL from the address bar and try to access it from another browser window or tab</li>
<li>Simply click your browser&#8217;s Refresh button</li>
</ol>
<p>You get an empty screen with no data. If you look at a debug console (for example, in Chrome&#8217;s Developer Tools), you&#8217;ll get this message:</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2011/12/chome-error.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/chome-error.jpg" alt="" title="chome-error" width="640" height="317" class="alignnone size-full wp-image-2580" /></a></p>
<p>Let&#8217;s take a look at what&#8217;s going on here:</p>
<pre class="brush: jscript; title: ; notranslate">
var AppRouter = Backbone.Router.extend({

	routes: {
		&quot;&quot;			: &quot;list&quot;,
		&quot;wines/:id&quot;	: &quot;wineDetails&quot;
	},

	list: function() {
    	this.wineList = new WineCollection();
    	this.wineListView = new WineListView({model: this.wineList});
		this.wineList.fetch();
  	},

	wineDetails: function(id) {
		this.wine = this.wineList.get(id);
		if (app.wineView) app.wineView.close();
   		this.wineView = new WineView({model: this.wine});
		this.wineView.render();
  	}

});
</pre>
<p>The problem is on line 15: we are assuming that a wine collection (this.wineList) already exists, and are trying to &#8220;get&#8221; a specific item from that list. That works well when we start the application with the default (&#8220;&#8221;) route. But this.wineList won&#8217;t exist if we start the application with the &#8220;wines/:id&#8221; route. There are different ways to address the issue:</p>
<p>We could modify the wineDetails function to fetch the requested item directly:</p>
<pre class="brush: jscript; title: ; notranslate">
	wineDetails: function(id) {
		this.wine = new Wine({id: id});
		this.wineView = new WineView({model: this.wine});
		this.wine.fetch();
  	}
</pre>
<p>That takes care of loading the wine details in the form, but the wine list remains empty when we start the application with &#8220;wines/:id&#8221; route. We could add the following line of code to load the list if it doesn&#8217;t exist:</p>
<pre class="brush: jscript; title: ; notranslate">
if (!this.wineList) this.list();
</pre>
<p>But now, the wine model that is part of the collection and the wine model fetched separately are two different objects, which means that data binding and View synchronization will not work as expected.</p>
<p>Another approach is to check if the collection exists in the wineDetails function. If it does, we simply &#8220;get&#8221; the requested item and render it as we did before. If it doesn&#8217;t, we store the requested id in a variable, and then invoke the existing list() function to populate the list. We then modify the list function: When we get the list from the server (on success), we check if there was a requested id. If there was, we invoke the wineDetails function to render the corresponding item.</p>
<pre class="brush: jscript; title: ; notranslate">
var AppRouter = Backbone.Router.extend({

	routes: {
		&quot;&quot;			: &quot;list&quot;,
		&quot;wines/:id&quot;	: &quot;wineDetails&quot;
	},

	list: function() {
    	this.wineList = new WineCollection();
		var self = this;
		this.wineList.fetch({
			success: function() {
		    	self.wineListView = new WineListView({model: self.wineList});
				self.wineListView.render();
				if (self.requestedId) self.wineDetails(self.requestedId);
			}
		});
  	},

	wineDetails: function(id) {
		if (this.wineList)
		{
			this.wine = this.wineList.get(id);
			if (this.wineView) this.wineView.close();
		    		this.wineView = new WineView({model: this.wine});
			this.wineView.render();
		} else {
			this.requestedId = id;
			this.list();
		}
  	}
});
</pre>
<p>&nbsp;</p>
<h4>Problem 2: Updating the URL after a wine is created</h4>
<p><strong>The problem</strong>: Add a new Wine, and click Save. The id that has been assigned to the newly created wine appears in the form field. However the URL is still:<br />
http://localhost/backbone-cellar/part2/ when it should really be: http://localhost/backbone-cellar/part2/#wines/<em>[id]</em>.</p>
<p>You can easily fix that issue by using the router&#8217;s navigate function to change the URL. The second argument (false), indicates that we actually don&#8217;t want to &#8220;execute&#8221; that route: we just want to change the URL.</p>
<pre class="brush: jscript; title: ; notranslate">
if (this.model.isNew()) {
	var self = this;
	app.wineList.create(this.model, {
		success: function() {
			app.navigate('wines/'+self.model.id, false);
		}
	});
} else {
	this.model.save();
}
</pre>
<p>&nbsp;</p>
<h4>Problem 3: Updating the URL while creating a new wine</h4>
<p><strong>The problem</strong>: Select a wine in the list. The URL looks like this: http://localhost/backbone-cellar/part2/#wines/<em>[id]</em></p>
<p>Now, click the &#8220;Add Wine&#8221; button. You get an empty form to enter a new wine, but notice that the URL is still unchanged (http://localhost/backbone-cellar/part2/#wines/<em>[id]</em>). In other words, it doesn&#8217;t reflect the current state of the application.</p>
<p>In this case, we are going to add a new &#8220;route&#8221;:</p>
<pre class="brush: jscript; title: ; notranslate">
	routes: {
		&quot;&quot;			: &quot;list&quot;,
		&quot;wines/new&quot;	: &quot;newWine&quot;,
		&quot;wines/:id&quot;	: &quot;wineDetails&quot;
	},
</pre>
<p>The router&#8217;s newWine method is implemented as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
	newWine: function() {
		console.log('MyRouter newWine');
		if (app.wineView) app.wineView.close();
		app.wineView = new WineView({model: new Wine()});
		app.wineView.render();
	}
</pre>
<p>And we can change the HeaderView newWine() method as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
newWine: function(event) {
	app.navigate(&quot;wines/new&quot;, true);
	return false;
}
</pre>
<p>&nbsp;</p>
<h4>Putting it all together</h4>
<p>You can run the application (Part 3) <a href="http://coenraets.org/backbone-cellar/part3">here</a>. The create/update/delete features are disabled in this online version. Use the link at the bottom of this post to download a fully enabled version.</p>
<p>Here is the final version of the code:</p>
<pre class="brush: jscript; title: ; notranslate">
window.Wine = Backbone.Model.extend({
	urlRoot: &quot;api/wines&quot;,
	defaults: {
		&quot;id&quot;: null,
	    &quot;name&quot;:  &quot;&quot;,
	    &quot;grapes&quot;:  &quot;&quot;,
	    &quot;country&quot;:  &quot;USA&quot;,
	    &quot;region&quot;:  &quot;California&quot;,
	    &quot;year&quot;:  &quot;&quot;,
	    &quot;description&quot;:  &quot;&quot;,
	    &quot;picture&quot;:  &quot;&quot;
	  }
});

window.WineCollection = Backbone.Collection.extend({
	model: Wine,
	url: &quot;api/wines&quot;
});

window.WineListView = Backbone.View.extend({

	el: $('#wineList'),

    initialize: function() {
		this.model.bind(&quot;reset&quot;, this.render, this);
		this.model.bind(&quot;add&quot;, function(wine) {
			$('#wineList').append(new WineListItemView({model: wine}).render().el);
		});
    },

    render: function(eventName) {
		_.each(this.model.models, function(wine) {
            $(this.el).append(new WineListItemView({model: wine}).render().el);
		}, this);
		return this;
    }
});

window.WineListItemView = Backbone.View.extend({

	tagName: &quot;li&quot;,

	template: _.template($('#wine-list-item').html()),

    initialize: function() {
		this.model.bind(&quot;change&quot;, this.render, this);
		this.model.bind(&quot;destroy&quot;, this.close, this);
    },

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    },

	close: function() {
		$(this.el).unbind();
		$(this.el).remove();
	}
});

window.WineView = Backbone.View.extend({

    el: $('#mainArea'),

	template: _.template($('#wine-details').html()),

    initialize: function() {
		this.model.bind(&quot;change&quot;, this.render, this);
    },

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    },

    events: {
        &quot;change input&quot;: &quot;change&quot;,
		&quot;click .save&quot;: &quot;saveWine&quot;,
		&quot;click .delete&quot;: &quot;deleteWine&quot;
    },

    change: function(event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
		// You could change your model on the spot, like this:
        // var change = {};
        // change[target.name] = target.value;
        // this.model.set(change);
    },

	saveWine: function() {
		this.model.set({
			name: $('#name').val(),
			grapes: $('#grapes').val(),
			country: $('#country').val(),
			region: $('#region').val(),
			year: $('#year').val(),
			description: $('#description').val()
		});
		if (this.model.isNew()) {
			var self = this;
			app.wineList.create(this.model, {
				success: function() {
					app.navigate('wines/'+self.model.id, false);
				}
			});
		} else {
			this.model.save();
		}

		return false;
	},

	deleteWine: function() {
		this.model.destroy({
			success: function() {
				alert('Wine deleted successfully');
				window.history.back();
			}
		});
		return false;
	},

	close: function() {
		$(this.el).unbind();
		$(this.el).empty();
	}
});

window.HeaderView = Backbone.View.extend({

	el: $('.header'),

	template: _.template($('#header').html()),

    initialize: function() {
		this.render();
    },

    render: function(eventName) {
		$(this.el).html(this.template());
		return this;
    },

    events: {
		&quot;click .new&quot;: &quot;newWine&quot;
    },

	newWine: function(event) {
		app.navigate(&quot;wines/new&quot;, true);
		return false;
	}
});

var AppRouter = Backbone.Router.extend({

	routes: {
		&quot;&quot;			: &quot;list&quot;,
		&quot;wines/new&quot;	: &quot;newWine&quot;,
		&quot;wines/:id&quot;	: &quot;wineDetails&quot;
	},

	list: function() {
    	this.wineList = new WineCollection();
		var self = this;
		this.wineList.fetch({
			success: function() {
		    	self.wineListView = new WineListView({model: self.wineList});
				self.wineListView.render();
				if (self.requestedId) self.wineDetails(self.requestedId);
			}
		});
  	},

	wineDetails: function(id) {
		if (this.wineList)
		{
			this.wine = this.wineList.get(id);
			if (this.wineView) this.wineView.close();
		    		this.wineView = new WineView({model: this.wine});
			this.wineView.render();
		} else {
			this.requestedId = id;
			this.list();
		}
  	},

	newWine: function() {
		if (app.wineView) app.wineView.close();
		app.wineView = new WineView({model: new Wine()});
		app.wineView.render();
	}

});

var app = new AppRouter();
Backbone.history.start();
var header = new HeaderView();
</pre>
<p>&nbsp;</p>
<h3>Download</h3>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/backbone-cellar">here</a> (see part3). And <a href="https://github.com/ccoenraets/backbone-cellar/zipball/master">here</a> is a quick link to the download.</p>
<p>You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download. </p>
<p><strong>UPDATE (1/11/2012):</strong> A version of this application with a Java back-end (using JAX-RS and Jersey) is also available on GitHub <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>. You can find more information on the Java version of this application <a href="http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/">here</a>.</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Backbone.js Wine Cellar Tutorial — Part 3: Deep Linking and Application States http://coenraets.org/blog/?p=2555" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Fbackbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Backbone.js Wine Cellar Tutorial — Part 2: CRUD</title>
		<link>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=backbone-js-wine-cellar-tutorial-part-2-crud</link>
		<comments>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 16:52:01 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2483</guid>
		<description><![CDATA[In Part 1 of this tutorial, we set up the basic infrastructure for the Wine Cellar application. The application so far is read-only: it allows you to retrieve a list of wines, and display the details of the wine you select. In this second installment, we will add the ability to create, update, and delete [...]
	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Backbone.js Wine Cellar Tutorial — Part 2: CRUD http://coenraets.org/blog/?p=2483" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Fbackbone-js-wine-cellar-tutorial-part-2-crud%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">Part 1</a> of this tutorial, we set up the basic infrastructure for the Wine Cellar application. The application so far is read-only: it allows you to retrieve a list of wines, and display the details of the wine you select.</p>
<p>In this second installment, we will add the ability to create, update, and delete (CRUD) wines.</p>
<h4>RESTful Services</h4>
<p>As mentioned in Part 1, <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> provides a natural and elegant integration with RESTful services. If your back-end data is exposed through a pure RESTful API, retrieving (GET), creating (POST), updating (PUT), and deleting (DELETE) models is incredibly easy using the Backbone.js simple Model API.</p>
<p>This tutorial uses pure RESTful services. The services are implemented as follows:</p>
<table style="border-collapse:collapse;margin-bottom:20px;">
<tr>
<th style="padding:4px;border: 1px solid #666666;width:150px;">HTTP Method</th>
<th style="padding:4px;border: 1px solid #666666;width:150px;">URL</th>
<th style="padding:4px;border: 1px solid #666666;width:300px;">Action</th>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Retrieve all wines</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10
<td style="padding:4px;border: 1px solid #666666;">Retrieve wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">POST</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Add a new wine</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">PUT</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Update wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">DELETE</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Delete wine with id == 10</td>
</tr>
</table>
<p><span id="more-2483"></span><br />
A PHP version of these services (using the <a href="http://www.slimframework.com/">Slim framework</a>) is available as part of the download. A similar Java version of the API (using JAX-RS) is available as part of <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/">this post</a>.</p>
<p><strong>Using Backbone.js with non-RESTful Services</strong></p>
<p>If your persistence layer is not available through RESTful services, you can override Backbone.sync. From the documentation:</p>
<p><em>&#8220;Backbone.sync is the function that Backbone calls every time it attempts to read or save a model to the server. By default, it uses (jQuery/Zepto).ajax to make a RESTful JSON request. You can override it in order to use a different persistence strategy, such as WebSockets, XML transport, or Local Storage.&#8221;</em></p>
<p>Using non-RESTful services is not discussed in this tutorial. See the <a href="http://documentcloud.github.com/backbone/">documentation</a> for more information.</p>
<h3>Part 2: Adding Create, Update, Delete</h3>
<p>You can run the application (Part 2) <a href="http://coenraets.org/backbone-cellar/part2">here</a>. The create/update/delete features are disabled in this online version. Use the link at the bottom of this post to download a fully enabled version.</p>
<p>Here is the code for the improved version of the applications. Key changes are discussed below.</p>
<pre class="brush: jscript; title: ; notranslate">
window.Wine = Backbone.Model.extend({
	urlRoot: &quot;api/wines&quot;,
	defaults: {
		&quot;id&quot;: null,
	    &quot;name&quot;:  &quot;&quot;,
	    &quot;grapes&quot;:  &quot;&quot;,
	    &quot;country&quot;:  &quot;USA&quot;,
	    &quot;region&quot;:  &quot;California&quot;,
	    &quot;year&quot;:  &quot;&quot;,
	    &quot;description&quot;:  &quot;&quot;,
	    &quot;picture&quot;:  &quot;&quot;
	  }
});

window.WineCollection = Backbone.Collection.extend({
	model: Wine,
	url: &quot;api/wines&quot;
});

window.WineListView = Backbone.View.extend({

	el: $('#wineList'),

    initialize: function() {
		this.model.bind(&quot;reset&quot;, this.render, this);
		this.model.bind(&quot;add&quot;, function(wine) {
			$('#wineList').append(new WineListItemView({model: wine}).render().el);
		});
    },

    render: function(eventName) {
		_.each(this.model.models, function(wine) {
            $(this.el).append(new WineListItemView({model: wine}).render().el);
		}, this);
		return this;
    }
});

window.WineListItemView = Backbone.View.extend({

	tagName: &quot;li&quot;,

	template: _.template($('#wine-list-item').html()),

    initialize: function() {
		this.model.bind(&quot;change&quot;, this.render, this);
		this.model.bind(&quot;destroy&quot;, this.close, this);
    },

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    },

	close: function() {
		$(this.el).unbind();
		$(this.el).remove();
	}
});

window.WineView = Backbone.View.extend({

    el: $('#mainArea'),

	template: _.template($('#wine-details').html()),

    initialize: function() {
		this.model.bind(&quot;change&quot;, this.render, this);
    },

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    },

    events: {
        &quot;change input&quot;: &quot;change&quot;,
		&quot;click .save&quot;: &quot;saveWine&quot;,
		&quot;click .delete&quot;: &quot;deleteWine&quot;
    },

    change: function(event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
		// You could change your model on the spot, like this:
        // var change = {};
        // change[target.name] = target.value;
        // this.model.set(change);
    },

	saveWine: function() {
		this.model.set({
			name: $('#name').val(),
			grapes: $('#grapes').val(),
			country: $('#country').val(),
			region: $('#region').val(),
			year: $('#year').val(),
			description: $('#description').val()
		});
		if (this.model.isNew()) {
			app.wineList.create(this.model);
		} else {
			this.model.save();
		}
		return false;
	},

	deleteWine: function() {
		this.model.destroy({
			success: function() {
				alert('Wine deleted successfully');
				window.history.back();
			}
		});
		return false;
	},

	close: function() {
		$(this.el).unbind();
		$(this.el).empty();
	}
});

window.HeaderView = Backbone.View.extend({

	el: $('.header'),

	template: _.template($('#header').html()),

    initialize: function() {
		this.render();
    },

    render: function(eventName) {
		$(this.el).html(this.template());
		return this;
    },

    events: {
		&quot;click .new&quot;: &quot;newWine&quot;
    },

    newWine: function(event) {
		if (app.wineView) app.wineView.close();
		app.wineView = new WineView({model: new Wine()});
		app.wineView.render();
		return false;
	}
});

var AppRouter = Backbone.Router.extend({

	routes: {
		&quot;&quot;			: &quot;list&quot;,
		&quot;wines/:id&quot;	: &quot;wineDetails&quot;
	},

	list: function() {
    	this.wineList = new WineCollection();
    	this.wineListView = new WineListView({model: this.wineList});
		this.wineList.fetch();
  	},

	wineDetails: function(id) {
		this.wine = this.wineList.get(id);
		if (app.wineView) app.wineView.close();
   		this.wineView = new WineView({model: this.wine});
		this.wineView.render();
  	}

});

var app = new AppRouter();
Backbone.history.start();
var header = new HeaderView();
</pre>
<h4>Wine</h4>
<p>Two attributes were added to the Wine Model:</p>
<ul>
<li><strong>urlRoot</strong>: RESTful service endpoint to retrieve or persist Model data. Note that this attribute is only needed when retrieving/persisting Models that are not part of a Collection. If the Model is part of a Collection, the <strong>url</strong> attribute defined in the Collection is enough for Backbone.js to know how to retrieve, update, or delete data using your RESTful API.</li>
<li><strong>defaults</strong>: Default values used when a new instance of the model is created. This attribute is optional. However, it was required in this application for the wine-details template to render an &#8216;empty&#8217; wine model object (which happens when adding a new wine).</li>
</ul>
<h4>WineListView</h4>
<p>When a new wine is added, you want it to automatically appear in the list. To make that happen, you bind the View to the <strong>add</strong> event of the WineListView model (which is the collection of wines). When that event is fired, a new instance of WineListItemView is created and added to the list.</p>
<h4>WineListItemView</h4>
<p>When a wine is changed, you want the corresponding WineListItemView to re-render automatically to reflect the change. To make that happen, you bind the View to the <strong>change</strong> event of its model, and execute the render function when the event is fired.</p>
<p>Similarly, when a wine is deleted, you want the list item to be removed automatically. To make that happen, you bind the view to the <strong>destroy</strong> event of its model and execute our custom close function when the event is fired. To <strong>avoid memory leaks and events firing multiple times</strong>, it is important to unbind the event listeners before removing the list item from the DOM.</p>
<p>Note that in either case we don&#8217;t have the overhead of re-rendering the entire list: we only re-render or remove the list item affected by the change.</p>
<h4>WineView</h4>
<p>In the spirit of encapsulation, the event handlers for the Save and Delete buttons are defined inside WineView, as opposed to defining them as free-hanging code blocks outside the &#8220;class&#8221; definitions. You use the Backbone.js Events syntax which uses jQuery delegate mechanism behind the scenes.</p>
<p>There are always different approaches to update the model based on user input in a form:</p>
<ul>
<li>&#8220;Real time&#8221; approach: you use the change handler to update the model as changes are made in the form. This is in essence bi-directional data binding: the model and the UI controls are always in sync. Using this approach, you can then choose between sending changes to the server in real time (implicit save), or wait until the user clicks a Save button (explicit save). The first option can be chatty and unpractical when there are cross-field validation rules. The second option may require you to undo model changes if the user navigates to another item without clicking Save.</li>
<li>&#8220;Delayed&#8221; approach: You wait until the user clicks Save to update the model based on the new values in UI controls, and then send the changes to the server.</li>
</ul>
<p>This discussion is not specific to Backbone.js and is therefore beyond the scope of this post. For simplicity, I used the delayed approach here. However I still wired the <strong>change</strong> event, and use it to log changes to the console. I found this very useful when debugging the application, and particularly to make sure I had cleaned up my bindings (see close function): I you see the change event firing multiple times, you probably didn&#8217;t clean up as appropriate.</p>
<h4>HeaderView</h4>
<p>Backbone.js Views are typically used to render domain models (as done in WineListView, WineListItemView, and Wine View). But they can also be used to create composite UI components. For example, in this application, we define a Header View (a toolbar) that could be made of different components and that encapsulates its own logic.</p>
<h3>Download</h3>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/backbone-cellar">here</a> (see part2). And <a href="https://github.com/ccoenraets/backbone-cellar/zipball/master">here</a> is a quick link to the download.</p>
<p>You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download. </p>
<p><strong>UPDATE (1/11/2012):</strong> A version of this application with a Java back-end (using JAX-RS and Jersey) is also available on GitHub <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>. You can find more information on the Java version of this application <a href="http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/">here</a>.</p>
<h3>What&#8217;s Next?</h3>
<p>The application so far doesn&#8217;t support deep-linking. For example, select a wine in the list, grab the URL in the address bar and paste it in another browser window: it doesn&#8217;t work. In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/">Part 3</a>, we will add complete support for deep linking.</p>

	
<!-- Start WP Socializer Plugin - Retweet Button -->
<a href="http://twitter.com/?status=RT @ Backbone.js Wine Cellar Tutorial — Part 2: CRUD http://coenraets.org/blog/?p=2483" target="_blank">Retweet this</a>
<!-- End WP Socializer Plugin - Retweet Button -->

	
	
<!-- Start WP Socializer Plugin - Facebook Button -->
<a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fcoenraets.org%2Fblog%2F2011%2F12%2Fbackbone-js-wine-cellar-tutorial-part-2-crud%2F" target="_blank">Share on Facebook</a>
<!-- End WP Socializer Plugin - Facebook Button -->



Follow @ccoenraets
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

