diff options
author | Thomas Davis <thomasalwyndavis@gmail.com> | 2014-11-14 09:02:55 +1000 |
---|---|---|
committer | Thomas Davis <thomasalwyndavis@gmail.com> | 2014-11-14 09:02:55 +1000 |
commit | 5fe3d858830a88dbcd54fd53ff08f225e48e45cc (patch) | |
tree | 8cd27c5b65f460f83f40f458d1392797aacb8231 | |
parent | 3d6bba78f9c0799f88b710809090770f53f3bb75 (diff) | |
download | backbonetutorials-5fe3d858830a88dbcd54fd53ff08f225e48e45cc.zip backbonetutorials-5fe3d858830a88dbcd54fd53ff08f225e48e45cc.tar.gz backbonetutorials-5fe3d858830a88dbcd54fd53ff08f225e48e45cc.tar.bz2 |
updates
30 files changed, 2113 insertions, 2898 deletions
diff --git a/_config.yml b/_config.yml index 021f688..7878bba 100644 --- a/_config.yml +++ b/_config.yml @@ -1,3 +1,2 @@ -markdown: rdiscount pygments: true permalink: /:title diff --git a/_layouts/default.html b/_layouts/default.html index fe769a9..cd65b18 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -10,66 +10,49 @@ <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -97,7 +80,6 @@ <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> -<script> Nowtalk = []; Nowtalk.config = {fullscreen: false, session_id: 0, base_url: "https://www.nowtalk.com", widget_url: "https://www.nowtalk.com/chat", chat_id: "53a9f0318dcaf", debug: false }; document.write(unescape("%3Cscript src='https://www.nowtalk.com/build/embed_nowtalk.min.js?' type='text/javascript'%3E%3C/script%3E")); </script> </body> </html> diff --git a/_posts/2012-8-1-seo-for-single-page-apps.md b/_posts/2012-8-1-seo-for-single-page-apps.md index 00a241f..5c26733 100644 --- a/_posts/2012-8-1-seo-for-single-page-apps.md +++ b/_posts/2012-8-1-seo-for-single-page-apps.md @@ -27,7 +27,7 @@ Using modern headless browsers, we can easily return the fully rendered content You will need to install node.js and phantom.js onto a box. Then start up this server below. There are two files, one which is the web server and the other is a phantomjs script that renders the page. -{% highlight javascript %} +```javascript // web.js // Express is our web server that can handle request @@ -67,7 +67,7 @@ var respond = function (req, res) { app.get(/(.*)/, respond); app.listen(3000); -{% endhighlight %} +``` The script below is `phantom-server.js` and will be in charge of fully rendering the content. We don't return the content until the page is fully rendered. We hook into the resources listener to do this. diff --git a/_site/2011-12-12-cross-domain-backbone-apps.html b/_site/2011-12-12-cross-domain-backbone-apps.html index 8497bdf..ff7bae5 100644 --- a/_site/2011-12-12-cross-domain-backbone-apps.html +++ b/_site/2011-12-12-cross-domain-backbone-apps.html @@ -5,71 +5,54 @@ <title>Cross Browser problems when consuming your own API - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -126,7 +111,7 @@ <p>The example isn’t super fleshed out but should give you a vague idea.</p> <h3>Example File Structure</h3> <p>There are many different ways to lay out your files and I believe it is actually dependent on the size and type of the project. In the example below views and templates are mirroed in file structure. Collections and Models aren’t categorized into folders kind of like an <span class="caps">ORM</span>.</p> -<div class="highlight"><pre><code class="javascript"><span class="cm">/* File Structure</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="cm">/* File Structure</span> <span class="cm">├── imgs</span> <span class="cm">├── css</span> <span class="cm">│ └── style.css</span> @@ -168,13 +153,12 @@ <span class="cm">│ └── text.js //Require.js plugin</span> <span class="cm">└── index.html</span> -<span class="cm">*/</span> -</code></pre></div><p>To continue you must really understand what we are aiming towards as described in the introduction.</p> +<span class="cm">*/</span></code></pre></div><p>To continue you must really understand what we are aiming towards as described in the introduction.</p> <h3>Bootstrapping your application</h3> <p>Using Require.js we define a single entry point on our index page.<br /> We should setup any useful containers that might be used by our Backbone views.</p> <p><b>Note</b>: The data-main attribute on our single script tag tells Require.js to load the script located at “js/main.js”. It automatically appends the “.js”</p> -<div class="highlight"><pre><code class="html"><span class="cp"><!doctype html></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="cp"><!doctype html></span> <span class="nt"><html</span> <span class="na">lang=</span><span class="s">"en"</span><span class="nt">></span> <span class="nt"><head></span> <span class="nt"><title></span>Jackie Chan<span class="nt"></title></span> @@ -189,8 +173,7 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="nt"></div></span> <span class="nt"></body></span> -<span class="nt"></html></span> -</code></pre></div><p>You should most always end up with quite a light weight index file. You can serve this off your server and then the rest of your site off a <span class="caps">CDN</span> ensuring that everything that can be cached, will be.</p> +<span class="nt"></html></span></code></pre></div><p>You should most always end up with quite a light weight index file. You can serve this off your server and then the rest of your site off a <span class="caps">CDN</span> ensuring that everything that can be cached, will be.</p> <h4>What does the bootstrap look like?</h4> <p>Our bootstrap file will be responsible for configuring Require.js and loading initially important dependencies.</p> <p>In the below example we configure Require.js to create shortcut alias to commonly used scripts such as jQuery, Underscore and Backbone.</p> @@ -198,7 +181,7 @@ We should setup any useful containers that might be used by our Backbone views.< <p>Hopefully if the <span class="caps">AMD</span> specification takes off these libraries will add code to allow themselves to be loaded asynchronously. Due to this inconvience the bootstrap is not as intuitive as it could be, I hope to solve this problem in the near future.</p> <p>We also request a module called “app”, this will contain the entireity of our application logic.</p> <p><b>Note:</b> Modules are loaded relativly to the boot strap and always append with “.js”. So the module “app” will load “app.js” which is in the same directory as the bootstrap.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: main.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: main.js</span> <span class="c1">// Require.js allows us to configure shortcut alias</span> <span class="c1">// There usage will become more apparent futher along in the tutorial.</span> @@ -225,12 +208,11 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="c1">// The "app" dependency is passed in as "App"</span> <span class="c1">// Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function</span> <span class="nx">App</span><span class="p">.</span><span class="nx">initialize</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div><h3>How should we lay out external scripts?</h3> +<span class="p">});</span></code></pre></div><h3>How should we lay out external scripts?</h3> <p>Any modules we develop for our application using <span class="caps">AMD</span>/Require.js will be asynchronously loaded.</p> <p>We have a heavy dependency on jQuery, Underscore and Backbone, unfortunatly this libraries are loaded synchronously and also depend on each other existing in the global namespace.</p> <p>Below I propose a solution(until these libraries allow themselves to be loaded asynchronously) to allow these libraries to be loaded properly(synchronously) and also removing themselves from global scope.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: libs/jquery/jquery.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: libs/jquery/jquery.js</span> <span class="nx">define</span><span class="p">([</span> <span class="c1">// Load the original jQuery source file</span> @@ -238,14 +220,12 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">],</span> <span class="kd">function</span><span class="p">(){</span> <span class="c1">// Tell Require.js that this module returns a reference to jQuery</span> <span class="k">return</span> <span class="nx">$</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div><div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: libs/underscore/underscore</span> +<span class="p">});</span></code></pre></div><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: libs/underscore/underscore</span> <span class="c1">// As above lets load the original underscore source code</span> <span class="nx">define</span><span class="p">([</span><span class="s1">'order!libs/underscore/underscore-min'</span><span class="p">],</span> <span class="kd">function</span><span class="p">(){</span> <span class="c1">// Tell Require.js that this module returns a reference to Underscore</span> <span class="k">return</span> <span class="nx">_</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div><div class="highlight"><pre><code class="javascript"> <span class="c1">// Filename: libs/backbone/backbone</span> +<span class="p">});</span></code></pre></div><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: libs/backbone/backbone</span> <span class="c1">// Finally lets load the original backbone source code</span> <span class="nx">define</span><span class="p">([</span><span class="s1">'order!libs/backbone/backbone-min'</span><span class="p">],</span> <span class="kd">function</span><span class="p">(){</span> <span class="c1">// Now that all the orignal source codes have ran and accessed each other</span> @@ -254,11 +234,10 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="nx">_</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">();</span> <span class="nx">$</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">();</span> <span class="k">return</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div><h3>A boiler plate module</h3> +<span class="p">});</span></code></pre></div><h3>A boiler plate module</h3> <p>So before we start developing our application, let’s quickly look over boiler plate code that will be reused quite often.</p> <p>For convience sake I generally keep a “boilerplate.js” in my application root so I can copy it when I need to.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">//Filename: boilerplate.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">//Filename: boilerplate.js</span> <span class="nx">define</span><span class="p">([</span> <span class="c1">// These are path alias that we configured in our bootstrap</span> @@ -270,12 +249,11 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="c1">// They will not be accesible in the global scope</span> <span class="k">return</span> <span class="p">{};</span> <span class="c1">// What we return here will be used by other modules</span> -<span class="p">});</span> -</code></pre></div><p>The first argument of the define function is our dependency array, we can pass in any modules we like in the future.</p> +<span class="p">});</span></code></pre></div><p>The first argument of the define function is our dependency array, we can pass in any modules we like in the future.</p> <h3>App.js Building our applications main module</h3> <p>Our applications main module should always remain quite light weight. This tutorial covers only setting up a Backbone Router and initializing it in our main module.</p> <p>The router will then load the correct dependencies depending on the current <span class="caps">URL</span>.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: app.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: app.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jQuery'</span><span class="p">,</span> <span class="s1">'Underscore'</span><span class="p">,</span> @@ -290,8 +268,7 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div><div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: router.js</span> +<span class="p">});</span></code></pre></div><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: router.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jQuery'</span><span class="p">,</span> <span class="s1">'Underscore'</span><span class="p">,</span> @@ -331,10 +308,9 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div><h3>Modularizing a Backbone View</h3> +<span class="p">});</span></code></pre></div><h3>Modularizing a Backbone View</h3> <p>Backbone views most usually always interact with the <span class="caps">DOM</span>, using our new modular system we can load in Javascript templates using Require.js text! plugin.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/project/list</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/project/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jQuery'</span><span class="p">,</span> <span class="s1">'Underscore'</span><span class="p">,</span> @@ -356,12 +332,11 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="c1">// Our module now returns an instantiated view</span> <span class="c1">// Sometimes you might return an un-instantiated view e.g. return projectListView</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">projectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div><p>Javascript templating allows us to seperate the design from the application logic placing all our html in the templates folder.</p> +<span class="p">});</span></code></pre></div><p>Javascript templating allows us to seperate the design from the application logic placing all our html in the templates folder.</p> <h3>Modularizing a Collection, Model and View</h3> <p>Now we put it altogether by chaining up a Model, Collection and View which is a typical scenairo when building a Backbone.js application.</p> <p>First off we will define our model</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: models/project</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: models/project</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'Underscore'</span><span class="p">,</span> <span class="s1">'Backbone'</span> @@ -373,10 +348,9 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">});</span> <span class="c1">// You usually don't return a model instantiated</span> <span class="k">return</span> <span class="nx">projectModel</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div><p>Now we have a model, our collection module can depend on it. We will set the “model” attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> +<span class="p">});</span></code></pre></div><p>Now we have a model, our collection module can depend on it. We will set the “model” attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> <p>“Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.”</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: collections/projects</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: collections/projects</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'Underscore'</span><span class="p">,</span> <span class="s1">'Backbone'</span><span class="p">,</span> @@ -388,9 +362,8 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">});</span> <span class="c1">// You don't usually return a collection instantiated</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">projectCollection</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div><p>Now we can simply depend on our collection in our view and pass it to our Javascript template.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/projects/list</span> +<span class="p">});</span></code></pre></div><p>Now we can simply depend on our collection in our view and pass it to our Javascript template.</p> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/projects/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jQuery'</span><span class="p">,</span> <span class="s1">'Underscore'</span><span class="p">,</span> @@ -411,8 +384,7 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">});</span> <span class="c1">// Returning instantiated views can be quite useful for having "state"</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">projectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div><h3>Conclusion</h3> +<span class="p">});</span></code></pre></div><h3>Conclusion</h3> <p>Looking forward to feedback so I can turn this post and example into quality references on building modular Javascript applications.</p> <p>Get in touch with me on twitter, comments or github!</p> <h3>Relevant Links</h3> @@ -437,7 +409,8 @@ We should setup any useful containers that might be used by our Backbone views.< <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -460,17 +433,9 @@ We should setup any useful containers that might be used by our Backbone views.< </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/about.html b/_site/about.html index ad926c6..e43e37a 100644 --- a/_site/about.html +++ b/_site/about.html @@ -5,71 +5,54 @@ <title>About Backbone Tutorials - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -78,13 +61,15 @@ <h3 class="panel-title">About</h3> </div> - <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this in my spare time, so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> + <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,17 +81,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/atom.xml b/_site/atom.xml index 258dfc3..6488d59 100644 --- a/_site/atom.xml +++ b/_site/atom.xml @@ -4,7 +4,7 @@ <title>Backbone Tutorials</title> <link href="http://backbonetutorials.com/atom.xml" rel="self"/> <link href="http://backbonetutorials.com/"/> - <updated>2013-08-14T18:01:55+10:00</updated> + <updated>2014-11-14T09:02:49+10:00</updated> <id>http://backbonetutorials.com/</id> <author> <name>Thomas Davis</name> @@ -12,78 +12,170 @@ </author> <entry> - <title>SEO for single page applications</title> - <link href="http://backbonetutorials.com/seo-for-single-page-apps"/> - <updated>2012-08-01T00:00:00+10:00</updated> - <id>http://backbonetutorials.com/seo-for-single-page-apps</id> - <content type="html"><h1>SEO for single page apps</h1> + <title>Real-Time Backbone With PubNub</title> + <link href="http://backbonetutorials.com/real-time-backbone-with-pubnub"/> + <updated>2013-08-29T00:00:00+10:00</updated> + <id>http://backbonetutorials.com/real-time-backbone-with-pubnub</id> + <content type="html"><h1 id="real-time-backbone-with-pubnub">Real-Time Backbone With PubNub</h1> -<p>This tutorial will show you how to index your application on search engines. As the author I believe that servers should be completely independent of the client in the age of API's. Which speeds up development for the ever increasing array of clients. It is on the shoulders of the search engines to conform and they should not dictate how the web is stored and accessed.</p> +<p>Backbone is one of the most popular JavaScript based frameworks to date. It is a simple yet powerful way to create interactive JavaScript applications with data bindings to a back-end server. Instead of having to constantly synchronize data between your client and server though, why not have all the data there when it happens? Users should not have to wait to see updates to their model’s data so we decided to tackle this problem by integrating Backbone.js with PubNub.</p> -<p>In 2009 Google released the idea of <a href="http://googlewebmastercentral.blogspot.com.au/2009/10/proposal-for-making-ajax-crawlable.html">escaped fragments</a>.</p> +<p><img src="http://blogly.pubnub.com/wp-content/uploads/2013/08/PubNubBackboneJS.png" alt="PubnNub and Backbone" /></p> -<p>The idea simply stating that if a search engine should come across your JavaScript application then you have the permission to redirect the search engine to another URL that serves the fully rendered version of the page (The current search engines cannot execute much JavaScript (Some people speculate that Google Chrome was born of Google Search wishing to successfully render every web page to retrieve ajaxed content)).</p> +<p>Our integration allows developers to create a Backbone model or collection and have them synchronize with every other client instance of those models or collections in real-time. This will give any Backbone application a better user experience when working with collaborative, social, or any type of multi-user interface. It works by taking all of the create, update, and delete methods that are spawned by Backbone and propagating them across the PubNub real-time network.</p> -<h2>How does redirecting bots work?</h2> +<p>Want to see it in action? A full working tutorial and all the code you need is available at our <a href="http://pubnub.github.io/backbone/">GitHub page</a></p> -<p>Using modern headless browsers, we can easily return the fully rendered content per request by redirecting bots using our web servers configuration. Here is an image made by Google depicting the setup.</p> +<h2 id="getting-started">Getting Started</h2> -<p><img src="http://acris.googlecode.com/svn/wiki/images/seo_google_crawlability.png" alt="headless seo" /></p> +<p>The easiest way to get started is by using bower via <code>bower install pubnub-backbone</code>. You can also clone the repository and copy the built javascript files. Now you can include this and the base PubNub library found at <a href="https://github.com/pubnub/javascript#pubnub-cdn-javascript-sdk">https://github.com/pubnub/javascript#pubnub-cdn-javascript-sdk</a> like so:</p> -<div style='clear: both;'></div> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;http://cdn.pubnub.com/pubnub.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span> +<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;/path/to/backbone-pubnub.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span></code></pre></div> +<p>The easiest way to get started using the library is by creating a PubNub based collection. This will automatically propagate all create, update, and delete methods across all other clients in real-time. This requires creating a free account to get your API keys at <a href="http://pubnub.com/free-trial">http://pubnub.com/free-trial</a> and then initializing a global PubNub instance:</p> -<h2>Implementation using Phantom.js</h2> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">pubnub</span> <span class="o">=</span> <span class="nx">PUBNUB</span><span class="p">.</span><span class="nx">init</span><span class="p">({</span> + <span class="nx">publish_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span><span class="p">,</span> + <span class="nx">subscribe_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span> +<span class="p">});</span></code></pre></div> -<p><a href="http://phantomjs.org/">Phantom.js</a> is a headless webkit browser. We are going to setup a node.js server that given a URL, it will fully render the page content. Then we will redirect bots to this server to retrieve the correct content.</p> +<h2 id="creating-a-real-time-collection">Creating a Real-Time Collection</h2> -<p>You will need to install node.js and phantom.js onto a box. Then start up this server below. There are two files, one which is the web server and the other is a phantomjs script that renders the page.</p> +<p>Now that we have a connection to PubNub, we can feed that connection into our custom Backbone collection:</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// web.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">MyCollection</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">PubNub</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;MyCollection&#39;</span><span class="p">,</span> + <span class="nx">pubnub</span><span class="o">:</span> <span class="nx">pubnub</span> +<span class="p">});</span></code></pre></div> -<span class="c1">// Express is our web server that can handle request</span> -<span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> -<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span> +<p>This will look and act just like a normal Backbone collection with two extra keys. The “name” key allows PubNub to distinguish this collection, so it connects this collections to only collections of the same type. Think of this as a namespace so you can have multiple types of collections all updating in real-time. It uses this to generate a PubNub channel that is unique to the collection in the form of “backbone-collection-{name}”. The “pubnub” property is the globally referenced connection to the PubNub network. This is the object that comes back after calling PUBNUB.init.</p> +<p>Now your Backbone collection will update in real-time. You can listen for add and remove events just like usual when something gets added or removed in real-time. The next step is to implement a way to get the current set of data when the collection first loads so every client is using the same data set. A great way of accomplishing this is by listening to the PubNub based events with a server and replicating the data store. Then the client can ask for the current set of data every time the application loads. This is made even simpler when using the backbone npm module for nodejs:</p> -<span class="kd">var</span> <span class="nx">getContent</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span> - <span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span> - <span class="c1">// Here we spawn a phantom.js process, the first element of the </span> - <span class="c1">// array is our phantomjs script and the second element is our url </span> - <span class="kd">var</span> <span class="nx">phantom</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;child_process&#39;</span><span class="p">).</span><span class="nx">spawn</span><span class="p">(</span><span class="s1">&#39;phantomjs&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;phantom-server.js&#39;</span><span class="p">,</span> <span class="nx">url</span><span class="p">]);</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">setEncoding</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">);</span> - <span class="c1">// Our phantom.js script is simply logging the output and</span> - <span class="c1">// we access it here through stdout</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">content</span> <span class="o">+=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span> - <span class="p">});</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;exit&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> - <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;We have an error&#39;</span><span class="p">);</span> - <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> - <span class="c1">// once our phantom.js script exits, let&#39;s call out call back</span> - <span class="c1">// which outputs the contents to the page</span> - <span class="nx">callback</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;underscore&#39;</span><span class="p">).</span><span class="nx">_</span><span class="p">,</span> + <span class="nx">Backbone</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;backbone&#39;</span><span class="p">),</span> + <span class="nx">pubnub</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;pubnub&#39;</span><span class="p">).</span><span class="nx">init</span><span class="p">({</span> + <span class="nx">publish_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span><span class="p">,</span> + <span class="nx">subscribe_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span> + <span class="p">});</span> + +<span class="kd">var</span> <span class="nx">MyCollection</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="c1">// Add business logic here</span> +<span class="p">});</span> + +<span class="kd">var</span> <span class="nx">myCollection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyCollection</span><span class="p">();</span> + +<span class="nx">pubnub</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">({</span> + <span class="nx">channel</span><span class="o">:</span> <span class="s1">&#39;backbone-collection-MyCollection&#39;</span><span class="p">,</span> <span class="c1">// This is what is created internally by the framework</span> + <span class="nx">callback</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> + <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span> <span class="c1">// All data is transferred as JSON</span> + + <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">method</span> <span class="o">===</span> <span class="s1">&#39;create&#39;</span><span class="p">)</span> <span class="p">{</span> + <span class="nx">myCollection</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">);</span> + <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">method</span> <span class="o">===</span> <span class="s1">&#39;update&#39;</span><span class="p">)</span> <span class="p">{</span> + <span class="nx">myCollection</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">);</span> + <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">method</span> <span class="o">===</span> <span class="s1">&#39;delete&#39;</span><span class="p">)</span> <span class="p">{</span> + <span class="kd">var</span> <span class="nx">record</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">myCollection</span><span class="p">.</span><span class="nx">models</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">record</span><span class="p">)</span> <span class="p">{</span> + <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">id</span> <span class="o">===</span> <span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span> + <span class="p">});</span> + + <span class="k">if</span> <span class="p">(</span><span class="nx">record</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span> + <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Could not record: &quot;</span> <span class="o">+</span> <span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span> + <span class="p">}</span> + + <span class="kd">var</span> <span class="nx">diff</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">difference</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">record</span><span class="p">.</span><span class="nx">attributes</span><span class="p">),</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">));</span> + <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">diff</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span> + <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">unset</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span> + <span class="p">});</span> + + <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">,</span> <span class="nx">data</span><span class="p">.</span><span class="nx">options</span><span class="p">);</span> <span class="p">}</span> - <span class="p">});</span> -<span class="p">};</span> + <span class="p">}</span> +<span class="p">});</span> + +<span class="c1">// Now myCollection will always be up to date.</span> +<span class="c1">// Here you can provide some way (i.e. http.createServer) to get the data from the server.</span></code></pre></div> -<span class="kd">var</span> <span class="nx">respond</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span> - <span class="c1">// Because we use [P] in htaccess we have access to this header</span> - <span class="nx">url</span> <span class="o">=</span> <span class="s1">&#39;http://&#39;</span> <span class="o">+</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">&#39;x-forwarded-host&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> - <span class="nx">getContent</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span> - <span class="p">});</span> -<span class="p">}</span> +<p>Now you can listen for all the changes to the collection and either store them in memory or even a database such as MongoDB. You can even add other business logic for validations and more. Although nodejs was an obvious choice for the demo, this code will work with any type of back end too. This is just one easy way to use the framework but be sure to check out the repository for more examples!</p> + +<p>We here at PubNub truly believe that real-time is the way of the future. Your users will not have to click a refresh button to constantly synchronize their Backbone client data with a server. Instead, with PubNub integration, your users will get data right when it happens. This is also much more extensible since any client or server can listen to the events and manipulate them as they need to. This allows business logic to lay in more places than one. We really hope this changes the way developers look at building not just Backbone applications but web applications overall.</p> -<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sr">/(.*)/</span><span class="p">,</span> <span class="nx">respond</span><span class="p">);</span> -<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span> -</code></pre></div> +<p>You can read more about PubNub at <a href="http://pubnub.com">our website</a> and more about Backbone integration at <a href="http://pubnub.github.io/backbone/">our GitHub page</a></p> +</content> + </entry> + + <entry> + <title>SEO for single page applications</title> + <link href="http://backbonetutorials.com/seo-for-single-page-apps"/> + <updated>2012-08-01T00:00:00+10:00</updated> + <id>http://backbonetutorials.com/seo-for-single-page-apps</id> + <content type="html"><h1 id="seo-for-single-page-apps">SEO for single page apps</h1> + +<p>This tutorial will show you how to index your application on search engines. As the author I believe that servers should be completely independent of the client in the age of API’s. Which speeds up development for the ever increasing array of clients. It is on the shoulders of the search engines to conform and they should not dictate how the web is stored and accessed.</p> + +<p>In 2009 Google released the idea of <a href="http://googlewebmastercentral.blogspot.com.au/2009/10/proposal-for-making-ajax-crawlable.html">escaped fragments</a>. </p> + +<p>The idea simply stating that if a search engine should come across your JavaScript application then you have the permission to redirect the search engine to another URL that serves the fully rendered version of the page (The current search engines cannot execute much JavaScript (Some people speculate that Google Chrome was born of Google Search wishing to successfully render every web page to retrieve ajaxed content)).</p> + +<h2 id="how-does-redirecting-bots-work">How does redirecting bots work?</h2> + +<p>Using modern headless browsers, we can easily return the fully rendered content per request by redirecting bots using our web servers configuration. Here is an image made by Google depicting the setup.</p> +<p><img src="http://acris.googlecode.com/svn/wiki/images/seo_google_crawlability.png" alt="headless seo" /></p> + +<div style="clear: both;"></div> + +<h2 id="implementation-using-phantomjs">Implementation using Phantom.js</h2> + +<p><a href="http://phantomjs.org/">Phantom.js</a> is a headless webkit browser. We are going to setup a node.js server that given a URL, it will fully render the page content. Then we will redirect bots to this server to retrieve the correct content.</p> -<p>The script below is <code>phantom-server.js</code> and will be in charge of fully rendering the content. We don't return the content until the page is fully rendered. We hook into the resources listener to do this.</p> +<p>You will need to install node.js and phantom.js onto a box. Then start up this server below. There are two files, one which is the web server and the other is a phantomjs script that renders the page.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;webpage&#39;</span><span class="p">).</span><span class="nx">create</span><span class="p">();</span> +<p>```javascript +// web.js</p> + +<p>// Express is our web server that can handle request +var express = require(‘express’); +var app = express();</p> + +<p>var getContent = function(url, callback) { + var content = ‘’; + // Here we spawn a phantom.js process, the first element of the + // array is our phantomjs script and the second element is our url + var phantom = require(‘child_process’).spawn(‘phantomjs’, [‘phantom-server.js’, url]); + phantom.stdout.setEncoding(‘utf8’); + // Our phantom.js script is simply logging the output and + // we access it here through stdout + phantom.stdout.on(‘data’, function(data) { + content += data.toString(); + }); + phantom.on(‘exit’, function(code) { + if (code !== 0) { + console.log(‘We have an error’); + } else { + // once our phantom.js script exits, let’s call out call back + // which outputs the contents to the page + callback(content); + } + }); +};</p> + +<p>var respond = function (req, res) { + // Because we use [P] in htaccess we have access to this header + url = ‘http://’ + req.headers[‘x-forwarded-host’] + req.params[0]; + getContent(url, function (content) { + res.send(content); + }); +}</p> + +<p>app.get(/(.*)/, respond); +app.listen(3000); +```</p> + +<p>The script below is <code>phantom-server.js</code> and will be in charge of fully rendering the content. We don’t return the content until the page is fully rendered. We hook into the resources listener to do this.</p> + +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;webpage&#39;</span><span class="p">).</span><span class="nx">create</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;system&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">lastReceived</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">();</span> @@ -119,25 +211,21 @@ <span class="p">}</span> <span class="p">}</span> <span class="c1">// Let us check to see if the page is finished rendering</span> -<span class="kd">var</span> <span class="nx">checkCompleteInterval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="nx">checkComplete</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> -</code></pre></div> +<span class="kd">var</span> <span class="nx">checkCompleteInterval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="nx">checkComplete</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span></code></pre></div> +<p>Once we have this server up and running we just redirect bots to the server in our client’s web server configuration.</p> -<p>Once we have this server up and running we just redirect bots to the server in our client's web server configuration.</p> - -<h2>Redirecting bots</h2> +<h2 id="redirecting-bots">Redirecting bots</h2> <p>If you are using apache we can edit out <code>.htaccess</code> such that Google requests are proxied to our middle man phantom.js server.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">RewriteEngine</span> <span class="nx">on</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">RewriteEngine</span> <span class="nx">on</span> <span class="nx">RewriteCond</span> <span class="o">%</span><span class="p">{</span><span class="nx">QUERY_STRING</span><span class="p">}</span> <span class="o">^</span><span class="nx">_escaped_fragment_</span><span class="o">=</span><span class="p">(.</span><span class="o">*</span><span class="p">)</span><span class="nx">$</span> -<span class="nx">RewriteRule</span> <span class="p">(.</span><span class="o">*</span><span class="p">)</span> <span class="nx">http</span><span class="o">:</span><span class="c1">//webserver:3000/%1? [P]</span> -</code></pre></div> - +<span class="nx">RewriteRule</span> <span class="p">(.</span><span class="o">*</span><span class="p">)</span> <span class="nx">http</span><span class="o">:</span><span class="c1">//webserver:3000/%1? [P]</span></code></pre></div> <p>We could also include other <code>RewriteCond</code>, such as <code>user agent</code> to redirect other search engines we wish to be indexed on.</p> -<p>Though Google won't use <code>_escaped_fragment_</code> unless we tell it to by either including a meta tag; +<p>Though Google won’t use <code>_escaped_fragment_</code> unless we tell it to by either including a meta tag; <code>&lt;meta name="fragment" content="!"&gt;</code> or using <code>#!</code> URLs in our links.</p> @@ -148,12 +236,11 @@ using <code>#!</code> URLs in our links.</p> <p>This has been tested with Google Webmasters fetch tool. Make sure you include <code>#!</code> on your URLs when using the fetch tool.</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://seo.apiengine.io">Open source node.js Seo Server</a></li> + <li><a href="http://seo.apiengine.io">Open source node.js Seo Server</a></li> </ul> - </content> </entry> @@ -162,7 +249,7 @@ using <code>#!</code> URLs in our links.</p> <link href="http://backbonetutorials.com/organizing-backbone-using-modules"/> <updated>2011-10-10T00:00:00+10:00</updated> <id>http://backbonetutorials.com/organizing-backbone-using-modules</id> - <content type="html"><h1>Organizing your application using Modules (require.js)</h1> + <content type="html"><h1 id="organizing-your-application-using-modules-requirejs">Organizing your application using Modules (require.js)</h1> <p>Unfortunately Backbone.js does not tell you how to organize your code, leaving many developers in the dark regarding how to load scripts and lay out their development environments.</p> @@ -172,7 +259,7 @@ using <code>#!</code> URLs in our links.</p> <p>This tutorial will get you started on combining Backbone.js with <a href="https://github.com/amdjs/amdjs-api/wiki/AMD">AMD</a> (Asynchronous Module Definitions).</p> -<h2>What is AMD?</h2> +<h2 id="what-is-amd">What is AMD?</h2> <p><a href="https://github.com/amdjs/amdjs-api/wiki/AMD">Asynchronous Module Definitions</a> designed to load modular code asynchronously in the browser and server. It is actually a fork of the Common.js specification. Many script loaders have built their implementations around AMD, seeing it as the future of modular JavaScript development.</p> @@ -183,26 +270,20 @@ using <code>#!</code> URLs in our links.</p> <p>Quick Overview</p> <ul> -<li>Modular</li> -<li>Scalable</li> -<li>Compiles well(see <a href="http://requirejs.org/docs/optimization.html">r.js</a> )</li> -<li>Market Adoption( <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 converted fully to AMD</a> )</li> + <li>Modular</li> + <li>Scalable</li> + <li>Compiles well(see <a href="http://requirejs.org/docs/optimization.html">r.js</a> )</li> + <li>Market Adoption( <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 converted fully to AMD</a> )</li> </ul> +<h2 id="why-requirejs">Why Require.js?</h2> -<h2>Why Require.js?</h2> - -<ol type="a"> -<li>Require.js has a great community and it is growing rapidly. <a href="http://tagneto.blogspot.com/">James Burke</a> the author is married to Require.js and always responds to user feedback. He is a leading expert in script loading and a contributer to the AMD specification.</li> -</ol> - - -<p><a href="https://twitter.com/jrburke" class="twitter-follow-button">Follow @jrburke</a></p> +<p>p. Require.js has a great community and it is growing rapidly. <a href="http://tagneto.blogspot.com/">James Burke</a> the author is married to Require.js and always responds to user feedback. He is a leading expert in script loading and a contributer to the AMD specification.</p> -<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script> +<p><a href="https://twitter.com/jrburke" class="twitter-follow-button">Follow @jrburke</a> +<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script></p> - -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> @@ -214,13 +295,13 @@ using <code>#!</code> URLs in our links.</p> <p>If you would like to see how a particular use case would be implemented please visit the GitHub page and create an issue.(Example Request: How to do nested views).</p> -<p>The example isn't super fleshed out but should give you a vague idea.</p> +<p>The example isn’t super fleshed out but should give you a vague idea.</p> -<h2>Example File Structure</h2> +<h2 id="example-file-structure">Example File Structure</h2> <p>There are many different ways to lay out your files and I believe it is actually dependent on the size and type of the project. In the example below views and templates are mirrored in file structure. Collections and Models are categorized into folders kind of like an ORM.</p> -<div class="highlight"><pre><code class="javascript"><span class="cm">/* File Structure</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="cm">/* File Structure</span> <span class="cm">├── imgs</span> <span class="cm">├── css</span> <span class="cm">│ └── style.css</span> @@ -259,25 +340,23 @@ using <code>#!</code> URLs in our links.</p> <span class="cm">│ └── text.js //Require.js plugin</span> <span class="cm">└── index.html</span> -<span class="cm">*/</span> -</code></pre></div> - +<span class="cm">*/</span></code></pre></div> <p>To continue you must really understand what we are aiming towards as described in the introduction.</p> -<h2>Bootstrapping your application</h2> +<h2 id="bootstrapping-your-application">Bootstrapping your application</h2> <p>Using Require.js we define a single entry point on our index page. We should setup any useful containers that might be used by our Backbone views.</p> -<p><em>Note: The data-main attribute on our single script tag tells Require.js to load the script located at "js/main.js". It automatically appends the ".js"</em></p> +<p><em>Note: The data-main attribute on our single script tag tells Require.js to load the script located at “js/main.js”. It automatically appends the “.js”</em></p> -<div class="highlight"><pre><code class="html"><span class="cp">&lt;!doctype html&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="cp">&lt;!doctype html&gt;</span> <span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">&quot;en&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;head&gt;</span> - <span class="nt">&lt;title&gt;</span>Jackie Chan<span class="nt">&lt;/title&gt;</span> - <span class="c">&lt;!-- Load the script &quot;js/main.js&quot; as our entry point --&gt;</span> - <span class="nt">&lt;script </span><span class="na">data-main=</span><span class="s">&quot;js/main&quot;</span> <span class="na">src=</span><span class="s">&quot;js/libs/require/require.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span> + <span class="nt">&lt;title&gt;</span>Jackie Chan<span class="nt">&lt;/title&gt;</span> + <span class="c">&lt;!-- Load the script &quot;js/main.js&quot; as our entry point --&gt;</span> + <span class="nt">&lt;script </span><span class="na">data-main=</span><span class="s">&quot;js/main&quot;</span> <span class="na">src=</span><span class="s">&quot;js/libs/require/require.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span> <span class="nt">&lt;/head&gt;</span> <span class="nt">&lt;body&gt;</span> @@ -287,27 +366,25 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/body&gt;</span> -<span class="nt">&lt;/html&gt;</span> -</code></pre></div> - +<span class="nt">&lt;/html&gt;</span></code></pre></div> <p>You should most always end up with quite a light weight index file. You can serve this off your server and then the rest of your site off a CDN ensuring that everything that can be cached, will be. (You can also now serve the index file off the CDN using Cloudfront)</p> -<h3>What does the bootstrap look like?</h3> +<h3 id="what-does-the-bootstrap-look-like">What does the bootstrap look like?</h3> <p>Our bootstrap file will be responsible for configuring Require.js and loading initially important dependencies.</p> <p>In the example below we configure Require.js to create a shortcut alias to commonly used scripts such as jQuery, Underscore and Backbone.</p> -<p>Unfortunately Backbone.js isn't AMD enabled so I downloaded the community managed repository and patched it on <a href="https://github.com/amdjs">amdjs</a>.</p> +<p>Unfortunately Backbone.js isn’t AMD enabled so I downloaded the community managed repository and patched it on <a href="https://github.com/amdjs">amdjs</a>.</p> <p>Hopefully if the AMD specification takes off these libraries will add code to allow themselves to be loaded asynchronously. Due to this inconvenience the bootstrap is not as intuitive as it could be.</p> -<p>We also request a module called "app", this will contain the entirety of our application logic.</p> +<p>We also request a module called “app”, this will contain the entirety of our application logic.</p> -<p><em>Note: Modules are loaded relatively to the boot strap and always append with ".js". So the module "app" will load "app.js" which is in the same directory as the bootstrap.</em></p> +<p><em>Note: Modules are loaded relatively to the boot strap and always append with “.js”. So the module “app” will load “app.js” which is in the same directory as the bootstrap.</em></p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: main.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: main.js</span> <span class="c1">// Require.js allows us to configure shortcut alias</span> <span class="c1">// There usage will become more apparent further along in the tutorial.</span> @@ -327,23 +404,21 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">App</span><span class="p">){</span> <span class="c1">// The &quot;app&quot; dependency is passed in as &quot;App&quot;</span> <span class="nx">App</span><span class="p">.</span><span class="nx">initialize</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<h2>How should we lay out external scripts?</h2> +<h2 id="how-should-we-lay-out-external-scripts">How should we lay out external scripts?</h2> <p>Any modules we develop for our application using AMD/Require.js will be asynchronously loaded.</p> <p>We have a heavy dependency on jQuery, Underscore and Backbone, unfortunately this libraries are loaded synchronously and also depend on each other existing in the global namespace.</p> -<h2>A boiler plate module</h2> +<h2 id="a-boiler-plate-module">A boiler plate module</h2> -<p>So before we start developing our application, let's quickly look over boiler plate code that will be reused quite often.</p> +<p>So before we start developing our application, let’s quickly look over boiler plate code that will be reused quite often.</p> -<p>For convenience sake I generally keep a "boilerplate.js" in my application root so I can copy it when I need to.</p> +<p>For convenience sake I generally keep a “boilerplate.js” in my application root so I can copy it when I need to.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">//Filename: boilerplate.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">//Filename: boilerplate.js</span> <span class="nx">define</span><span class="p">([</span> <span class="c1">// These are path alias that we configured in our bootstrap</span> @@ -355,19 +430,17 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="c1">// They will not be accessible in the global scope</span> <span class="k">return</span> <span class="p">{};</span> <span class="c1">// What we return here will be used by other modules</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>The first argument of the define function is our dependency array, in the future we can pass in any modules we like.</p> -<h2>App.js Building our applications main module</h2> +<h2 id="appjs-building-our-applications-main-module">App.js Building our applications main module</h2> <p>Our applications main module should always remain light weight. This tutorial only covers setting up a Backbone Router and initializing it in our main module.</p> <p>The router will then load the correct dependencies depending on the current URL.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: app.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: app.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -382,20 +455,16 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div> - - - +<span class="p">});</span></code></pre></div> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: router.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: router.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> <span class="s1">&#39;views/projects/list&#39;</span><span class="p">,</span> <span class="s1">&#39;views/users/list&#39;</span> -<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">Session</span><span class="p">,</span> <span class="nx">ProjectListView</span><span class="p">,</span> <span class="nx">UserListView</span><span class="p">){</span> +<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">ProjectListView</span><span class="p">,</span> <span class="nx">UserListView</span><span class="p">){</span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="c1">// Define some URL routes</span> @@ -430,15 +499,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<h2>Modularizing a Backbone View</h2> +<h2 id="modularizing-a-backbone-view">Modularizing a Backbone View</h2> <p>Backbone views usually interact with the DOM. Using our new modular system we can load in JavaScript templates using the Require.js text! plug-in.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/project/list</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/project/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -459,19 +526,17 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// Our module now returns our view</span> <span class="k">return</span> <span class="nx">ProjectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>JavaScript templating allows us to separate the design from the application logic by placing all our HTML in the templates folder.</p> -<h2>Modularizing a Collection, Model and View</h2> +<h2 id="modularizing-a-collection-model-and-view">Modularizing a Collection, Model and View</h2> <p>Now we put it altogether by chaining up a Model, Collection and View which is a typical scenario when building a Backbone.js application.</p> <p>First we will define our model</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: models/project</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: models/project</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span> @@ -483,15 +548,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// Return the model for the module</span> <span class="k">return</span> <span class="nx">ProjectModel</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<p>Now that we have a model, our collection module can depend on it. We will set the "model" attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> +<p>Now that we have a model, our collection module can depend on it. We will set the “model” attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> -<blockquote><p>Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.</p></blockquote> +<blockquote> + <p>Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.</p> +</blockquote> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: collections/projects</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: collections/projects</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -503,13 +568,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// You don&#39;t usually return a collection instantiated</span> <span class="k">return</span> <span class="nx">ProjectCollection</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>Now we can simply depend on our collection in our view and pass it to our JavaScript template.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/projects/list</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/projects/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -530,29 +593,25 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// Returning instantiated views can be quite useful for having &quot;state&quot;</span> <span class="k">return</span> <span class="nx">ProjectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> +<span class="p">});</span></code></pre></div> - -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>Looking forward to feedback so I can turn this post and example into quality references on building modular JavaScript applications.</p> <p>Get in touch with me on twitter, comments or GitHub!</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></li> + <li><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/dzejkej">Jakub Kozisek</a> (created modular-backbone-updated containing updated libs with AMD support)</li> + <li><a href="https://github.com/dzejkej">Jakub Kozisek</a> (created modular-backbone-updated containing updated libs with AMD support)</li> </ul> - </content> </entry> @@ -561,45 +620,44 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/cross-domain-sessions"/> <updated>2011-05-01T00:00:00+10:00</updated> <id>http://backbonetutorials.com/cross-domain-sessions</id> - <content type="html"><h1>Cross-domain Backbone.js with sessions using CORS</h1> + <content type="html"><h1 id="cross-domain-backbonejs-with-sessions-using-cors">Cross-domain Backbone.js with sessions using CORS</h1> -<p><strong> This tutorial is a proof of concept and needs to be checked for security flaws </strong></p> +<p>** This tutorial is a proof of concept and needs to be checked for security flaws **</p> <p>This tutorial will teach you how to completely separate the server and client allowing for developers to work with freedom in their respective areas.</p> <p>On a personal note, I consider this development practice highly desirable and encourage others to think of the possible benefits but the security still needs to be proved.</p> -<blockquote><p>Cross-Origin Resource Sharing (CORS) is a specification that enables a truly open access across domain-boundaries. - <a href="http://enable-cors.org/">enable-cors.org</a></p></blockquote> +<blockquote> + <p>Cross-Origin Resource Sharing (CORS) is a specification that enables a truly open access across domain-boundaries. - <a href="http://enable-cors.org/">enable-cors.org</a></p> +</blockquote> <p><strong>Some benefits include</strong></p> <ul> -<li>The client and back end exist independently regardless of where they are each hosted and built.</li> -<li>Due to the separation of concerns, testing now becomes easier and more controlled.</li> -<li>Develop only one API on the server, your front-end could be outsourced or built by a in-house team.</li> -<li>As a front-end developer you can host the client anywhere.</li> -<li>This separation enforces that the API be built robustly, documented, collaboratively and versioned.</li> + <li>The client and back end exist independently regardless of where they are each hosted and built.</li> + <li>Due to the separation of concerns, testing now becomes easier and more controlled.</li> + <li>Develop only one API on the server, your front-end could be outsourced or built by a in-house team.</li> + <li>As a front-end developer you can host the client anywhere.</li> + <li>This separation enforces that the API be built robustly, documented, collaboratively and versioned.</li> </ul> - -<p><strong> Cons of this tutorial </strong></p> +<p>** Cons of this tutorial **</p> <ul> -<li>This tutorial doesn't explain how to perform this with cross browser support. CORS headers aren't supported by Opera and IE 6/7. Though it is do-able using <a href="http://easyxdm.net/wp/">easyXDM</a></li> -<li>Security is somewhat addressed but maybe a more thorough security expert can chime in.</li> + <li>This tutorial doesn’t explain how to perform this with cross browser support. CORS headers aren’t supported by Opera and IE 6/7. Though it is do-able using <a href="http://easyxdm.net/wp/">easyXDM</a></li> + <li>Security is somewhat addressed but maybe a more thorough security expert can chime in.</li> </ul> - -<h2>Security</h2> +<h2 id="security">Security</h2> <ul> -<li>Don't allow GET request to change data, only retrieve.</li> -<li>Whitelist your allowed domains (see <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/server.js">server.js</a>)</li> -<li>Protect again <a href="http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html">JSON padding</a></li> + <li>Don’t allow GET request to change data, only retrieve.</li> + <li>Whitelist your allowed domains (see <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/server.js">server.js</a>)</li> + <li>Protect again <a href="http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html">JSON padding</a></li> </ul> - -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> @@ -611,11 +669,11 @@ We should setup any useful containers that might be used by our Backbone views.& <p>This tutorial focuses on building a flexible Session model to control session state in your application.</p> -<h2>Checking session state at first load</h2> +<h2 id="checking-session-state-at-first-load">Checking session state at first load</h2> <p>Before starting any routes, we should really know whether the user is authenticated. This will allow us to load the appropriate views. We will simply wrap our <code>Backbone.history.start</code> in a callback that executes after <code>Session.getAuth</code> has checked the server. We will jump into our Session model next.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -645,19 +703,17 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> <span class="p">})</span> <span class="p">}</span> - <span class="p">});</span> + <span class="p">});</span> <span class="k">return</span> <span class="nx">AppView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: We have used jQuery <code>ajaxPrefilter</code> to hook into all AJAX requests before they are executed. This is where we specify what server we want the application to hit.</em></p> -<h2>An example Session model</h2> +<h2 id="an-example-session-model">An example Session model</h2> -<p>This is a very light weight Session model which handles most situations. Read through the code and comments below. The model simply has a login, logout and check function. Again we have hooked into jQuery <code>ajaxPrefilter</code> to allow for csrf tokens and also telling jQuery to send cookies with the <code>withCredentials</code> property. The model relies heavily on it's <code>auth</code> property. Throughout your application, each view can simply bind to <code>change:auth</code> on the Session model and react accordingly. Because we return this AMD module instantiated using the new keyword, then it will keep state throughout the page. (This may not be best practice but it's highly convenient)</p> +<p>This is a very light weight Session model which handles most situations. Read through the code and comments below. The model simply has a login, logout and check function. Again we have hooked into jQuery <code>ajaxPrefilter</code> to allow for csrf tokens and also telling jQuery to send cookies with the <code>withCredentials</code> property. The model relies heavily on it’s <code>auth</code> property. Throughout your application, each view can simply bind to <code>change:auth</code> on the Session model and react accordingly. Because we return this AMD module instantiated using the new keyword, then it will keep state throughout the page. (This may not be best practice but it’s highly convenient)</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// views/app.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// views/app.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span> @@ -711,17 +767,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">SessionModel</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: This session model is missing one useful feature. If a user looses auth when navigating your application then the application should set {auth: false} on this model. To do this, in the <code>ajaxPrefilter</code> edit outgoing <code>success</code> functions to check if the server response was {auth: false} and then call the original <code>success()</code> function.</em></p> -<h2>Hooking up views to listen to changes in <code>auth</code></h2> +<h2 id="hooking-up-views-to-listen-to-changes-in-auth">Hooking up views to listen to changes in <code>auth</code></h2> -<p>Now that we have a Session model, let's hook up our <code>login/logout</code> view to listen to changes in <code>auth</code>. When creating the view we use <code>on</code> to bind a listener to the <code>auth</code> attribute of our model. Everytime it changes we will re-render the view which will conditionally load a template depending on the value of <code>Session.get('auth')</code>.</p> +<p>Now that we have a Session model, let’s hook up our <code>login/logout</code> view to listen to changes in <code>auth</code>. When creating the view we use <code>on</code> to bind a listener to the <code>auth</code> attribute of our model. Everytime it changes we will re-render the view which will conditionally load a template depending on the value of <code>Session.get('auth')</code>.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// models/session.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// models/session.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -768,15 +822,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">ExamplePage</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>.serializeObject</code> is not a native jQuery function and I have included it as <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/js/views/app.js">app.js</a> in the demo folder. <code>creds</code> can be an object of any variation of inputs, regardless it will be converted to JSON and posted to the server like any normal Backbone model.</em></p> <p>Here are the templates we are using for our login view</p> -<div class="highlight"><pre><code class="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">login</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">login</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">form</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;login&quot;</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nx">label</span> <span class="k">for</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="o">&gt;</span><span class="nx">Username</span><span class="o">&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&quot;username&quot;</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">required</span> <span class="nx">autofocus</span><span class="o">&gt;</span> @@ -785,60 +837,54 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">logout</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;</span><span class="nx">Hello</span><span class="p">,</span> <span class="o">&lt;%=</span> <span class="nx">username</span> <span class="o">%&gt;</span><span class="p">.</span> <span class="nx">Time</span> <span class="nx">to</span> <span class="nx">logout</span><span class="o">?&lt;</span><span class="err">/p&gt;</span> -<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;logout&quot;</span><span class="o">&gt;</span><span class="nx">Logout</span><span class="o">&lt;</span><span class="err">/button&gt;</span> -</code></pre></div> - +<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;logout&quot;</span><span class="o">&gt;</span><span class="nx">Logout</span><span class="o">&lt;</span><span class="err">/button&gt;</span></code></pre></div> <p>This wraps up setting up the client, there are some notable points to make sure this technique works.</p> <ul> -<li>You must use <code>withCredentials</code> supplied by jQuery - session.js</li> -<li>You must send your request with csrf tokens for security - session.js</li> -<li>You should wrap your applications entry pointer (router in this example) in a check auth function - app.js</li> -<li>You must point your application at the right server - app.js</li> + <li>You must use <code>withCredentials</code> supplied by jQuery - session.js</li> + <li>You must send your request with csrf tokens for security - session.js</li> + <li>You should wrap your applications entry pointer (router in this example) in a check auth function - app.js</li> + <li>You must point your application at the right server - app.js</li> </ul> - -<h2>Building a compatible server</h2> +<h2 id="building-a-compatible-server">Building a compatible server</h2> <p>This tutorial uses node.js, express.js and a modified csrf.js library. An example server.js file exist in the <code>examples/cross-domain</code> folder. When inside the folder simply type <code>npm install -d</code> to install the dependencies and then <code>node server.js</code> to start the server. Again, make sure your <code>app.js</code> points at the correct server.</p> <p>The server has to do a few things;</p> <ul> -<li>Allow CORS request</li> -<li>Implement csrf protection</li> -<li>Allow jQuery to send credentials</li> -<li>Set a whitelist of allowed domains</li> -<li>Configure the correct response headers</li> + <li>Allow CORS request</li> + <li>Implement csrf protection</li> + <li>Allow jQuery to send credentials</li> + <li>Set a whitelist of allowed domains</li> + <li>Configure the correct response headers</li> </ul> - <p>To save you sometime here are some gotchas;</p> <ul> -<li>When sending <code>withCredentials</code> you must set correct response header <code>Access-Control-Allow-Credentials: true</code>. Also as a security policy browsers do not allow <code>Access-Control-Allow-Origin</code> to be set to <code>*</code>. So the origin of the request has to be known and trusted, so in the example below we use an of white listed domains.</li> -<li>jQuery ajax will trigger the browser to send these headers to enforce security <code>origin, x-requested-with, accept</code> so our server must allow them.</li> -<li>The browser might send out a <code>pre-flight</code> request to verify that it can talk to the server. The server must return <code>200 OK</code> on these <code>pre-flight</code> request.</li> + <li>When sending <code>withCredentials</code> you must set correct response header <code>Access-Control-Allow-Credentials: true</code>. Also as a security policy browsers do not allow <code>Access-Control-Allow-Origin</code> to be set to <code>*</code>. So the origin of the request has to be known and trusted, so in the example below we use an of white listed domains.</li> + <li>jQuery ajax will trigger the browser to send these headers to enforce security <code>origin, x-requested-with, accept</code> so our server must allow them.</li> + <li>The browser might send out a <code>pre-flight</code> request to verify that it can talk to the server. The server must return <code>200 OK</code> on these <code>pre-flight</code> request.</li> </ul> - <p>Be sure to read this Mozilla <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">documentation</a> on the above.</p> -<h2>Example node server</h2> +<h2 id="example-node-server">Example node server</h2> <p>This server below implements everything we have talked about so far. It should be relatively easy to see how would translate into other frameworks and languages. <code>app.configure</code> runs the specified libraries against every request. We have told the server that on each request it should check the csrf token and check if the origin domain is white-listed. If so we edit each request to contain the appropriate headers.</p> <p>This server has 3 endpoints, that are pseudo-restful;</p> <ul> -<li>POST /session - Login - Sets the session username and returns a csrf token for the user to use</li> -<li>DELETE /session - Logout - Destroys the session and regenerates a new csrf token if the user wants to re-login</li> -<li>GET /session - Checks Auth - Simply returns if auth is true or false, if true then also returns some session details</li> + <li>POST /session - Login - Sets the session username and returns a csrf token for the user to use</li> + <li>DELETE /session - Logout - Destroys the session and regenerates a new csrf token if the user wants to re-login</li> + <li>GET /session - Checks Auth - Simply returns if auth is true or false, if true then also returns some session details</li> </ul> - -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">connect</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;connect&#39;</span><span class="p">);</span> <span class="c1">// Custom csrf library</span> @@ -904,13 +950,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="p">});</span> -<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">8000</span><span class="p">);</span> -</code></pre></div> - +<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">8000</span><span class="p">);</span></code></pre></div> -<p><em>Note: I wrote a custom csrf module for this which can be found in the example directory. It's based of connects and uses the <code>crypto</code> library. I didn't spend much time on it but other traditional csrf modules won't work because they aren't exactly built for this implementation technique.</em></p> +<p><em>Note: I wrote a custom csrf module for this which can be found in the example directory. It’s based of connects and uses the <code>crypto</code> library. I didn’t spend much time on it but other traditional csrf modules won’t work because they aren’t exactly built for this implementation technique.</em></p> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>This approach really hammers in the need for a well documented and designed API. A powerful API will let you do application iterations with ease.</p> @@ -924,14 +968,13 @@ We should setup any useful containers that might be used by our Backbone views.& <p><a href="http://backbonetutorials.com/examples/cross-domain/">Example Demo</a></p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">cross-site xmlhttprequest with CORS</a></li> -<li><a href="http://www.w3.org/TR/cors/">Cross-Origin Resource Sharing</a></li> -<li><a href="http://www.kendoui.com/blogs/teamblog/posts/11-10-04/using_cors_with_all_modern_browsers.aspx">Using CORS with All (Modern) Browsers</a></li> + <li><a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">cross-site xmlhttprequest with CORS</a></li> + <li><a href="http://www.w3.org/TR/cors/">Cross-Origin Resource Sharing</a></li> + <li><a href="http://www.kendoui.com/blogs/teamblog/posts/11-10-04/using_cors_with_all_modern_browsers.aspx">Using CORS with All (Modern) Browsers</a></li> </ul> - </content> </entry> @@ -940,9 +983,9 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/infinite-scrolling"/> <updated>2011-04-28T00:00:00+10:00</updated> <id>http://backbonetutorials.com/infinite-scrolling</id> - <content type="html"><h1>Lightweight Infinite Scrolling using Twitter API</h1> + <content type="html"><h1 id="lightweight-infinite-scrolling-using-twitter-api">Lightweight Infinite Scrolling using Twitter API</h1> -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>In this example we are going to build a widget that pulls in tweets and when the user scrolls to the bottom of the widget Backbone.js will re-sync with the server to bring down the next page of results.</p> @@ -952,15 +995,15 @@ We should setup any useful containers that might be used by our Backbone views.& <p><em>Note: This tutorial will use <a href="http://backbonetutorials.com/organizing-backbone-using-modules">AMD</a> for modularity.</em></p> -<h2>The Twitter Collection</h2> +<h2 id="the-twitter-collection">The Twitter Collection</h2> -<p>Twitter offers a jsonp API for browsing tweets. The first thing to note is that we have to append '&amp;callback?' to allow cross domain Ajax calls which is a feature of <a href="http://en.wikipedia.org/wiki/JSONP">jsonp</a>.</p> +<p>Twitter offers a jsonp API for browsing tweets. The first thing to note is that we have to append ‘&amp;callback?’ to allow cross domain Ajax calls which is a feature of <a href="http://en.wikipedia.org/wiki/JSONP">jsonp</a>.</p> -<p>Using the 'q' and 'page' query parameters we can find the results we are after. In the collection definition below we have set some defaults which can be overridden at any point.</p> +<p>Using the ‘q’ and ‘page’ query parameters we can find the results we are after. In the collection definition below we have set some defaults which can be overridden at any point.</p> -<p>Twitter's search API actually returns a whole bunch of meta information alongside the results. Though this is a problem for Backbone.js because a Collection expects to be populated with an array of objects. So in our collection definition we can override the Backbone.js default parse function to instead choose the correct property to populate the collection.</p> +<p>Twitter’s search API actually returns a whole bunch of meta information alongside the results. Though this is a problem for Backbone.js because a Collection expects to be populated with an array of objects. So in our collection definition we can override the Backbone.js default parse function to instead choose the correct property to populate the collection. </p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// collections/twitter.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// collections/twitter.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -980,24 +1023,20 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="k">return</span> <span class="nx">Tweets</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: Feel free to attach the meta information returned by Twitter to the collection itself e.g.</em></p> -<div class="highlight"><pre><code class="javascript"><span class="nx">parse</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">)</span> <span class="p">{</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">parse</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">completed_in</span> <span class="o">=</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">completed_in</span> <span class="k">return</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">results</span><span class="p">;</span> -<span class="p">},</span> -</code></pre></div> - +<span class="p">},</span></code></pre></div> -<h2>Setting up the View</h2> +<h2 id="setting-up-the-view">Setting up the View</h2> -<p>The first thing to do is to load our Twitter collection and template into the widget module. We should attach our collection to our view in our <code>initialize</code> function. <code>loadResults</code> will be responsible for calling fetch on our Twitter collection. On success we will append the latest results to our widget using our template. Our Backbone.js <code>events</code> will listen for <code>scroll</code> on the current <code>el</code> of the view which is '.twitter-widget'. If the current <code>scrollTop</code> is at the bottom then we simply increment the Twitter collections current page property and call <code>loadResults</code> again.</p> +<p>The first thing to do is to load our Twitter collection and template into the widget module. We should attach our collection to our view in our <code>initialize</code> function. <code>loadResults</code> will be responsible for calling fetch on our Twitter collection. On success we will append the latest results to our widget using our template. Our Backbone.js <code>events</code> will listen for <code>scroll</code> on the current <code>el</code> of the view which is ‘.twitter-widget’. If the current <code>scrollTop</code> is at the bottom then we simply increment the Twitter collections current page property and call <code>loadResults</code> again.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// views/twitter/widget.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// views/twitter/widget.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -1044,28 +1083,24 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">TwitterWidget</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>triggerPoint</code> will allow you to set an offset where the user has to scroll to before loading the next page</em></p> -<h2>The widget template</h2> +<h2 id="the-widget-template">The widget template</h2> -<p>Our view above passes into our underscore template the variable tweets which we can simply iterate over with using underscore's <code>each</code> method.</p> +<p>Our view above passes into our underscore template the variable tweets which we can simply iterate over with using underscore’s <code>each</code> method.</p> -<div class="highlight"><pre><code class="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">twitter</span><span class="o">/</span><span class="nx">list</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">twitter</span><span class="o">/</span><span class="nx">list</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">ul</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;tweets&quot;</span><span class="o">&gt;</span> <span class="o">&lt;%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">tweets</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">tweet</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span> <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;&lt;%=</span> <span class="nx">tweet</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;text&#39;</span><span class="p">)</span> <span class="o">%&gt;&lt;</span><span class="err">/li&gt; </span> <span class="o">&lt;%</span> <span class="p">});</span> <span class="o">%&gt;</span> -<span class="o">&lt;</span><span class="err">/ul&gt;</span> -</code></pre></div> +<span class="o">&lt;</span><span class="err">/ul&gt;</span></code></pre></div> - -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>This is a very lightweight but robust infinite scroll example. There are caveats to using infinite scroll in UI/UX so make sure to only use it when applicable.</p> @@ -1080,91 +1115,85 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/nodejs-restify-mongodb-mongoose"/> <updated>2011-04-22T00:00:00+10:00</updated> <id>http://backbonetutorials.com/nodejs-restify-mongodb-mongoose</id> - <content type="html"><h1>Simple example - Node.js, Restify, MongoDb and Mongoose</h1> + <content type="html"><h1 id="simple-example---nodejs-restify-mongodb-and-mongoose">Simple example - Node.js, Restify, MongoDb and Mongoose</h1> -<p>Before I start, the Backbone.js parts of this tutorial will be using techniques described in "Organizing your application using <a href="http://backbonetutorials.com/organizing-backbone-using-modules/">Modules</a> to construct a simple guestbook.</p> +<p>Before I start, the Backbone.js parts of this tutorial will be using techniques described in “Organizing your application using <a href="http://backbonetutorials.com/organizing-backbone-using-modules/">Modules</a> to construct a simple guestbook.</p> -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> <p><a href="https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify">Example Codebase</a></p> -<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/">Example Demo</a></p> +<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/app">Example Demo</a></p> <p>This tutorial will assist you in saving data(Backbone.js Models) to MongoDb and retrieving a list(Backbone.js Collections) of them back.</p> -<h2>The technologies</h2> +<h2 id="the-technologies">The technologies</h2> <p>This stack is great for rapid prototyping and highly intuitive. Personal note: I love using JavaScript as my only language for the entire application (FrontEnd/BackEnd/API/Database). Restify is still in early development but is essentially just an extension of Express. So for anyone needing more stability you can easily just substitute Express in.</p> -<h3>Node.js</h3> +<h3 id="nodejs">Node.js</h3> -<p>"Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices."</p> +<p>“Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.”</p> -<h3>Restify</h3> +<h3 id="restify">Restify</h3> -<p>"Restify is a node.js module built specifically to enable you to build correct REST web services. It borrows heavily from express (intentionally) as that is more or less the de facto API for writing web applications on top of node.js."</p> +<p>“Restify is a node.js module built specifically to enable you to build correct REST web services. It borrows heavily from express (intentionally) as that is more or less the de facto API for writing web applications on top of node.js.”</p> -<h3>MongoDb</h3> +<h3 id="mongodb">MongoDb</h3> -<p>"MongoDB (from "humongous") is a scalable, high-performance, open source NoSQL database."</p> +<p>“MongoDB (from “humongous”) is a scalable, high-performance, open source NoSQL database.”</p> -<h3>Mongoose</h3> +<h3 id="mongoose">Mongoose</h3> -<p>"Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment."</p> +<p>“Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.”</p> -<h2>Building the server</h2> +<h2 id="building-the-server">Building the server</h2> <p>In the example repository there is a server.js example which can be executed by running <code>node server.js</code>. If you use this example in your own applications make sure to update the Backbone.js <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/models/message.js">Model</a> and <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/collections/messages.js">Collection</a> definitions to match your server address.</p> -<h2>Restify configuration</h2> +<h2 id="restify-configuration">Restify configuration</h2> <p>The first thing to do is require the Restify module. Restify will be in control of handling our restful endpoints and returning the appropriate JSON.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">restify</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;restify&#39;</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">restify</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;restify&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">server</span> <span class="o">=</span> <span class="nx">restify</span><span class="p">.</span><span class="nx">createServer</span><span class="p">();</span> -<span class="nx">server</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">restify</span><span class="p">.</span><span class="nx">bodyParser</span><span class="p">());</span> -</code></pre></div> - +<span class="nx">server</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">restify</span><span class="p">.</span><span class="nx">bodyParser</span><span class="p">());</span></code></pre></div> <p>Note: bodyParser() takes care of turning your request data into a JavaScript object on the server automatically.</p> -<h2>MongoDb/Mongoose configuration</h2> +<h2 id="mongodbmongoose-configuration">MongoDb/Mongoose configuration</h2> <p>We simply want to require the MongoDb module and pass it a MongoDb authentication URI e.g. mongodb://username:server@mongoserver:10059/somecollection</p> <p>The code below presupposes you have another file in the same directory called <code>config.js</code>. Your config should never be public as it contains your credentials. So for this repository I have added <code>config.js</code> to my <code>.gitignore</code> but added in a <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/config-sample.js">sample config</a>.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">mongoose</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;mongoose/&#39;</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">mongoose</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;mongoose/&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">config</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./config&#39;</span><span class="p">);</span> <span class="nx">db</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">creds</span><span class="p">.</span><span class="nx">mongoose_auth</span><span class="p">),</span> -<span class="nx">Schema</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">;</span> -</code></pre></div> - +<span class="nx">Schema</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">;</span></code></pre></div> -<h2>Mongoose Schema</h2> +<h2 id="mongoose-schema">Mongoose Schema</h2> <p>Mongoose introduces a concept of <a href="http://mongoosejs.com/docs/model-definition.html">model/schema</a> enforcing types which allow for easier input validation etc</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Create a schema for our data</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Create a schema for our data</span> <span class="kd">var</span> <span class="nx">MessageSchema</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Schema</span><span class="p">({</span> <span class="nx">message</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span> <span class="nx">date</span><span class="o">:</span> <span class="nb">Date</span> <span class="p">});</span> <span class="c1">// Use the schema to register a model with MongoDb</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">&#39;Message&#39;</span><span class="p">,</span> <span class="nx">MessageSchema</span><span class="p">);</span> -<span class="kd">var</span> <span class="nx">Message</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">&#39;Message&#39;</span><span class="p">);</span> -</code></pre></div> - +<span class="kd">var</span> <span class="nx">Message</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">&#39;Message&#39;</span><span class="p">);</span></code></pre></div> <p><em>Note: <code>Message</code> can now be used for all things CRUD related.</em></p> -<h2>Setting up the routes</h2> +<h2 id="setting-up-the-routes">Setting up the routes</h2> <p>Just like in Backbone, Restify allows you to configure different routes and their associated callbacks. In the code below we define two routes. One for saving new messages and one for retrieving all messages. After we have created our function definitions, we attach them to either GET/POST/PUT/DELETE on a particular restful endpoint e.g. GET /messages</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// This function is responsible for returning all entries for the Message model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// This function is responsible for returning all entries for the Message model</span> <span class="kd">function</span> <span class="nx">getMessages</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Resitify currently has a bug which doesn&#39;t allow you to set default headers</span> <span class="c1">// This headers comply with CORS and allow us to server our response to any origin</span> @@ -1193,9 +1222,7 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="c1">// Set up our routes and start the server</span> <span class="nx">server</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/messages&#39;</span><span class="p">,</span> <span class="nx">getMessages</span><span class="p">);</span> -<span class="nx">server</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/messages&#39;</span><span class="p">,</span> <span class="nx">postMessage</span><span class="p">);</span> -</code></pre></div> - +<span class="nx">server</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/messages&#39;</span><span class="p">,</span> <span class="nx">postMessage</span><span class="p">);</span></code></pre></div> <p>This wraps up the server side of things, if you follow the <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/server.js">example</a> then you should see something like</p> @@ -1203,36 +1230,33 @@ We should setup any useful containers that might be used by our Backbone views.& <p><em>Note: Again you must remember to change the <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/models/message.js">Model</a> and <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/collections/messages.js">Collection</a> definitions to match your server address.</em></p> -<h2>Setting up the client (Backbone.js)</h2> +<h2 id="setting-up-the-client-backbonejs">Setting up the client (Backbone.js)</h2> -<p>I've actually used the latest copy of <a href="http://backboneboilerplate.com">http://backboneboilerplate.com</a> to set up the example page.</p> +<p>I’ve actually used the latest copy of <a href="http://backboneboilerplate.com">http://backboneboilerplate.com</a> to set up the example page.</p> <p>The important files you will want to check out are;</p> <ul> -<li>views/dashboard/page.js</li> -<li>views/guestbook/form.js</li> -<li>views/guestbook/list.js</li> -<li>models/message.js</li> -<li>collections/messages.js</li> -<li>templates/guestbook/</li> + <li>views/dashboard/page.js</li> + <li>views/guestbook/form.js</li> + <li>views/guestbook/list.js</li> + <li>models/message.js</li> + <li>collections/messages.js</li> + <li>templates/guestbook/</li> </ul> - -<h2>Saving a message</h2> +<h2 id="saving-a-message">Saving a message</h2> <p>First of all we want to setup a <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/templates/guestbook/form.html">template</a> for showing our form that creates new messages.</p> -<div class="highlight"><pre><code class="javascript"><span class="o">&lt;</span><span class="nx">textarea</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;message&quot;</span><span class="o">&gt;&lt;</span><span class="err">/textarea&gt;</span> -<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;post-message&quot;</span><span class="o">&gt;</span><span class="nx">Post</span> <span class="nx">Message</span><span class="o">&lt;</span><span class="err">/button&gt;</span> -</code></pre></div> - +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o">&lt;</span><span class="nx">textarea</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;message&quot;</span><span class="o">&gt;&lt;</span><span class="err">/textarea&gt;</span> +<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;post-message&quot;</span><span class="o">&gt;</span><span class="nx">Post</span> <span class="nx">Message</span><span class="o">&lt;</span><span class="err">/button&gt;</span></code></pre></div> <p>This template gets inserted into the DOM by <code>views/guestbook/form.js</code>, this Backbone view also handles the interaction of the form and the posting of the new data.</p> <p>Let us create a Backbone Model that has the correct URL for our restful interface.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span> <span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">)</span> <span class="p">{</span> @@ -1240,13 +1264,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;http://localhost:8080/messages&#39;</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">Message</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>We can see how we require our predefined model for messages and also our form template.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -1274,17 +1296,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">GuestbookForm</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>trigger</code> is from Backbone Events, I binded a listener to this view in <code>views/dashboard/page.js</code> so when a new message is submitted, the list is re-rendered. We are setting the date of the POST on the server so there is no need to pass it up.</em></p> -<h2>Retrieving a list of messages</h2> +<h2 id="retrieving-a-list-of-messages">Retrieving a list of messages</h2> <p>We setup a route on our server to generate a list of all available messages at <code>GET /messages</code>. So we need to define a collection with the appropriate <code>url</code> to fetch this data down.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -1296,13 +1316,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="k">return</span> <span class="nx">Messages</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>Now that we have a collection to use we can setup our <code>views/list.js</code> to require the collection and trigger a fetch. Once the fetch is complete we want to render our returned data to a template and insert it into the DOM.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -1322,30 +1340,26 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">GuestbookList</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>The template file should iterate over <code>messages.models</code> which is an array and print out a HTML fragment for each model.</p> -<div class="highlight"><pre><code class="javascript"><span class="o">&lt;%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o">&lt;%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span> <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;&lt;%=</span> <span class="nx">message</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;message&#39;</span><span class="p">)</span> <span class="o">%&gt;&lt;</span><span class="err">/p&gt;</span> <span class="o">&lt;</span><span class="nx">em</span><span class="o">&gt;&lt;%=</span> <span class="nx">message</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;date&#39;</span><span class="p">)</span> <span class="o">%&gt;&lt;</span><span class="err">/em&gt;</span> -<span class="o">&lt;%</span> <span class="p">});</span> <span class="o">%&gt;</span> -</code></pre></div> - +<span class="o">&lt;%</span> <span class="p">});</span> <span class="o">%&gt;</span></code></pre></div> <p>This actually sums up everything you need to know to implement this simple example.</p> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p><a href="https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify">Example Codebase</a></p> -<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/">Example Demo</a></p> +<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/app">Example Demo</a></p> -<p>In this example you should really be using relative URL's in your collections/models and instead setting a baseUrl in a config file or by placing your index.html file on the restful server.</p> +<p>In this example you should really be using relative URL’s in your collections/models and instead setting a baseUrl in a config file or by placing your index.html file on the restful server.</p> <p>This example is hosted on GitHub therefore we had to include the absolute URL to the server which is hosted on nodejitsu.com</p> @@ -1355,7 +1369,7 @@ We should setup any useful containers that might be used by our Backbone views.& <p>Get in touch with me on twitter, comments or GitHub!</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <p><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></p> </content> @@ -1366,37 +1380,35 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/why-would-you-use-backbone"/> <updated>2011-02-01T00:00:00+10:00</updated> <id>http://backbonetutorials.com/why-would-you-use-backbone</id> - <content type="html"><h1>Why do you need Backbone.js?</h1> + <content type="html"><h1 id="why-do-you-need-backbonejs">Why do you need Backbone.js?</h1> <p>Building single-page web apps or complicated user interfaces will get extremely difficult by simply using <a href="http://jquery.com">jQuery</a> or <a href="http://mootools.net">MooTools</a>. The problem is standard JavaScript libraries are great at what they do - and without realizing it you can build an entire application without any formal structure. You will with ease turn your application into a nested pile of jQuery callbacks, all tied to concrete DOM elements.</p> -<p>I shouldn't need to explain why building something without any structure is a bad idea. Of course you can always invent your own way of structuring your application but you miss out on the benefits of the open source community.</p> +<p>I shouldn’t need to explain why building something without any structure is a bad idea. Of course you can always invent your own way of structuring your application but you miss out on the benefits of the open source community.</p> -<h2>Why single page applications are the future</h2> +<h2 id="why-single-page-applications-are-the-future">Why single page applications are the future</h2> <p>Backbone.js enforces that communication to the server should be done entirely through a RESTful API. The web is currently trending such that all data/content will be exposed through an API. This is because the browser is no longer the only client, we now have mobile devices, tablet devices, Google Goggles and electronic fridges etc.</p> -<h2>So how does Backbone.js help?</h2> +<h2 id="so-how-does-backbonejs-help">So how does Backbone.js help?</h2> <p>Backbone is an incredibly small library for the amount of functionality and structure it gives you. It is essentially MVC for the client and allows you to make your code modular. If you read through some of the beginner tutorials the benefits will soon become self evident and due to Backbone.js light nature you can incrementally include it in any current or future projects.</p> -<h2>Other frameworks</h2> +<h2 id="other-frameworks">Other frameworks</h2> <p>If you are looking for comparisons to build your single page application, try some of these resourceful links.</p> <ul> -<li><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">A feature comparison of different frontend frameworks</a></li> -<li><a href="http://addyosmani.github.com/todomvc/">Todo MVC - Todo list implemented in the many different types of frontend frameworks</a></li> + <li><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">A feature comparison of different frontend frameworks</a></li> + <li><a href="http://addyosmani.github.com/todomvc/">Todo MVC - Todo list implemented in the many different types of frontend frameworks</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/FND">FND</a></li> + <li><a href="https://github.com/FND">FND</a></li> </ul> - <p><strong>If you questions regarding why you should choose Backbone.js as your framework, please leave a comment below</strong></p> </content> </entry> @@ -1406,31 +1418,31 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/what-is-a-model"/> <updated>2011-01-29T00:00:00+10:00</updated> <id>http://backbonetutorials.com/what-is-a-model</id> - <content type="html"><h1>What is a model?</h1> + <content type="html"><h1 id="what-is-a-model">What is a model?</h1> -<p>Across the internet the definition of <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> is so diluted that it's hard to tell what exactly your model should be doing. The authors of backbone.js have quite a clear definition of what they believe the model represents in backbone.js.</p> +<p>Across the internet the definition of <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> is so diluted that it’s hard to tell what exactly your model should be doing. The authors of backbone.js have quite a clear definition of what they believe the model represents in backbone.js.</p> -<blockquote><p>Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.</p></blockquote> +<blockquote> + <p>Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.</p> +</blockquote> -<p>So for the purpose of the tutorial let's create a model.</p> +<p>So for the purpose of the tutorial let’s create a model.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Welcome to this world&quot;</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span> -</code></pre></div> - + <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span></code></pre></div> -<p>So <em>initialize()</em> is triggered whenever you create a new instance of a model( models, collections and views work the same way ). You don't have to include it in your model declaration but you will find yourself using it more often than not.</p> +<p>So <em>initialize()</em> is triggered whenever you create a new instance of a model( models, collections and views work the same way ). You don’t have to include it in your model declaration but you will find yourself using it more often than not.</p> -<h2>Setting attributes</h2> +<h2 id="setting-attributes">Setting attributes</h2> <p>Now we want to pass some parameters when we create an instance of our model.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Welcome to this world&quot;</span><span class="p">);</span> <span class="p">}</span> @@ -1439,18 +1451,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> <span class="c1">// or we can set afterwards, these operations are equivelent</span> <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">();</span> - <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> - -</code></pre></div> - + <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span></code></pre></div> -<p>So passing a JavaScript object to our constructor is the same as calling <em>model.set()</em>. Now that these models have attributes set we need to be able to retrieve them.</p> +<p>So passing a JavaScript object to our constructor is the same as calling <em>model.set()</em>. Now that these models have attributes set we need to be able to retrieve them. </p> -<h2>Getting attributes</h2> +<h2 id="getting-attributes">Getting attributes</h2> <p>Using the <em>model.get()</em> method we can access model properties at anytime.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Welcome to this world&quot;</span><span class="p">);</span> <span class="p">}</span> @@ -1460,16 +1469,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">age</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;age&quot;</span><span class="p">);</span> <span class="c1">// 67</span> <span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">);</span> <span class="c1">// &quot;Thomas&quot;</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span> - -</code></pre></div> - + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span></code></pre></div> -<h2>Setting model defaults</h2> +<h2 id="setting-model-defaults">Setting model defaults</h2> -<p>Sometimes you will want your model to contain default values. This can easily be accomplished by setting a property name 'defaults' in your model declaration.</p> +<p>Sometimes you will want your model to contain default values. This can easily be accomplished by setting a property name ‘defaults’ in your model declaration.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Fetus&#39;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> @@ -1484,16 +1490,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">age</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;age&quot;</span><span class="p">);</span> <span class="c1">// 67</span> <span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">);</span> <span class="c1">// &quot;Thomas&quot;</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span> - -</code></pre></div> - + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span></code></pre></div> -<h2>Manipulating model attributes</h2> +<h2 id="manipulating-model-attributes">Manipulating model attributes</h2> <p>Models can contain as many custom methods as you like to manipulate attributes. By default all methods are public.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Fetus&#39;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> @@ -1509,18 +1512,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">,</span> <span class="nx">child</span><span class="o">:</span> <span class="s1">&#39;Ryan&#39;</span><span class="p">});</span> <span class="nx">person</span><span class="p">.</span><span class="nx">adopt</span><span class="p">(</span><span class="s1">&#39;John Resig&#39;</span><span class="p">);</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;John Resig&#39;</span> - -</code></pre></div> - + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;John Resig&#39;</span></code></pre></div> -<p>So we can implement methods to get/set and perform other calculations using attributes from our model at any time.</p> +<p>So we can implement methods to get/set and perform other calculations using attributes from our model at any time. </p> -<h2>Listening for changes to the model</h2> +<h2 id="listening-for-changes-to-the-model">Listening for changes to the model</h2> -<p>Now onto one of the more useful parts of using a library such as backbone. All attributes of a model can have listeners bound to them to detect changes to their values. In our initialize function we are going to bind a function call everytime we change the value of our attribute. In this case if the name of our "person" changes we will alert their new name.</p> +<p>Now onto one of the more useful parts of using a library such as backbone. All attributes of a model can have listeners bound to them to detect changes to their values. In our initialize function we are going to bind a function call everytime we change the value of our attribute. In this case if the name of our “person” changes we will alert their new name.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Fetus&#39;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span> @@ -1535,13 +1535,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> - <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Stewie Griffin&#39;</span><span class="p">});</span> <span class="c1">// This triggers a change and will alert()</span> -</code></pre></div> + <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Stewie Griffin&#39;</span><span class="p">});</span> <span class="c1">// This triggers a change and will alert()</span></code></pre></div> +<p>So we can bind the change listener to individual attributes or if we like simply ‘<em>this.on(“change”, function(model){});</em>’ to listen for changes to all attributes of the model.</p> -<p>So we can bind the change listener to individual attributes or if we like simply '<em>this.on("change", function(model){});</em>' to listen for changes to all attributes of the model.</p> - -<h2>Interacting with the server</h2> +<h2 id="interacting-with-the-server">Interacting with the server</h2> <p>Models are used to represent data from your server and actions you perform on them will be translated to RESTful operations.</p> @@ -1553,22 +1551,20 @@ We should setup any useful containers that might be used by our Backbone views.& <p>Our model definition shall thus look like;</p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">urlRoot</span><span class="o">:</span> <span class="s1">&#39;/user&#39;</span><span class="p">,</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s1">&#39;&#39;</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Creating a new model</h3> +<h3 id="creating-a-new-model">Creating a new model</h3> -<p>If we wish to create a new user on the server then we will instantiate a new UserModel and call <code>save</code>. If the <code>id</code> attribute of the model is <code>null</code>, Backbone.js will send a POST request to the urlRoot of the server.</p> +<p>If we wish to create a new user on the server then we will instantiate a new UserModel and call <code>save</code>. If the <code>id</code> attribute of the model is <code>null</code>, Backbone.js will send a POST request to the urlRoot of the server. </p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">urlRoot</span><span class="o">:</span> <span class="s1">&#39;/user&#39;</span><span class="p">,</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> @@ -1588,21 +1584,19 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">})</span> -</code></pre></div> - + <span class="p">})</span></code></pre></div> <p>Our table should now have the values</p> -<p>1, 'Thomas', 'thomasalwyndavis@gmail.com'</p> +<p>1, ‘Thomas’, ‘thomasalwyndavis@gmail.com’</p> -<h3>Getting a model</h3> +<h3 id="getting-a-model">Getting a model</h3> <p>Now that we have saved a new user model, we can retrieve it from the server. We know that the <code>id</code> is 1 from the above example.</p> -<p>If we instantiate a model with an <code>id</code>, Backbone.js will automatically perform a get request to the urlRoot + '/id' (conforming to RESTful conventions)</p> +<p>If we instantiate a model with an <code>id</code>, Backbone.js will automatically perform a get request to the urlRoot + ‘/id’ (conforming to RESTful conventions)</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span><span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">});</span> <span class="c1">// The fetch below will perform GET /user/1</span> @@ -1611,16 +1605,14 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">})</span> -</code></pre></div> - + <span class="p">})</span></code></pre></div> -<h3>Updating a model</h3> +<h3 id="updating-a-model">Updating a model</h3> <p>Now that we have a model that exist on the server we can perform an update using a PUT request. We will use the <code>save</code> api call which is intelligent and will send a PUT request instead of a POST request if an <code>id</code> is present(conforming to RESTful conventions)</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Thomas&#39;</span><span class="p">,</span> @@ -1634,15 +1626,13 @@ We will use the <code>save</code> api call which is intelligent and <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Deleting a model</h3> +<h3 id="deleting-a-model">Deleting a model</h3> <p>When a model has an <code>id</code> we know that it exist on the server, so if we wish to remove it from the server we can call <code>destroy</code>. <code>destroy</code> will fire off a DELETE /user/id (conforming to RESTful conventions).</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Thomas&#39;</span><span class="p">,</span> @@ -1655,27 +1645,22 @@ We will use the <code>save</code> api call which is intelligent and <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;Destroyed&#39;</span><span class="p">);</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Tips and Tricks</h3> +<h3 id="tips-and-tricks">Tips and Tricks</h3> <p><em>Get all the current attributes</em></p> -<div class="highlight"><pre><code class="javascript"> - <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> <span class="kd">var</span> <span class="nx">attributes</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">();</span> <span class="c1">// { name: &quot;Thomas&quot;, age: 67}</span> <span class="cm">/* This simply returns a copy of the current attributes. */</span> <span class="kd">var</span> <span class="nx">attributes</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">attributes</span><span class="p">;</span> - <span class="cm">/* The line above gives a direct reference to the attributes and you should be careful when playing with it. Best practise would suggest that you use .set() to edit attributes of a model to take advantage of backbone listeners. */</span> -</code></pre></div> - + <span class="cm">/* The line above gives a direct reference to the attributes and you should be careful when playing with it. Best practise would suggest that you use .set() to edit attributes of a model to take advantage of backbone listeners. */</span></code></pre></div> <p><em>Validate data before you set or save it</em></p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="c1">// If you return a string from the validate function,</span> <span class="c1">// Backbone will throw an error</span> <span class="nx">validate</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">attributes</span> <span class="p">){</span> @@ -1698,17 +1683,13 @@ We will use the <code>save</code> api call which is intelligent and <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span> <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Dr Manhatten&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">});</span> - <span class="c1">// God have mercy on our souls</span> - -</code></pre></div> - + <span class="c1">// God have mercy on our souls</span></code></pre></div> -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/utkarshkukreti">Utkarsh Kukreti</a></li> + <li><a href="https://github.com/utkarshkukreti">Utkarsh Kukreti</a></li> </ul> - </content> </entry> @@ -1717,15 +1698,15 @@ We will use the <code>save</code> api call which is intelligent and <link href="http://backbonetutorials.com/what-is-a-view"/> <updated>2011-01-28T00:00:00+10:00</updated> <id>http://backbonetutorials.com/what-is-a-view</id> - <content type="html"><h1>What is a view?</h1> + <content type="html"><h1 id="what-is-a-view">What is a view?</h1> -<p>Backbone views are used to reflect what your applications' data models look like. They are also used to listen to events and react accordingly. This tutorial will not be addressing how to bind models and collections to views but will focus on view functionality and how to use views with a JavaScript templating library, specifically <a href="http://documentcloud.github.com/underscore/#template">Underscore.js's _.template</a>.</p> +<p>Backbone views are used to reflect what your applications’ data models look like. They are also used to listen to events and react accordingly. This tutorial will not be addressing how to bind models and collections to views but will focus on view functionality and how to use views with a JavaScript templating library, specifically <a href="http://documentcloud.github.com/underscore/#template">Underscore.js’s _.template</a>.</p> -<p>We will be using <a href="http://jquery.com/">jQuery 1.8.2</a> as our DOM manipulator. It's possible to use other libraries such as <a href="http://mootools.net/">MooTools</a> or <a href="http://sizzlejs.com/">Sizzle</a>, but official Backbone.js documentation endorses jQuery. Backbone.View events may not work with other libraries other than jQuery.</p> +<p>We will be using <a href="http://jquery.com/">jQuery 1.8.2</a> as our DOM manipulator. It’s possible to use other libraries such as <a href="http://mootools.net/">MooTools</a> or <a href="http://sizzlejs.com/">Sizzle</a>, but official Backbone.js documentation endorses jQuery. Backbone.View events may not work with other libraries other than jQuery.</p> <p>For the purposes of this demonstration, we will be implementing a search box. <a href="http://jsfiddle.net/tBS4X/1/">A live example</a> can be found on jsFiddle.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Alerts suck.&quot;</span><span class="p">);</span> <span class="p">}</span> @@ -1733,39 +1714,35 @@ We will use the <code>save</code> api call which is intelligent and <span class="c1">// The initialize function is always called when instantiating a Backbone View.</span> <span class="c1">// Consider it the constructor of the class.</span> - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">();</span> -</code></pre></div> - + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">();</span></code></pre></div> -<h2>The "el" property</h2> +<h2 id="the-el-property">The “el” property</h2> -<p>The "el" property references the DOM object created in the browser. Every Backbone.js view has an "el" property, and if it not defined, Backbone.js will construct its own, which is an empty div element.</p> +<p>The “el” property references the DOM object created in the browser. Every Backbone.js view has an “el” property, and if it not defined, Backbone.js will construct its own, which is an empty div element.</p> -<p>Let us set our view's "el" property to div#search_container, effectively making Backbone.View the owner of the DOM element.</p> +<p>Let us set our view’s “el” property to div#search_container, effectively making Backbone.View the owner of the DOM element.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Alerts suck.&quot;</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Alerts suck.&quot;</span><span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><em>Note: Keep in mind that this binds the container element. Any events we trigger must be in this element.</em></p> -<h2>Loading a template</h2> +<h2 id="loading-a-template">Loading a template</h2> -<p>Backbone.js is dependent on Underscore.js, which includes its own micro-templating solution. Refer to <a href="http://documentcloud.github.com/underscore/">Underscore.js's documentation</a> for more information.</p> +<p>Backbone.js is dependent on Underscore.js, which includes its own micro-templating solution. Refer to <a href="http://documentcloud.github.com/underscore/">Underscore.js’s documentation</a> for more information.</p> -<p>Let us implement a "render()" function and call it when the view is initialized. The "render()" function will load our template into the view's "el" property using jQuery.</p> +<p>Let us implement a “render()” function and call it when the view is initialized. The “render()” function will load our template into the view’s “el” property using jQuery.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> <span class="o">&lt;</span><span class="nx">label</span><span class="o">&gt;</span><span class="nx">Search</span><span class="o">&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_input&quot;</span> <span class="o">/&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;button&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_button&quot;</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&quot;Search&quot;</span> <span class="o">/&gt;</span> @@ -1774,30 +1751,28 @@ We will use the <code>save</code> api call which is intelligent and <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> - <span class="p">},</span> - <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="c1">// Compile the template using underscore</span> - <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="p">{}</span> <span class="p">);</span> - <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> - <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> + <span class="p">},</span> + <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="c1">// Compile the template using underscore</span> + <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="p">{}</span> <span class="p">);</span> + <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> + <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><em>Tip: Place all your templates in a file and serve them from a CDN. This ensures your users will always have your application cached.</em></p> -<h2>Listening for events</h2> +<h2 id="listening-for-events">Listening for events</h2> -<p>To attach a listener to our view, we use the "events" attribute of Backbone.View. Remember that event listeners can only be attached to child elements of the "el" property. Let us attach a "click" listener to our button.</p> +<p>To attach a listener to our view, we use the “events” attribute of Backbone.View. Remember that event listeners can only be attached to child elements of the “el” property. Let us attach a “click” listener to our button.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> <span class="o">&lt;</span><span class="nx">label</span><span class="o">&gt;</span><span class="nx">Search</span><span class="o">&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_input&quot;</span> <span class="o">/&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;button&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_button&quot;</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&quot;Search&quot;</span> <span class="o">/&gt;</span> @@ -1824,15 +1799,13 @@ We will use the <code>save</code> api call which is intelligent and <span class="p">});</span> <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> +<span class="nt">&lt;/script&gt;</span></code></pre></div> - -<h2>Tips and Tricks</h2> +<h2 id="tips-and-tricks">Tips and Tricks</h2> <p><em>Using template variables</em></p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> <span class="c">&lt;!--</span> <span class="nx">Access</span> <span class="nx">template</span> <span class="nx">variables</span> <span class="kd">with</span> <span class="o">&lt;%=</span> <span class="o">%&gt;</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">label</span><span class="o">&gt;&lt;%=</span> <span class="nx">search_label</span> <span class="o">%&gt;&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_input&quot;</span> <span class="o">/&gt;</span> @@ -1842,48 +1815,44 @@ We will use the <code>save</code> api call which is intelligent and <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> - <span class="p">},</span> - <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="c1">//Pass variables in using Underscore.js Template</span> - <span class="kd">var</span> <span class="nx">variables</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">search_label</span><span class="o">:</span> <span class="s2">&quot;My Search&quot;</span> <span class="p">};</span> - <span class="c1">// Compile the template using underscore</span> - <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="nx">variables</span> <span class="p">);</span> - <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> - <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> - <span class="p">},</span> - <span class="nx">events</span><span class="o">:</span> <span class="p">{</span> - <span class="s2">&quot;click input[type=button]&quot;</span><span class="o">:</span> <span class="s2">&quot;doSearch&quot;</span> - <span class="p">},</span> - <span class="nx">doSearch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">event</span> <span class="p">){</span> - <span class="c1">// Button clicked, you can access the element that was clicked with event.currentTarget</span> - <span class="nx">alert</span><span class="p">(</span> <span class="s2">&quot;Search for &quot;</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_input&quot;</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - - -<h3>Relevant Links</h3> + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> + <span class="p">},</span> + <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="c1">//Pass variables in using Underscore.js Template</span> + <span class="kd">var</span> <span class="nx">variables</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">search_label</span><span class="o">:</span> <span class="s2">&quot;My Search&quot;</span> <span class="p">};</span> + <span class="c1">// Compile the template using underscore</span> + <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="nx">variables</span> <span class="p">);</span> + <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> + <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> + <span class="p">},</span> + <span class="nx">events</span><span class="o">:</span> <span class="p">{</span> + <span class="s2">&quot;click input[type=button]&quot;</span><span class="o">:</span> <span class="s2">&quot;doSearch&quot;</span> + <span class="p">},</span> + <span class="nx">doSearch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">event</span> <span class="p">){</span> + <span class="c1">// Button clicked, you can access the element that was clicked with event.currentTarget</span> + <span class="nx">alert</span><span class="p">(</span> <span class="s2">&quot;Search for &quot;</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_input&quot;</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> +<span class="nt">&lt;/script&gt;</span></code></pre></div> + +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://thomasdavis.github.com/2011/02/05/backbone-views-and-templates.html">This example implemented with google API</a></li> -<li><a href="http://jsfiddle.net/thomas/C9wew/4/">This examples exact code on jsfiddle.net</a></li> -<li><a href="http://jsfiddle.net/thomas/dKK9Y/6/">Another semi-complete example on jsFiddle</a></li> + <li><a href="http://thomasdavis.github.com/2011/02/05/backbone-views-and-templates.html">This example implemented with google API</a></li> + <li><a href="http://jsfiddle.net/thomas/C9wew/4/">This examples exact code on jsfiddle.net</a></li> + <li><a href="http://jsfiddle.net/thomas/dKK9Y/6/">Another semi-complete example on jsFiddle</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/zaeleus">Michael Macias</a></li> -<li><a href="https://github.com/lawnday">Alex Lande</a></li> + <li><a href="https://github.com/zaeleus">Michael Macias</a></li> + <li><a href="https://github.com/lawnday">Alex Lande</a></li> </ul> - </content> </entry> @@ -1892,15 +1861,15 @@ We will use the <code>save</code> api call which is intelligent and <link href="http://backbonetutorials.com/what-is-a-router"/> <updated>2011-01-27T00:00:00+10:00</updated> <id>http://backbonetutorials.com/what-is-a-router</id> - <content type="html"><h1>What is a router?</h1> + <content type="html"><h1 id="what-is-a-router">What is a router?</h1> -<p>Backbone routers are used for routing your applications URL's when using hash tags(#). In the traditional MVC sense they don't necessarily fit the semantics and if you have read "<a href="http://backbonetutorials.com/what-is-a-view">What is a view?</a>" it will elaborate on this point. Though a Backbone "router" is still very useful for any application/feature that needs URL routing/history capabilities.</p> +<p>Backbone routers are used for routing your applications URL’s when using hash tags(#). In the traditional MVC sense they don’t necessarily fit the semantics and if you have read “<a href="http://backbonetutorials.com/what-is-a-view">What is a view?</a>” it will elaborate on this point. Though a Backbone “router” is still very useful for any application/feature that needs URL routing/history capabilities. </p> <p>Defined routers should always contain at least one route and a function to map the particular route to. In the example below we are going to define a route that is always called.</p> -<p>Also note that routes interpret anything after "#" tag in the URL. All links in your application should target "#/action" or "#action". (Appending a forward slash after the hashtag looks a bit nicer e.g. http://example.com/#/user/help)</p> +<p>Also note that routes interpret anything after “#” tag in the URL. All links in your application should target “#/action” or “#action”. (Appending a forward slash after the hashtag looks a bit nicer e.g. http://example.com/#/user/help)</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script&gt;</span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;*actions&quot;</span><span class="o">:</span> <span class="s2">&quot;defaultRoute&quot;</span> <span class="c1">// matches http://example.com/#anything-here</span> @@ -1916,9 +1885,7 @@ We will use the <code>save</code> api call which is intelligent and <span class="c1">// Start Backbone history a necessary step for bookmarkable URL&#39;s</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><a href="#action">Activate route</a></p> @@ -1926,11 +1893,11 @@ We will use the <code>save</code> api call which is intelligent and <p><em>Notice the change in the url</em></p> -<h2>Dynamic Routing</h2> +<h2 id="dynamic-routing">Dynamic Routing</h2> -<p>Most conventional frameworks allow you to define routes that contain a mix of static and dynamic route parameters. For example you might want to retrieve a post with a variable id with a friendly URL string. Such that your URL would look like "http://example.com/#/posts/12". Once this route was activated you would want to access the id given in the URL string. This example is implemented below.</p> +<p>Most conventional frameworks allow you to define routes that contain a mix of static and dynamic route parameters. For example you might want to retrieve a post with a variable id with a friendly URL string. Such that your URL would look like “http://example.com/#/posts/12”. Once this route was activated you would want to access the id given in the URL string. This example is implemented below.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script&gt;</span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;posts/:id&quot;</span><span class="o">:</span> <span class="s2">&quot;getPost&quot;</span><span class="p">,</span> @@ -1949,9 +1916,7 @@ We will use the <code>save</code> api call which is intelligent and <span class="c1">// Start Backbone history a necessary step for bookmarkable URL&#39;s</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><a href="#/posts/120">Post 120</a></p> @@ -1959,15 +1924,15 @@ We will use the <code>save</code> api call which is intelligent and <p><em>Notice the change in the url</em></p> -<h2>Dynamic Routing Cont. ":params" and "*splats"</h2> +<h2 id="dynamic-routing-cont-params-and-splats">Dynamic Routing Cont. “:params” and “*splats”</h2> -<p>Backbone uses two styles of variables when implementing routes. First there are ":params" which match any URL components between slashes. Then there are "<em>splats" which match any number of URL components. Note that due to the nature of a "</em>splat" it will always be the last variable in your URL as it will match any and all components.</p> +<p>Backbone uses two styles of variables when implementing routes. First there are “:params” which match any URL components between slashes. Then there are “<em>splats” which match any number of URL components. Note that due to the nature of a “</em>splat” it will always be the last variable in your URL as it will match any and all components.</p> -<p>Any "*splats" or ":params" in route definitions are passed as arguments (in respective order) to the associated function. A route defined as "/:route/:action" will pass 2 variables (“route” and “action”) to the callback function. (If this is confusing please post a comment and I will try articulate it better)</p> +<p>Any “*splats” or “:params” in route definitions are passed as arguments (in respective order) to the associated function. A route defined as “/:route/:action” will pass 2 variables (“route” and “action”) to the callback function. (If this is confusing please post a comment and I will try articulate it better)</p> -<p>Here are some examples of using ":params" and "*splats"</p> +<p>Here are some examples of using “:params” and “*splats”</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;posts/:id&quot;</span><span class="o">:</span> <span class="s2">&quot;getPost&quot;</span><span class="p">,</span> <span class="c1">// &lt;a href=&quot;http://example.com/#/posts/121&quot;&gt;Example&lt;/a&gt;</span> @@ -1988,99 +1953,24 @@ We will use the <code>save</code> api call which is intelligent and <span class="p">});</span> <span class="nx">app_router</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;route:loadView&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">route</span><span class="p">,</span> <span class="nx">action</span> <span class="p">){</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">route</span> <span class="o">+</span> <span class="s2">&quot;_&quot;</span> <span class="o">+</span> <span class="nx">action</span><span class="p">);</span> <span class="c1">// dashboard_graph </span> - <span class="p">});</span> -</code></pre></div> + <span class="p">});</span></code></pre></div> - -<p>Routes are quite powerful and in an ideal world your application should never contain too many. If you need to implement hash tags with SEO in mind, do a google search for "google seo hashbangs". Also check out <a href="http://seo.apiengine.io">Seo Server</a></p> +<p>Routes are quite powerful and in an ideal world your application should never contain too many. If you need to implement hash tags with SEO in mind, do a google search for “google seo hashbangs”. Also check out <a href="http://seo.apiengine.io">Seo Server</a></p> <p>Remember to do a pull request for any errors you come across.</p> -<h3>Relevant Links</h3> - +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://documentcloud.github.com/backbone/#Router">Backbone.js official router documentation</a></li> -<li><a href="http://thomasdavis.github.com/2011/02/07/making-a-restful-ajax-app.html">Using routes and understanding the hash tag</a></li> + <li><a href="http://documentcloud.github.com/backbone/#Router">Backbone.js official router documentation</a></li> + <li><a href="http://thomasdavis.github.com/2011/02/07/making-a-restful-ajax-app.html">Using routes and understanding the hash tag</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="http://schistad.info">Herman Schistad</a> - (Backbone 0.5 rename from Controller to Router)</li> -<li><a href="http://paulirish.com">Paul Irish</a></li> + <li><a href="http://schistad.info">Herman Schistad</a> - (Backbone 0.5 rename from Controller to Router)</li> + <li><a href="http://paulirish.com">Paul Irish</a></li> </ul> - -</content> - </entry> - - <entry> - <title>What is a collection?</title> - <link href="http://backbonetutorials.com/what-is-a-collection"/> - <updated>2011-01-26T00:00:00+10:00</updated> - <id>http://backbonetutorials.com/what-is-a-collection</id> - <content type="html"><h1>What is a collection?</h1> - -<p>Backbone collections are simply an ordered set of <a href="/what-is-a-model">models</a>. Such that it can be used in situations such as;</p> - -<ul> -<li>Model: Student, Collection: ClassStudents</li> -<li>Model: Todo Item, Collection: Todo List</li> -<li>Model: Animal, Collection: Zoo</li> -</ul> - - -<p>Typically your collection will only use one type of model but models themselves are not limited to a type of collection;</p> - -<ul> -<li>Model: Student, Collection: Gym Class</li> -<li>Model: Student, Collection: Art Class</li> -<li>Model: Student, Collection: English Class</li> -</ul> - - -<p>Here is a generic Model/Collection example.</p> - -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Music is the answer&quot;</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">Album</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> - <span class="p">});</span> -</code></pre></div> - - -<h2>Building a collection</h2> - -<p>Now we are going to populate a collection with some useful data.</p> - -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> - <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Not specified&quot;</span><span class="p">,</span> - <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;Not specified&quot;</span> - <span class="p">},</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Music is the answer&quot;</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">Album</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">song1</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;How Bizarre&quot;</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;OMC&quot;</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">song2</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Sexual Healing&quot;</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;Marvin Gaye&quot;</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">song3</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Talk It Over In Bed&quot;</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;OMC&quot;</span> <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">myAlbum</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Album</span><span class="p">([</span> <span class="nx">song1</span><span class="p">,</span> <span class="nx">song2</span><span class="p">,</span> <span class="nx">song3</span><span class="p">]);</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">myAlbum</span><span class="p">.</span><span class="nx">models</span> <span class="p">);</span> <span class="c1">// [song1, song2, song3]</span> -</code></pre></div> - - - </content> </entry> diff --git a/_site/chat.html b/_site/chat.html index 1464f67..4acbcf2 100644 --- a/_site/chat.html +++ b/_site/chat.html @@ -5,71 +5,54 @@ <title>Chat - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -94,17 +79,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/contact.html b/_site/contact.html index 4777882..f960282 100644 --- a/_site/contact.html +++ b/_site/contact.html @@ -5,71 +5,54 @@ <title>Contact - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -93,17 +78,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/contribute.html b/_site/contribute.html index 3daac19..ad8fff2 100644 --- a/_site/contribute.html +++ b/_site/contribute.html @@ -5,71 +5,54 @@ <title>Contribute - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -94,17 +79,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/cross-domain-sessions/index.html b/_site/cross-domain-sessions/index.html index 223459d..ab45b04 100644 --- a/_site/cross-domain-sessions/index.html +++ b/_site/cross-domain-sessions/index.html @@ -5,71 +5,54 @@ <title>Cross-domain Backbone.js with sessions using CORS - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,45 +81,44 @@ <div id="post"> -<h1>Cross-domain Backbone.js with sessions using CORS</h1> +<h1 id="cross-domain-backbonejs-with-sessions-using-cors">Cross-domain Backbone.js with sessions using CORS</h1> -<p><strong> This tutorial is a proof of concept and needs to be checked for security flaws </strong></p> +<p>** This tutorial is a proof of concept and needs to be checked for security flaws **</p> <p>This tutorial will teach you how to completely separate the server and client allowing for developers to work with freedom in their respective areas.</p> <p>On a personal note, I consider this development practice highly desirable and encourage others to think of the possible benefits but the security still needs to be proved.</p> -<blockquote><p>Cross-Origin Resource Sharing (CORS) is a specification that enables a truly open access across domain-boundaries. - <a href="http://enable-cors.org/">enable-cors.org</a></p></blockquote> +<blockquote> + <p>Cross-Origin Resource Sharing (CORS) is a specification that enables a truly open access across domain-boundaries. - <a href="http://enable-cors.org/">enable-cors.org</a></p> +</blockquote> <p><strong>Some benefits include</strong></p> <ul> -<li>The client and back end exist independently regardless of where they are each hosted and built.</li> -<li>Due to the separation of concerns, testing now becomes easier and more controlled.</li> -<li>Develop only one API on the server, your front-end could be outsourced or built by a in-house team.</li> -<li>As a front-end developer you can host the client anywhere.</li> -<li>This separation enforces that the API be built robustly, documented, collaboratively and versioned.</li> + <li>The client and back end exist independently regardless of where they are each hosted and built.</li> + <li>Due to the separation of concerns, testing now becomes easier and more controlled.</li> + <li>Develop only one API on the server, your front-end could be outsourced or built by a in-house team.</li> + <li>As a front-end developer you can host the client anywhere.</li> + <li>This separation enforces that the API be built robustly, documented, collaboratively and versioned.</li> </ul> - -<p><strong> Cons of this tutorial </strong></p> +<p>** Cons of this tutorial **</p> <ul> -<li>This tutorial doesn't explain how to perform this with cross browser support. CORS headers aren't supported by Opera and IE 6/7. Though it is do-able using <a href="http://easyxdm.net/wp/">easyXDM</a></li> -<li>Security is somewhat addressed but maybe a more thorough security expert can chime in.</li> + <li>This tutorial doesn’t explain how to perform this with cross browser support. CORS headers aren’t supported by Opera and IE 6/7. Though it is do-able using <a href="http://easyxdm.net/wp/">easyXDM</a></li> + <li>Security is somewhat addressed but maybe a more thorough security expert can chime in.</li> </ul> - -<h2>Security</h2> +<h2 id="security">Security</h2> <ul> -<li>Don't allow GET request to change data, only retrieve.</li> -<li>Whitelist your allowed domains (see <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/server.js">server.js</a>)</li> -<li>Protect again <a href="http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html">JSON padding</a></li> + <li>Don’t allow GET request to change data, only retrieve.</li> + <li>Whitelist your allowed domains (see <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/server.js">server.js</a>)</li> + <li>Protect again <a href="http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html">JSON padding</a></li> </ul> - -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> @@ -146,11 +130,11 @@ <p>This tutorial focuses on building a flexible Session model to control session state in your application.</p> -<h2>Checking session state at first load</h2> +<h2 id="checking-session-state-at-first-load">Checking session state at first load</h2> <p>Before starting any routes, we should really know whether the user is authenticated. This will allow us to load the appropriate views. We will simply wrap our <code>Backbone.history.start</code> in a callback that executes after <code>Session.getAuth</code> has checked the server. We will jump into our Session model next.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span><span class="p">,</span> @@ -180,19 +164,17 @@ <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> <span class="p">})</span> <span class="p">}</span> - <span class="p">});</span> + <span class="p">});</span> <span class="k">return</span> <span class="nx">AppView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: We have used jQuery <code>ajaxPrefilter</code> to hook into all AJAX requests before they are executed. This is where we specify what server we want the application to hit.</em></p> -<h2>An example Session model</h2> +<h2 id="an-example-session-model">An example Session model</h2> -<p>This is a very light weight Session model which handles most situations. Read through the code and comments below. The model simply has a login, logout and check function. Again we have hooked into jQuery <code>ajaxPrefilter</code> to allow for csrf tokens and also telling jQuery to send cookies with the <code>withCredentials</code> property. The model relies heavily on it's <code>auth</code> property. Throughout your application, each view can simply bind to <code>change:auth</code> on the Session model and react accordingly. Because we return this AMD module instantiated using the new keyword, then it will keep state throughout the page. (This may not be best practice but it's highly convenient)</p> +<p>This is a very light weight Session model which handles most situations. Read through the code and comments below. The model simply has a login, logout and check function. Again we have hooked into jQuery <code>ajaxPrefilter</code> to allow for csrf tokens and also telling jQuery to send cookies with the <code>withCredentials</code> property. The model relies heavily on it’s <code>auth</code> property. Throughout your application, each view can simply bind to <code>change:auth</code> on the Session model and react accordingly. Because we return this AMD module instantiated using the new keyword, then it will keep state throughout the page. (This may not be best practice but it’s highly convenient)</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// views/app.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// views/app.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span> @@ -246,17 +228,15 @@ <span class="p">});</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">SessionModel</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: This session model is missing one useful feature. If a user looses auth when navigating your application then the application should set {auth: false} on this model. To do this, in the <code>ajaxPrefilter</code> edit outgoing <code>success</code> functions to check if the server response was {auth: false} and then call the original <code>success()</code> function.</em></p> -<h2>Hooking up views to listen to changes in <code>auth</code></h2> +<h2 id="hooking-up-views-to-listen-to-changes-in-auth">Hooking up views to listen to changes in <code>auth</code></h2> -<p>Now that we have a Session model, let's hook up our <code>login/logout</code> view to listen to changes in <code>auth</code>. When creating the view we use <code>on</code> to bind a listener to the <code>auth</code> attribute of our model. Everytime it changes we will re-render the view which will conditionally load a template depending on the value of <code>Session.get('auth')</code>.</p> +<p>Now that we have a Session model, let’s hook up our <code>login/logout</code> view to listen to changes in <code>auth</code>. When creating the view we use <code>on</code> to bind a listener to the <code>auth</code> attribute of our model. Everytime it changes we will re-render the view which will conditionally load a template depending on the value of <code>Session.get('auth')</code>.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// models/session.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// models/session.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> @@ -303,15 +283,13 @@ <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">ExamplePage</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>.serializeObject</code> is not a native jQuery function and I have included it as <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/js/views/app.js">app.js</a> in the demo folder. <code>creds</code> can be an object of any variation of inputs, regardless it will be converted to JSON and posted to the server like any normal Backbone model.</em></p> <p>Here are the templates we are using for our login view</p> -<div class="highlight"><pre><code class="javascript"><span class="c"><!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">login</span><span class="p">.</span><span class="nx">html</span> <span class="o">--></span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c"><!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">login</span><span class="p">.</span><span class="nx">html</span> <span class="o">--></span> <span class="o"><</span><span class="nx">form</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"login"</span><span class="o">></span> <span class="o"><</span><span class="nx">label</span> <span class="k">for</span><span class="o">=</span><span class="s2">""</span><span class="o">></span><span class="nx">Username</span><span class="o"><</span><span class="err">/label></span> <span class="o"><</span><span class="nx">input</span> <span class="nx">name</span><span class="o">=</span><span class="s2">"username"</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">required</span> <span class="nx">autofocus</span><span class="o">></span> @@ -320,60 +298,54 @@ <span class="c"><!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">logout</span><span class="p">.</span><span class="nx">html</span> <span class="o">--></span> <span class="o"><</span><span class="nx">p</span><span class="o">></span><span class="nx">Hello</span><span class="p">,</span> <span class="o"><%=</span> <span class="nx">username</span> <span class="o">%></span><span class="p">.</span> <span class="nx">Time</span> <span class="nx">to</span> <span class="nx">logout</span><span class="o">?<</span><span class="err">/p></span> -<span class="o"><</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"logout"</span><span class="o">></span><span class="nx">Logout</span><span class="o"><</span><span class="err">/button></span> -</code></pre></div> - +<span class="o"><</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"logout"</span><span class="o">></span><span class="nx">Logout</span><span class="o"><</span><span class="err">/button></span></code></pre></div> <p>This wraps up setting up the client, there are some notable points to make sure this technique works.</p> <ul> -<li>You must use <code>withCredentials</code> supplied by jQuery - session.js</li> -<li>You must send your request with csrf tokens for security - session.js</li> -<li>You should wrap your applications entry pointer (router in this example) in a check auth function - app.js</li> -<li>You must point your application at the right server - app.js</li> + <li>You must use <code>withCredentials</code> supplied by jQuery - session.js</li> + <li>You must send your request with csrf tokens for security - session.js</li> + <li>You should wrap your applications entry pointer (router in this example) in a check auth function - app.js</li> + <li>You must point your application at the right server - app.js</li> </ul> - -<h2>Building a compatible server</h2> +<h2 id="building-a-compatible-server">Building a compatible server</h2> <p>This tutorial uses node.js, express.js and a modified csrf.js library. An example server.js file exist in the <code>examples/cross-domain</code> folder. When inside the folder simply type <code>npm install -d</code> to install the dependencies and then <code>node server.js</code> to start the server. Again, make sure your <code>app.js</code> points at the correct server.</p> <p>The server has to do a few things;</p> <ul> -<li>Allow CORS request</li> -<li>Implement csrf protection</li> -<li>Allow jQuery to send credentials</li> -<li>Set a whitelist of allowed domains</li> -<li>Configure the correct response headers</li> + <li>Allow CORS request</li> + <li>Implement csrf protection</li> + <li>Allow jQuery to send credentials</li> + <li>Set a whitelist of allowed domains</li> + <li>Configure the correct response headers</li> </ul> - <p>To save you sometime here are some gotchas;</p> <ul> -<li>When sending <code>withCredentials</code> you must set correct response header <code>Access-Control-Allow-Credentials: true</code>. Also as a security policy browsers do not allow <code>Access-Control-Allow-Origin</code> to be set to <code>*</code>. So the origin of the request has to be known and trusted, so in the example below we use an of white listed domains.</li> -<li>jQuery ajax will trigger the browser to send these headers to enforce security <code>origin, x-requested-with, accept</code> so our server must allow them.</li> -<li>The browser might send out a <code>pre-flight</code> request to verify that it can talk to the server. The server must return <code>200 OK</code> on these <code>pre-flight</code> request.</li> + <li>When sending <code>withCredentials</code> you must set correct response header <code>Access-Control-Allow-Credentials: true</code>. Also as a security policy browsers do not allow <code>Access-Control-Allow-Origin</code> to be set to <code>*</code>. So the origin of the request has to be known and trusted, so in the example below we use an of white listed domains.</li> + <li>jQuery ajax will trigger the browser to send these headers to enforce security <code>origin, x-requested-with, accept</code> so our server must allow them.</li> + <li>The browser might send out a <code>pre-flight</code> request to verify that it can talk to the server. The server must return <code>200 OK</code> on these <code>pre-flight</code> request.</li> </ul> - <p>Be sure to read this Mozilla <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">documentation</a> on the above.</p> -<h2>Example node server</h2> +<h2 id="example-node-server">Example node server</h2> <p>This server below implements everything we have talked about so far. It should be relatively easy to see how would translate into other frameworks and languages. <code>app.configure</code> runs the specified libraries against every request. We have told the server that on each request it should check the csrf token and check if the origin domain is white-listed. If so we edit each request to contain the appropriate headers.</p> <p>This server has 3 endpoints, that are pseudo-restful;</p> <ul> -<li>POST /session - Login - Sets the session username and returns a csrf token for the user to use</li> -<li>DELETE /session - Logout - Destroys the session and regenerates a new csrf token if the user wants to re-login</li> -<li>GET /session - Checks Auth - Simply returns if auth is true or false, if true then also returns some session details</li> + <li>POST /session - Login - Sets the session username and returns a csrf token for the user to use</li> + <li>DELETE /session - Logout - Destroys the session and regenerates a new csrf token if the user wants to re-login</li> + <li>GET /session - Checks Auth - Simply returns if auth is true or false, if true then also returns some session details</li> </ul> - -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'express'</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'express'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">connect</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'connect'</span><span class="p">);</span> <span class="c1">// Custom csrf library</span> @@ -439,13 +411,11 @@ <span class="p">});</span> <span class="p">});</span> -<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">8000</span><span class="p">);</span> -</code></pre></div> - +<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">8000</span><span class="p">);</span></code></pre></div> -<p><em>Note: I wrote a custom csrf module for this which can be found in the example directory. It's based of connects and uses the <code>crypto</code> library. I didn't spend much time on it but other traditional csrf modules won't work because they aren't exactly built for this implementation technique.</em></p> +<p><em>Note: I wrote a custom csrf module for this which can be found in the example directory. It’s based of connects and uses the <code>crypto</code> library. I didn’t spend much time on it but other traditional csrf modules won’t work because they aren’t exactly built for this implementation technique.</em></p> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>This approach really hammers in the need for a well documented and designed API. A powerful API will let you do application iterations with ease.</p> @@ -459,15 +429,14 @@ <p><a href="http://backbonetutorials.com/examples/cross-domain/">Example Demo</a></p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">cross-site xmlhttprequest with CORS</a></li> -<li><a href="http://www.w3.org/TR/cors/">Cross-Origin Resource Sharing</a></li> -<li><a href="http://www.kendoui.com/blogs/teamblog/posts/11-10-04/using_cors_with_all_modern_browsers.aspx">Using CORS with All (Modern) Browsers</a></li> + <li><a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">cross-site xmlhttprequest with CORS</a></li> + <li><a href="http://www.w3.org/TR/cors/">Cross-Origin Resource Sharing</a></li> + <li><a href="http://www.kendoui.com/blogs/teamblog/posts/11-10-04/using_cors_with_all_modern_browsers.aspx">Using CORS with All (Modern) Browsers</a></li> </ul> - </div> </div> @@ -480,7 +449,8 @@ <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -503,17 +473,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/css/style.css b/_site/css/style.css index 8397263..3dd5ca0 100644 --- a/_site/css/style.css +++ b/_site/css/style.css @@ -7,3 +7,15 @@ #post h3 { font-size: 20px !important; } + +.container { + max-width: 840px !important ; +} +/* +body { + font: 1em "Arvo","Helvetica Neue",Helvetica,Arial,sans-serif !important; + text-shadow: 0 0 4px #CCC !important; + color: #333; + font-size: 14px !important; +} +*/
\ No newline at end of file diff --git a/_site/examples.html b/_site/examples.html index 28ff6ec..0ed5c3e 100644 --- a/_site/examples.html +++ b/_site/examples.html @@ -5,71 +5,54 @@ <title>Contact - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -97,17 +82,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/examples/modular-backbone/README.md b/_site/examples/modular-backbone/README.md index 1f1c447..13c547f 100644 --- a/_site/examples/modular-backbone/README.md +++ b/_site/examples/modular-backbone/README.md @@ -6,7 +6,7 @@ authors: [Thomas Davis](https://github.com/thomasdavis), [Brandon Flowers](https Learn how to use Backbone and Require together to create modular applications that are easy to maintain for solo and team-based projects. As you build your application, you will create many small javascript files with usually no more than 100 lines of code per file. Some developers say that each file does one thing, but we won't hold you to that but we do recommended trying to write smaller files and breaking up the tasks. -Once you have a working applicaiton and you're read to go to production, you can apply R.js (or alternatively grunt.js ) to minify and concatenate this code base into one javascript file that you'll deploy to your website. +Once you have a working application and you're ready to go to production, you can apply R.js (or alternatively grunt.js) to minify and concatenate this code base into one javascript file that you'll deploy to your website. [demo](http://backbonetutorials.com/examples/modular-backbone) | [discussion](http://backbonetutorials.com/organizing-backbone-using-modules/) diff --git a/_site/examples/modular-backbone/js/collections/projects/ProjectsCollection.js b/_site/examples/modular-backbone/js/collections/projects/ProjectsCollection.js index a8b0676..cdeb187 100644 --- a/_site/examples/modular-backbone/js/collections/projects/ProjectsCollection.js +++ b/_site/examples/modular-backbone/js/collections/projects/ProjectsCollection.js @@ -9,12 +9,6 @@ define([ initialize: function(){ - var project0 = new ProjectModel('Cross Domain', 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/cross-domain'); - var project1 = new ProjectModel('Infinite Scroll', 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/infinite-scroll'); - var project2 = new ProjectModel('Modular Backbone','https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/modular-backbone'); - var project3 = new ProjectModel('Node MongoDB Mongoose Restify','https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify'); - var project4 = new ProjectModel('Todo App','https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/todo-app'); - //this.add([project0, project1, project2, project3, project4]); } diff --git a/_site/examples/nodejs-mongodb-mongoose-restify/README.md b/_site/examples/nodejs-mongodb-mongoose-restify/README.md index 4b0a51b..7fc7cd7 100644 --- a/_site/examples/nodejs-mongodb-mongoose-restify/README.md +++ b/_site/examples/nodejs-mongodb-mongoose-restify/README.md @@ -1,13 +1,23 @@ -# Simple example - Node.js, Restify, MongoDb and Mongoose +## A Relatively Simple Example -authors: Thomas Davis | https://github.com/thomasdavis - Brandon Flowers | https://github.com/headwinds +### Node.js, Restify, MongoDb and Mongoose -If you would like to discuss any of this code, please your leave comments using disqus at the bottom of this article: +authors: -http://backbonetutorials.com/nodejs-restify-mongodb-mongoose/ +Thomas Davis | https://github.com/thomasdavis -## STRUCTURE +Brandon Flowers | https://github.com/headwinds + +If you would like to discuss any of this code, please your leave comments using disqus at the bottom of [the main article](http://backbonetutorials.com/nodejs-restify-mongodb-mongoose/). + +This README.md has four main sections: + +1. STRUCTURE - why are there 2 servers?! +2. HTTP SERVER - serves static html, css, js; the front-end +3. MONGODB - pure data services; the back-end +4. THE MISSING CONFIG.JS FILE - the long and short: see configSample.js and then create your own config.js + +### STRUCTURE There are basically two parts to this demo - two servers - within one file, server.js, which may sound a little confusing but the two servers do different things. @@ -19,9 +29,11 @@ In addition to server.js, I've also refactored it into two separate files: serve If you only need the mongobd server, you might start with the server-mongo folder. -## HTTP SERVER +### HTTP SERVER + +Originally, this tutorial started out as purely a mongodb one but I wanted to see the data in a browser and since this is a collection of Backbone tutorials, I might as well include some client-side backbone views. -Originally, this tutorial started out as purely a mongodb one but I wanted to see the data in a browser and since this is a collection of Backbone tutorials, I might as well include some client-side backbone views. I aslo started working on it before discovering Google's Yeoman which includes its own web server that serves static files thus making the HTTP portion not necessary when testing locally, however, when you move to host these files somewhere else like nodejitsu, you may need to use your own static web server if it doesn't support nginx or apache. +I also started working on it before discovering Google's Yeoman which includes its own web server that serves static files thus making the HTTP portion not necessary when testing locally, however, when you move to host these files somewhere else like nodejitsu, you may need to use your own static web server if it doesn't support nginx or apache. But before using Yeoman, you might want to try open a terminal to the directory of this app and typing: @@ -31,7 +43,7 @@ Next, you will need to open browser and point it to: http://localhost:8080/ -Alternatively, you can use Yeoman which would automatically launch a browswer window and also you more features like live reload. +Alternatively, you can use Yeoman which would automatically launch a browser window and also you more features like live reload. $ yeoman server @@ -43,15 +55,14 @@ http://localhost:3501/ http server: - If you'd like to see the raw messages as a json dump, you can point your browser to: http://localhost:8888/messages -This static server is taken very largely (line for line) from this example: -http://thecodinghumanist.com/blog/archives/2011/5/6/serving-static-files-from-node-js +This static server is taken very largely (line for line) from [this example on thecodinghumanist.com](http://thecodinghumanist.com/blog/archives/2011/5/6/serving-static-files-from-node-js) and thus a very large credit should go to Eric Sowell. + -## MONGODB +### MONGODB In order to setup my mongodb database, I've taken the following steps: @@ -83,16 +94,15 @@ Just to prove you've added a message, you can display all the messages Now, I have a database with a collection of messages containing at least one message. You view this message in the browser, visit: -http://localhost:8888/messages +> http://localhost:8888/messages -## CONFIG +## THE MISSING CONFIG.JS FILE -If you plan to work with a public github, it is a good idea to protect your production mongodb connection uri -and put it in a config file which you include in .gitignore so that it doesn't get committed +If you plan to work with a public github, it is a good idea to protect your production mongodb connection uri and put it in a config file which you include in .gitignore so that it doesn't get committed -var config = require('./config'); // Local congig file to hide creds -db = mongoose.connect(config.mongoose_auth), -Schema = mongoose.Schema; +> var config = require('./config'); // Local congig file to hide creds +> db = mongoose.connect(config.mongoose_auth), +> Schema = mongoose.Schema; When you go to host it on a platform like nodejitsu, you will need to deploy that config file so ensure it is included by using a .npmignore file @@ -104,7 +114,4 @@ backbone.sublime-workspace Within my .npmignore file, I have one to include the config: -!./config.js - - - +!./config.js
\ No newline at end of file diff --git a/_site/index.html b/_site/index.html index 74cc537..3e74f25 100644 --- a/_site/index.html +++ b/_site/index.html @@ -5,71 +5,54 @@ <title>Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -107,6 +92,8 @@ + + <a href="/why-would-you-use-backbone" class="list-group-item ">Why would you use Backbone.js?</a> @@ -137,6 +124,10 @@ <div class="list-group"> + <a href="/real-time-backbone-with-pubnub" class="list-group-item ">Real-Time Backbone With PubNub</a> + + + <a href="/seo-for-single-page-apps" class="list-group-item ">SEO for single page applications</a> @@ -210,12 +201,13 @@ <h3 class="panel-title">Example Apps</h3> </div> <div class="list-group"> - <a class="list-group-item" href="http://www.earbits.com">Earbits.com - Music streaming website</a> + <a class="list-group-item" href="http://www.dronehire.org">DroneHire.org - 100% built with Backbone.js</a> <a class="list-group-item" href="http://kaleistyleguide.com/">Kalei - A living CSS styleguide</a> <a class="list-group-item" href="http://apiengine.io">ApiEngine.io - Collaborativly build RESTful API's.</a> <a class="list-group-item" href="https://github.com/alessioalex/ClientManager" alt="Sample application built with Backbone, RequireJS, Twitter Bootstrap on the client and Node.js (Express.js, Mongoose) on the server.">ClientManager - Sample application</a> <a class="list-group-item" href="http://www.clevertim.com">Clevertim CRM - A simple CRM</a> - </div> + <a class="list-group-item" href="http://forum.dronehire.org">Drone hire forum</a> +</div> </div> </div> @@ -237,20 +229,13 @@ <li><a href="http://www.clevertim.com">Clevertim CRM - A real life example of implementing a simple CRM with backbone.js (check the Quick Demo)</a></li> </ul> --> + </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/infinite-scrolling/index.html b/_site/infinite-scrolling/index.html index 0351080..1b61fde 100644 --- a/_site/infinite-scrolling/index.html +++ b/_site/infinite-scrolling/index.html @@ -5,71 +5,54 @@ <title>Lightweight Infinite Scrolling using Twitter API - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,9 +81,9 @@ <div id="post"> -<h1>Lightweight Infinite Scrolling using Twitter API</h1> +<h1 id="lightweight-infinite-scrolling-using-twitter-api">Lightweight Infinite Scrolling using Twitter API</h1> -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>In this example we are going to build a widget that pulls in tweets and when the user scrolls to the bottom of the widget Backbone.js will re-sync with the server to bring down the next page of results.</p> @@ -108,15 +93,15 @@ <p><em>Note: This tutorial will use <a href="http://backbonetutorials.com/organizing-backbone-using-modules">AMD</a> for modularity.</em></p> -<h2>The Twitter Collection</h2> +<h2 id="the-twitter-collection">The Twitter Collection</h2> -<p>Twitter offers a jsonp API for browsing tweets. The first thing to note is that we have to append '&callback?' to allow cross domain Ajax calls which is a feature of <a href="http://en.wikipedia.org/wiki/JSONP">jsonp</a>.</p> +<p>Twitter offers a jsonp API for browsing tweets. The first thing to note is that we have to append ‘&callback?’ to allow cross domain Ajax calls which is a feature of <a href="http://en.wikipedia.org/wiki/JSONP">jsonp</a>.</p> -<p>Using the 'q' and 'page' query parameters we can find the results we are after. In the collection definition below we have set some defaults which can be overridden at any point.</p> +<p>Using the ‘q’ and ‘page’ query parameters we can find the results we are after. In the collection definition below we have set some defaults which can be overridden at any point.</p> -<p>Twitter's search API actually returns a whole bunch of meta information alongside the results. Though this is a problem for Backbone.js because a Collection expects to be populated with an array of objects. So in our collection definition we can override the Backbone.js default parse function to instead choose the correct property to populate the collection.</p> +<p>Twitter’s search API actually returns a whole bunch of meta information alongside the results. Though this is a problem for Backbone.js because a Collection expects to be populated with an array of objects. So in our collection definition we can override the Backbone.js default parse function to instead choose the correct property to populate the collection. </p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// collections/twitter.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// collections/twitter.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> @@ -136,24 +121,20 @@ <span class="p">});</span> <span class="k">return</span> <span class="nx">Tweets</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: Feel free to attach the meta information returned by Twitter to the collection itself e.g.</em></p> -<div class="highlight"><pre><code class="javascript"><span class="nx">parse</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">)</span> <span class="p">{</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">parse</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">completed_in</span> <span class="o">=</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">completed_in</span> <span class="k">return</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">results</span><span class="p">;</span> -<span class="p">},</span> -</code></pre></div> - +<span class="p">},</span></code></pre></div> -<h2>Setting up the View</h2> +<h2 id="setting-up-the-view">Setting up the View</h2> -<p>The first thing to do is to load our Twitter collection and template into the widget module. We should attach our collection to our view in our <code>initialize</code> function. <code>loadResults</code> will be responsible for calling fetch on our Twitter collection. On success we will append the latest results to our widget using our template. Our Backbone.js <code>events</code> will listen for <code>scroll</code> on the current <code>el</code> of the view which is '.twitter-widget'. If the current <code>scrollTop</code> is at the bottom then we simply increment the Twitter collections current page property and call <code>loadResults</code> again.</p> +<p>The first thing to do is to load our Twitter collection and template into the widget module. We should attach our collection to our view in our <code>initialize</code> function. <code>loadResults</code> will be responsible for calling fetch on our Twitter collection. On success we will append the latest results to our widget using our template. Our Backbone.js <code>events</code> will listen for <code>scroll</code> on the current <code>el</code> of the view which is ‘.twitter-widget’. If the current <code>scrollTop</code> is at the bottom then we simply increment the Twitter collections current page property and call <code>loadResults</code> again.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// views/twitter/widget.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// views/twitter/widget.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> @@ -200,28 +181,24 @@ <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">TwitterWidget</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>triggerPoint</code> will allow you to set an offset where the user has to scroll to before loading the next page</em></p> -<h2>The widget template</h2> +<h2 id="the-widget-template">The widget template</h2> -<p>Our view above passes into our underscore template the variable tweets which we can simply iterate over with using underscore's <code>each</code> method.</p> +<p>Our view above passes into our underscore template the variable tweets which we can simply iterate over with using underscore’s <code>each</code> method.</p> -<div class="highlight"><pre><code class="javascript"><span class="c"><!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">twitter</span><span class="o">/</span><span class="nx">list</span><span class="p">.</span><span class="nx">html</span> <span class="o">--></span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c"><!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">twitter</span><span class="o">/</span><span class="nx">list</span><span class="p">.</span><span class="nx">html</span> <span class="o">--></span> <span class="o"><</span><span class="nx">ul</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"tweets"</span><span class="o">></span> <span class="o"><%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">tweets</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">tweet</span><span class="p">)</span> <span class="p">{</span> <span class="o">%></span> <span class="o"><</span><span class="nx">li</span><span class="o">><%=</span> <span class="nx">tweet</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'text'</span><span class="p">)</span> <span class="o">%><</span><span class="err">/li> </span> <span class="o"><%</span> <span class="p">});</span> <span class="o">%></span> -<span class="o"><</span><span class="err">/ul></span> -</code></pre></div> - +<span class="o"><</span><span class="err">/ul></span></code></pre></div> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>This is a very lightweight but robust infinite scroll example. There are caveats to using infinite scroll in UI/UX so make sure to only use it when applicable.</p> @@ -241,7 +218,8 @@ <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -264,17 +242,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/lessons.html b/_site/lessons.html index 12c6427..ee8c4d9 100644 --- a/_site/lessons.html +++ b/_site/lessons.html @@ -5,71 +5,54 @@ <title>Lessons - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -93,17 +78,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/nodejs-restify-mongodb-mongoose/index.html b/_site/nodejs-restify-mongodb-mongoose/index.html index 782970c..8a548da 100644 --- a/_site/nodejs-restify-mongodb-mongoose/index.html +++ b/_site/nodejs-restify-mongodb-mongoose/index.html @@ -5,71 +5,54 @@ <title>Simple example - Node.js, Restify, MongoDb and Mongoose - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,91 +81,85 @@ <div id="post"> -<h1>Simple example - Node.js, Restify, MongoDb and Mongoose</h1> +<h1 id="simple-example---nodejs-restify-mongodb-and-mongoose">Simple example - Node.js, Restify, MongoDb and Mongoose</h1> -<p>Before I start, the Backbone.js parts of this tutorial will be using techniques described in "Organizing your application using <a href="http://backbonetutorials.com/organizing-backbone-using-modules/">Modules</a> to construct a simple guestbook.</p> +<p>Before I start, the Backbone.js parts of this tutorial will be using techniques described in “Organizing your application using <a href="http://backbonetutorials.com/organizing-backbone-using-modules/">Modules</a> to construct a simple guestbook.</p> -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> <p><a href="https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify">Example Codebase</a></p> -<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/">Example Demo</a></p> +<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/app">Example Demo</a></p> <p>This tutorial will assist you in saving data(Backbone.js Models) to MongoDb and retrieving a list(Backbone.js Collections) of them back.</p> -<h2>The technologies</h2> +<h2 id="the-technologies">The technologies</h2> <p>This stack is great for rapid prototyping and highly intuitive. Personal note: I love using JavaScript as my only language for the entire application (FrontEnd/BackEnd/API/Database). Restify is still in early development but is essentially just an extension of Express. So for anyone needing more stability you can easily just substitute Express in.</p> -<h3>Node.js</h3> +<h3 id="nodejs">Node.js</h3> -<p>"Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices."</p> +<p>“Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.”</p> -<h3>Restify</h3> +<h3 id="restify">Restify</h3> -<p>"Restify is a node.js module built specifically to enable you to build correct REST web services. It borrows heavily from express (intentionally) as that is more or less the de facto API for writing web applications on top of node.js."</p> +<p>“Restify is a node.js module built specifically to enable you to build correct REST web services. It borrows heavily from express (intentionally) as that is more or less the de facto API for writing web applications on top of node.js.”</p> -<h3>MongoDb</h3> +<h3 id="mongodb">MongoDb</h3> -<p>"MongoDB (from "humongous") is a scalable, high-performance, open source NoSQL database."</p> +<p>“MongoDB (from “humongous”) is a scalable, high-performance, open source NoSQL database.”</p> -<h3>Mongoose</h3> +<h3 id="mongoose">Mongoose</h3> -<p>"Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment."</p> +<p>“Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.”</p> -<h2>Building the server</h2> +<h2 id="building-the-server">Building the server</h2> <p>In the example repository there is a server.js example which can be executed by running <code>node server.js</code>. If you use this example in your own applications make sure to update the Backbone.js <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/models/message.js">Model</a> and <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/collections/messages.js">Collection</a> definitions to match your server address.</p> -<h2>Restify configuration</h2> +<h2 id="restify-configuration">Restify configuration</h2> <p>The first thing to do is require the Restify module. Restify will be in control of handling our restful endpoints and returning the appropriate JSON.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">restify</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'restify'</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">restify</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'restify'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">server</span> <span class="o">=</span> <span class="nx">restify</span><span class="p">.</span><span class="nx">createServer</span><span class="p">();</span> -<span class="nx">server</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">restify</span><span class="p">.</span><span class="nx">bodyParser</span><span class="p">());</span> -</code></pre></div> - +<span class="nx">server</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">restify</span><span class="p">.</span><span class="nx">bodyParser</span><span class="p">());</span></code></pre></div> <p>Note: bodyParser() takes care of turning your request data into a JavaScript object on the server automatically.</p> -<h2>MongoDb/Mongoose configuration</h2> +<h2 id="mongodbmongoose-configuration">MongoDb/Mongoose configuration</h2> <p>We simply want to require the MongoDb module and pass it a MongoDb authentication URI e.g. mongodb://username:server@mongoserver:10059/somecollection</p> <p>The code below presupposes you have another file in the same directory called <code>config.js</code>. Your config should never be public as it contains your credentials. So for this repository I have added <code>config.js</code> to my <code>.gitignore</code> but added in a <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/config-sample.js">sample config</a>.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">mongoose</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'mongoose/'</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">mongoose</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'mongoose/'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">config</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'./config'</span><span class="p">);</span> <span class="nx">db</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">creds</span><span class="p">.</span><span class="nx">mongoose_auth</span><span class="p">),</span> -<span class="nx">Schema</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">;</span> -</code></pre></div> +<span class="nx">Schema</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">;</span></code></pre></div> - -<h2>Mongoose Schema</h2> +<h2 id="mongoose-schema">Mongoose Schema</h2> <p>Mongoose introduces a concept of <a href="http://mongoosejs.com/docs/model-definition.html">model/schema</a> enforcing types which allow for easier input validation etc</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Create a schema for our data</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Create a schema for our data</span> <span class="kd">var</span> <span class="nx">MessageSchema</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Schema</span><span class="p">({</span> <span class="nx">message</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span> <span class="nx">date</span><span class="o">:</span> <span class="nb">Date</span> <span class="p">});</span> <span class="c1">// Use the schema to register a model with MongoDb</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">'Message'</span><span class="p">,</span> <span class="nx">MessageSchema</span><span class="p">);</span> -<span class="kd">var</span> <span class="nx">Message</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">'Message'</span><span class="p">);</span> -</code></pre></div> - +<span class="kd">var</span> <span class="nx">Message</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">'Message'</span><span class="p">);</span></code></pre></div> <p><em>Note: <code>Message</code> can now be used for all things CRUD related.</em></p> -<h2>Setting up the routes</h2> +<h2 id="setting-up-the-routes">Setting up the routes</h2> <p>Just like in Backbone, Restify allows you to configure different routes and their associated callbacks. In the code below we define two routes. One for saving new messages and one for retrieving all messages. After we have created our function definitions, we attach them to either GET/POST/PUT/DELETE on a particular restful endpoint e.g. GET /messages</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// This function is responsible for returning all entries for the Message model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// This function is responsible for returning all entries for the Message model</span> <span class="kd">function</span> <span class="nx">getMessages</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Resitify currently has a bug which doesn't allow you to set default headers</span> <span class="c1">// This headers comply with CORS and allow us to server our response to any origin</span> @@ -209,9 +188,7 @@ <span class="c1">// Set up our routes and start the server</span> <span class="nx">server</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'/messages'</span><span class="p">,</span> <span class="nx">getMessages</span><span class="p">);</span> -<span class="nx">server</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">'/messages'</span><span class="p">,</span> <span class="nx">postMessage</span><span class="p">);</span> -</code></pre></div> - +<span class="nx">server</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">'/messages'</span><span class="p">,</span> <span class="nx">postMessage</span><span class="p">);</span></code></pre></div> <p>This wraps up the server side of things, if you follow the <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/server.js">example</a> then you should see something like</p> @@ -219,36 +196,33 @@ <p><em>Note: Again you must remember to change the <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/models/message.js">Model</a> and <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/collections/messages.js">Collection</a> definitions to match your server address.</em></p> -<h2>Setting up the client (Backbone.js)</h2> +<h2 id="setting-up-the-client-backbonejs">Setting up the client (Backbone.js)</h2> -<p>I've actually used the latest copy of <a href="http://backboneboilerplate.com">http://backboneboilerplate.com</a> to set up the example page.</p> +<p>I’ve actually used the latest copy of <a href="http://backboneboilerplate.com">http://backboneboilerplate.com</a> to set up the example page.</p> <p>The important files you will want to check out are;</p> <ul> -<li>views/dashboard/page.js</li> -<li>views/guestbook/form.js</li> -<li>views/guestbook/list.js</li> -<li>models/message.js</li> -<li>collections/messages.js</li> -<li>templates/guestbook/</li> + <li>views/dashboard/page.js</li> + <li>views/guestbook/form.js</li> + <li>views/guestbook/list.js</li> + <li>models/message.js</li> + <li>collections/messages.js</li> + <li>templates/guestbook/</li> </ul> - -<h2>Saving a message</h2> +<h2 id="saving-a-message">Saving a message</h2> <p>First of all we want to setup a <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/templates/guestbook/form.html">template</a> for showing our form that creates new messages.</p> -<div class="highlight"><pre><code class="javascript"><span class="o"><</span><span class="nx">textarea</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"message"</span><span class="o">><</span><span class="err">/textarea></span> -<span class="o"><</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"post-message"</span><span class="o">></span><span class="nx">Post</span> <span class="nx">Message</span><span class="o"><</span><span class="err">/button></span> -</code></pre></div> - +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o"><</span><span class="nx">textarea</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"message"</span><span class="o">><</span><span class="err">/textarea></span> +<span class="o"><</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">"post-message"</span><span class="o">></span><span class="nx">Post</span> <span class="nx">Message</span><span class="o"><</span><span class="err">/button></span></code></pre></div> <p>This template gets inserted into the DOM by <code>views/guestbook/form.js</code>, this Backbone view also handles the interaction of the form and the posting of the new data.</p> <p>Let us create a Backbone Model that has the correct URL for our restful interface.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span> <span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">)</span> <span class="p">{</span> @@ -256,13 +230,11 @@ <span class="nx">url</span><span class="o">:</span> <span class="s1">'http://localhost:8080/messages'</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">Message</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>We can see how we require our predefined model for messages and also our form template.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span><span class="p">,</span> @@ -290,17 +262,15 @@ <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">GuestbookForm</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>trigger</code> is from Backbone Events, I binded a listener to this view in <code>views/dashboard/page.js</code> so when a new message is submitted, the list is re-rendered. We are setting the date of the POST on the server so there is no need to pass it up.</em></p> -<h2>Retrieving a list of messages</h2> +<h2 id="retrieving-a-list-of-messages">Retrieving a list of messages</h2> <p>We setup a route on our server to generate a list of all available messages at <code>GET /messages</code>. So we need to define a collection with the appropriate <code>url</code> to fetch this data down.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span><span class="p">,</span> @@ -312,13 +282,11 @@ <span class="p">});</span> <span class="k">return</span> <span class="nx">Messages</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>Now that we have a collection to use we can setup our <code>views/list.js</code> to require the collection and trigger a fetch. Once the fetch is complete we want to render our returned data to a template and insert it into the DOM.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span><span class="p">,</span> @@ -338,30 +306,26 @@ <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">GuestbookList</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>The template file should iterate over <code>messages.models</code> which is an array and print out a HTML fragment for each model.</p> -<div class="highlight"><pre><code class="javascript"><span class="o"><%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> <span class="o">%></span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o"><%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> <span class="o">%></span> <span class="o"><</span><span class="nx">p</span><span class="o">><%=</span> <span class="nx">message</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'message'</span><span class="p">)</span> <span class="o">%><</span><span class="err">/p></span> <span class="o"><</span><span class="nx">em</span><span class="o">><%=</span> <span class="nx">message</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'date'</span><span class="p">)</span> <span class="o">%><</span><span class="err">/em></span> -<span class="o"><%</span> <span class="p">});</span> <span class="o">%></span> -</code></pre></div> - +<span class="o"><%</span> <span class="p">});</span> <span class="o">%></span></code></pre></div> <p>This actually sums up everything you need to know to implement this simple example.</p> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p><a href="https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify">Example Codebase</a></p> -<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/">Example Demo</a></p> +<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/app">Example Demo</a></p> -<p>In this example you should really be using relative URL's in your collections/models and instead setting a baseUrl in a config file or by placing your index.html file on the restful server.</p> +<p>In this example you should really be using relative URL’s in your collections/models and instead setting a baseUrl in a config file or by placing your index.html file on the restful server.</p> <p>This example is hosted on GitHub therefore we had to include the absolute URL to the server which is hosted on nodejitsu.com</p> @@ -371,7 +335,7 @@ <p>Get in touch with me on twitter, comments or GitHub!</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <p><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></p> @@ -387,7 +351,8 @@ <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -410,17 +375,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/organizing-backbone-using-modules/index.html b/_site/organizing-backbone-using-modules/index.html index e578138..7c76b15 100644 --- a/_site/organizing-backbone-using-modules/index.html +++ b/_site/organizing-backbone-using-modules/index.html @@ -5,71 +5,54 @@ <title>Organizing your application using Modules (require.js) - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,7 +81,7 @@ <div id="post"> -<h1>Organizing your application using Modules (require.js)</h1> +<h1 id="organizing-your-application-using-modules-requirejs">Organizing your application using Modules (require.js)</h1> <p>Unfortunately Backbone.js does not tell you how to organize your code, leaving many developers in the dark regarding how to load scripts and lay out their development environments.</p> @@ -106,7 +91,7 @@ <p>This tutorial will get you started on combining Backbone.js with <a href="https://github.com/amdjs/amdjs-api/wiki/AMD">AMD</a> (Asynchronous Module Definitions).</p> -<h2>What is AMD?</h2> +<h2 id="what-is-amd">What is AMD?</h2> <p><a href="https://github.com/amdjs/amdjs-api/wiki/AMD">Asynchronous Module Definitions</a> designed to load modular code asynchronously in the browser and server. It is actually a fork of the Common.js specification. Many script loaders have built their implementations around AMD, seeing it as the future of modular JavaScript development.</p> @@ -117,26 +102,20 @@ <p>Quick Overview</p> <ul> -<li>Modular</li> -<li>Scalable</li> -<li>Compiles well(see <a href="http://requirejs.org/docs/optimization.html">r.js</a> )</li> -<li>Market Adoption( <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 converted fully to AMD</a> )</li> + <li>Modular</li> + <li>Scalable</li> + <li>Compiles well(see <a href="http://requirejs.org/docs/optimization.html">r.js</a> )</li> + <li>Market Adoption( <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 converted fully to AMD</a> )</li> </ul> +<h2 id="why-requirejs">Why Require.js?</h2> -<h2>Why Require.js?</h2> - -<ol type="a"> -<li>Require.js has a great community and it is growing rapidly. <a href="http://tagneto.blogspot.com/">James Burke</a> the author is married to Require.js and always responds to user feedback. He is a leading expert in script loading and a contributer to the AMD specification.</li> -</ol> - - -<p><a href="https://twitter.com/jrburke" class="twitter-follow-button">Follow @jrburke</a></p> +<p>p. Require.js has a great community and it is growing rapidly. <a href="http://tagneto.blogspot.com/">James Burke</a> the author is married to Require.js and always responds to user feedback. He is a leading expert in script loading and a contributer to the AMD specification.</p> -<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script> +<p><a href="https://twitter.com/jrburke" class="twitter-follow-button">Follow @jrburke</a> +<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script></p> - -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> @@ -148,13 +127,13 @@ <p>If you would like to see how a particular use case would be implemented please visit the GitHub page and create an issue.(Example Request: How to do nested views).</p> -<p>The example isn't super fleshed out but should give you a vague idea.</p> +<p>The example isn’t super fleshed out but should give you a vague idea.</p> -<h2>Example File Structure</h2> +<h2 id="example-file-structure">Example File Structure</h2> <p>There are many different ways to lay out your files and I believe it is actually dependent on the size and type of the project. In the example below views and templates are mirrored in file structure. Collections and Models are categorized into folders kind of like an ORM.</p> -<div class="highlight"><pre><code class="javascript"><span class="cm">/* File Structure</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="cm">/* File Structure</span> <span class="cm">├── imgs</span> <span class="cm">├── css</span> <span class="cm">│ └── style.css</span> @@ -193,25 +172,23 @@ <span class="cm">│ └── text.js //Require.js plugin</span> <span class="cm">└── index.html</span> -<span class="cm">*/</span> -</code></pre></div> - +<span class="cm">*/</span></code></pre></div> <p>To continue you must really understand what we are aiming towards as described in the introduction.</p> -<h2>Bootstrapping your application</h2> +<h2 id="bootstrapping-your-application">Bootstrapping your application</h2> <p>Using Require.js we define a single entry point on our index page. We should setup any useful containers that might be used by our Backbone views.</p> -<p><em>Note: The data-main attribute on our single script tag tells Require.js to load the script located at "js/main.js". It automatically appends the ".js"</em></p> +<p><em>Note: The data-main attribute on our single script tag tells Require.js to load the script located at “js/main.js”. It automatically appends the “.js”</em></p> -<div class="highlight"><pre><code class="html"><span class="cp"><!doctype html></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="cp"><!doctype html></span> <span class="nt"><html</span> <span class="na">lang=</span><span class="s">"en"</span><span class="nt">></span> <span class="nt"><head></span> - <span class="nt"><title></span>Jackie Chan<span class="nt"></title></span> - <span class="c"><!-- Load the script "js/main.js" as our entry point --></span> - <span class="nt"><script </span><span class="na">data-main=</span><span class="s">"js/main"</span> <span class="na">src=</span><span class="s">"js/libs/require/require.js"</span><span class="nt">></script></span> + <span class="nt"><title></span>Jackie Chan<span class="nt"></title></span> + <span class="c"><!-- Load the script "js/main.js" as our entry point --></span> + <span class="nt"><script </span><span class="na">data-main=</span><span class="s">"js/main"</span> <span class="na">src=</span><span class="s">"js/libs/require/require.js"</span><span class="nt">></script></span> <span class="nt"></head></span> <span class="nt"><body></span> @@ -221,27 +198,25 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="nt"></div></span> <span class="nt"></body></span> -<span class="nt"></html></span> -</code></pre></div> - +<span class="nt"></html></span></code></pre></div> <p>You should most always end up with quite a light weight index file. You can serve this off your server and then the rest of your site off a CDN ensuring that everything that can be cached, will be. (You can also now serve the index file off the CDN using Cloudfront)</p> -<h3>What does the bootstrap look like?</h3> +<h3 id="what-does-the-bootstrap-look-like">What does the bootstrap look like?</h3> <p>Our bootstrap file will be responsible for configuring Require.js and loading initially important dependencies.</p> <p>In the example below we configure Require.js to create a shortcut alias to commonly used scripts such as jQuery, Underscore and Backbone.</p> -<p>Unfortunately Backbone.js isn't AMD enabled so I downloaded the community managed repository and patched it on <a href="https://github.com/amdjs">amdjs</a>.</p> +<p>Unfortunately Backbone.js isn’t AMD enabled so I downloaded the community managed repository and patched it on <a href="https://github.com/amdjs">amdjs</a>.</p> <p>Hopefully if the AMD specification takes off these libraries will add code to allow themselves to be loaded asynchronously. Due to this inconvenience the bootstrap is not as intuitive as it could be.</p> -<p>We also request a module called "app", this will contain the entirety of our application logic.</p> +<p>We also request a module called “app”, this will contain the entirety of our application logic.</p> -<p><em>Note: Modules are loaded relatively to the boot strap and always append with ".js". So the module "app" will load "app.js" which is in the same directory as the bootstrap.</em></p> +<p><em>Note: Modules are loaded relatively to the boot strap and always append with “.js”. So the module “app” will load “app.js” which is in the same directory as the bootstrap.</em></p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: main.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: main.js</span> <span class="c1">// Require.js allows us to configure shortcut alias</span> <span class="c1">// There usage will become more apparent further along in the tutorial.</span> @@ -261,23 +236,21 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">App</span><span class="p">){</span> <span class="c1">// The "app" dependency is passed in as "App"</span> <span class="nx">App</span><span class="p">.</span><span class="nx">initialize</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<h2>How should we lay out external scripts?</h2> +<h2 id="how-should-we-lay-out-external-scripts">How should we lay out external scripts?</h2> <p>Any modules we develop for our application using AMD/Require.js will be asynchronously loaded.</p> -<p>We have a heavy dependency on jQuery, Underscore and Backbone. Unfortunately, these libraries are loaded synchronously and also depend on each other existing in the global namespace.</p> +<p>We have a heavy dependency on jQuery, Underscore and Backbone, unfortunately this libraries are loaded synchronously and also depend on each other existing in the global namespace.</p> -<h2>A boiler plate module</h2> +<h2 id="a-boiler-plate-module">A boiler plate module</h2> -<p>So before we start developing our application, let's quickly look over boiler plate code that will be reused quite often.</p> +<p>So before we start developing our application, let’s quickly look over boiler plate code that will be reused quite often.</p> -<p>For convenience sake I generally keep a "boilerplate.js" in my application root so I can copy it when I need to.</p> +<p>For convenience sake I generally keep a “boilerplate.js” in my application root so I can copy it when I need to.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">//Filename: boilerplate.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">//Filename: boilerplate.js</span> <span class="nx">define</span><span class="p">([</span> <span class="c1">// These are path alias that we configured in our bootstrap</span> @@ -289,19 +262,17 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="c1">// They will not be accessible in the global scope</span> <span class="k">return</span> <span class="p">{};</span> <span class="c1">// What we return here will be used by other modules</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>The first argument of the define function is our dependency array, in the future we can pass in any modules we like.</p> -<h2>App.js Building our applications main module</h2> +<h2 id="appjs-building-our-applications-main-module">App.js Building our applications main module</h2> <p>Our applications main module should always remain light weight. This tutorial only covers setting up a Backbone Router and initializing it in our main module.</p> <p>The router will then load the correct dependencies depending on the current URL.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: app.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: app.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> @@ -316,20 +287,16 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div> - - - +<span class="p">});</span></code></pre></div> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: router.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: router.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span><span class="p">,</span> <span class="s1">'views/projects/list'</span><span class="p">,</span> <span class="s1">'views/users/list'</span> -<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">Session</span><span class="p">,</span> <span class="nx">ProjectListView</span><span class="p">,</span> <span class="nx">UserListView</span><span class="p">){</span> +<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">ProjectListView</span><span class="p">,</span> <span class="nx">UserListView</span><span class="p">){</span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="c1">// Define some URL routes</span> @@ -364,15 +331,13 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<h2>Modularizing a Backbone View</h2> +<h2 id="modularizing-a-backbone-view">Modularizing a Backbone View</h2> <p>Backbone views usually interact with the DOM. Using our new modular system we can load in JavaScript templates using the Require.js text! plug-in.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/project/list</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/project/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> @@ -393,19 +358,17 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">});</span> <span class="c1">// Our module now returns our view</span> <span class="k">return</span> <span class="nx">ProjectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>JavaScript templating allows us to separate the design from the application logic by placing all our HTML in the templates folder.</p> -<h2>Modularizing a Collection, Model and View</h2> +<h2 id="modularizing-a-collection-model-and-view">Modularizing a Collection, Model and View</h2> <p>Now we put it altogether by chaining up a Model, Collection and View which is a typical scenario when building a Backbone.js application.</p> <p>First we will define our model</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: models/project</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: models/project</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span> @@ -417,15 +380,15 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">});</span> <span class="c1">// Return the model for the module</span> <span class="k">return</span> <span class="nx">ProjectModel</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> +<span class="p">});</span></code></pre></div> +<p>Now that we have a model, our collection module can depend on it. We will set the “model” attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> -<p>Now that we have a model, our collection module can depend on it. We will set the "model" attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> +<blockquote> + <p>Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.</p> +</blockquote> -<blockquote><p>Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.</p></blockquote> - -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: collections/projects</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: collections/projects</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'underscore'</span><span class="p">,</span> <span class="s1">'backbone'</span><span class="p">,</span> @@ -437,13 +400,11 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">});</span> <span class="c1">// You don't usually return a collection instantiated</span> <span class="k">return</span> <span class="nx">ProjectCollection</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>Now we can simply depend on our collection in our view and pass it to our JavaScript template.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/projects/list</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/projects/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'underscore'</span><span class="p">,</span> @@ -464,30 +425,26 @@ We should setup any useful containers that might be used by our Backbone views.< <span class="p">});</span> <span class="c1">// Returning instantiated views can be quite useful for having "state"</span> <span class="k">return</span> <span class="nx">ProjectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>Looking forward to feedback so I can turn this post and example into quality references on building modular JavaScript applications.</p> <p>Get in touch with me on twitter, comments or GitHub!</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></li> + <li><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/dzejkej">Jakub Kozisek</a> (created modular-backbone-updated containing updated libs with AMD support)</li> + <li><a href="https://github.com/dzejkej">Jakub Kozisek</a> (created modular-backbone-updated containing updated libs with AMD support)</li> </ul> - </div> </div> @@ -500,7 +457,8 @@ We should setup any useful containers that might be used by our Backbone views.< <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -523,17 +481,9 @@ We should setup any useful containers that might be used by our Backbone views.< </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/rss.xml b/_site/rss.xml index dfc212f..dd3d045 100644 --- a/_site/rss.xml +++ b/_site/rss.xml @@ -4,7 +4,7 @@ <title>Backbone Tutorials</title> <link href="http://backbonetutorials.com/atom.xml" rel="self"/> <link href="http://backbonetutorials.com/"/> - <updated>2013-08-14T18:01:55+10:00</updated> + <updated>2014-11-14T09:02:49+10:00</updated> <id>http://backbonetutorials.com/</id> <author> <name>Thomas Davis</name> @@ -12,78 +12,170 @@ </author> <entry> - <title>SEO for single page applications</title> - <link href="http://backbonetutorials.com/seo-for-single-page-apps?cachebust"/> - <updated>2012-08-01T00:00:00+10:00</updated> - <id>http://backbonetutorials.com/seo-for-single-page-apps</id> - <content type="html"><h1>SEO for single page apps</h1> + <title>Real-Time Backbone With PubNub</title> + <link href="http://backbonetutorials.com/real-time-backbone-with-pubnub?cachebust"/> + <updated>2013-08-29T00:00:00+10:00</updated> + <id>http://backbonetutorials.com/real-time-backbone-with-pubnub</id> + <content type="html"><h1 id="real-time-backbone-with-pubnub">Real-Time Backbone With PubNub</h1> -<p>This tutorial will show you how to index your application on search engines. As the author I believe that servers should be completely independent of the client in the age of API's. Which speeds up development for the ever increasing array of clients. It is on the shoulders of the search engines to conform and they should not dictate how the web is stored and accessed.</p> +<p>Backbone is one of the most popular JavaScript based frameworks to date. It is a simple yet powerful way to create interactive JavaScript applications with data bindings to a back-end server. Instead of having to constantly synchronize data between your client and server though, why not have all the data there when it happens? Users should not have to wait to see updates to their model’s data so we decided to tackle this problem by integrating Backbone.js with PubNub.</p> -<p>In 2009 Google released the idea of <a href="http://googlewebmastercentral.blogspot.com.au/2009/10/proposal-for-making-ajax-crawlable.html">escaped fragments</a>.</p> +<p><img src="http://blogly.pubnub.com/wp-content/uploads/2013/08/PubNubBackboneJS.png" alt="PubnNub and Backbone" /></p> -<p>The idea simply stating that if a search engine should come across your JavaScript application then you have the permission to redirect the search engine to another URL that serves the fully rendered version of the page (The current search engines cannot execute much JavaScript (Some people speculate that Google Chrome was born of Google Search wishing to successfully render every web page to retrieve ajaxed content)).</p> +<p>Our integration allows developers to create a Backbone model or collection and have them synchronize with every other client instance of those models or collections in real-time. This will give any Backbone application a better user experience when working with collaborative, social, or any type of multi-user interface. It works by taking all of the create, update, and delete methods that are spawned by Backbone and propagating them across the PubNub real-time network.</p> -<h2>How does redirecting bots work?</h2> +<p>Want to see it in action? A full working tutorial and all the code you need is available at our <a href="http://pubnub.github.io/backbone/">GitHub page</a></p> -<p>Using modern headless browsers, we can easily return the fully rendered content per request by redirecting bots using our web servers configuration. Here is an image made by Google depicting the setup.</p> +<h2 id="getting-started">Getting Started</h2> -<p><img src="http://acris.googlecode.com/svn/wiki/images/seo_google_crawlability.png" alt="headless seo" /></p> +<p>The easiest way to get started is by using bower via <code>bower install pubnub-backbone</code>. You can also clone the repository and copy the built javascript files. Now you can include this and the base PubNub library found at <a href="https://github.com/pubnub/javascript#pubnub-cdn-javascript-sdk">https://github.com/pubnub/javascript#pubnub-cdn-javascript-sdk</a> like so:</p> -<div style='clear: both;'></div> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;http://cdn.pubnub.com/pubnub.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span> +<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;/path/to/backbone-pubnub.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span></code></pre></div> +<p>The easiest way to get started using the library is by creating a PubNub based collection. This will automatically propagate all create, update, and delete methods across all other clients in real-time. This requires creating a free account to get your API keys at <a href="http://pubnub.com/free-trial">http://pubnub.com/free-trial</a> and then initializing a global PubNub instance:</p> -<h2>Implementation using Phantom.js</h2> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">pubnub</span> <span class="o">=</span> <span class="nx">PUBNUB</span><span class="p">.</span><span class="nx">init</span><span class="p">({</span> + <span class="nx">publish_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span><span class="p">,</span> + <span class="nx">subscribe_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span> +<span class="p">});</span></code></pre></div> -<p><a href="http://phantomjs.org/">Phantom.js</a> is a headless webkit browser. We are going to setup a node.js server that given a URL, it will fully render the page content. Then we will redirect bots to this server to retrieve the correct content.</p> +<h2 id="creating-a-real-time-collection">Creating a Real-Time Collection</h2> -<p>You will need to install node.js and phantom.js onto a box. Then start up this server below. There are two files, one which is the web server and the other is a phantomjs script that renders the page.</p> +<p>Now that we have a connection to PubNub, we can feed that connection into our custom Backbone collection:</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// web.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">MyCollection</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">PubNub</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;MyCollection&#39;</span><span class="p">,</span> + <span class="nx">pubnub</span><span class="o">:</span> <span class="nx">pubnub</span> +<span class="p">});</span></code></pre></div> -<span class="c1">// Express is our web server that can handle request</span> -<span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> -<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span> +<p>This will look and act just like a normal Backbone collection with two extra keys. The “name” key allows PubNub to distinguish this collection, so it connects this collections to only collections of the same type. Think of this as a namespace so you can have multiple types of collections all updating in real-time. It uses this to generate a PubNub channel that is unique to the collection in the form of “backbone-collection-{name}”. The “pubnub” property is the globally referenced connection to the PubNub network. This is the object that comes back after calling PUBNUB.init.</p> +<p>Now your Backbone collection will update in real-time. You can listen for add and remove events just like usual when something gets added or removed in real-time. The next step is to implement a way to get the current set of data when the collection first loads so every client is using the same data set. A great way of accomplishing this is by listening to the PubNub based events with a server and replicating the data store. Then the client can ask for the current set of data every time the application loads. This is made even simpler when using the backbone npm module for nodejs:</p> -<span class="kd">var</span> <span class="nx">getContent</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span> - <span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span> - <span class="c1">// Here we spawn a phantom.js process, the first element of the </span> - <span class="c1">// array is our phantomjs script and the second element is our url </span> - <span class="kd">var</span> <span class="nx">phantom</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;child_process&#39;</span><span class="p">).</span><span class="nx">spawn</span><span class="p">(</span><span class="s1">&#39;phantomjs&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;phantom-server.js&#39;</span><span class="p">,</span> <span class="nx">url</span><span class="p">]);</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">setEncoding</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">);</span> - <span class="c1">// Our phantom.js script is simply logging the output and</span> - <span class="c1">// we access it here through stdout</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">content</span> <span class="o">+=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span> - <span class="p">});</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;exit&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> - <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;We have an error&#39;</span><span class="p">);</span> - <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> - <span class="c1">// once our phantom.js script exits, let&#39;s call out call back</span> - <span class="c1">// which outputs the contents to the page</span> - <span class="nx">callback</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;underscore&#39;</span><span class="p">).</span><span class="nx">_</span><span class="p">,</span> + <span class="nx">Backbone</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;backbone&#39;</span><span class="p">),</span> + <span class="nx">pubnub</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;pubnub&#39;</span><span class="p">).</span><span class="nx">init</span><span class="p">({</span> + <span class="nx">publish_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span><span class="p">,</span> + <span class="nx">subscribe_key</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span> + <span class="p">});</span> + +<span class="kd">var</span> <span class="nx">MyCollection</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="c1">// Add business logic here</span> +<span class="p">});</span> + +<span class="kd">var</span> <span class="nx">myCollection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyCollection</span><span class="p">();</span> + +<span class="nx">pubnub</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">({</span> + <span class="nx">channel</span><span class="o">:</span> <span class="s1">&#39;backbone-collection-MyCollection&#39;</span><span class="p">,</span> <span class="c1">// This is what is created internally by the framework</span> + <span class="nx">callback</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> + <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span> <span class="c1">// All data is transferred as JSON</span> + + <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">method</span> <span class="o">===</span> <span class="s1">&#39;create&#39;</span><span class="p">)</span> <span class="p">{</span> + <span class="nx">myCollection</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">);</span> + <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">method</span> <span class="o">===</span> <span class="s1">&#39;update&#39;</span><span class="p">)</span> <span class="p">{</span> + <span class="nx">myCollection</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">);</span> + <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">method</span> <span class="o">===</span> <span class="s1">&#39;delete&#39;</span><span class="p">)</span> <span class="p">{</span> + <span class="kd">var</span> <span class="nx">record</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">myCollection</span><span class="p">.</span><span class="nx">models</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">record</span><span class="p">)</span> <span class="p">{</span> + <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">id</span> <span class="o">===</span> <span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span> + <span class="p">});</span> + + <span class="k">if</span> <span class="p">(</span><span class="nx">record</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span> + <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Could not record: &quot;</span> <span class="o">+</span> <span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span> + <span class="p">}</span> + + <span class="kd">var</span> <span class="nx">diff</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">difference</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">record</span><span class="p">.</span><span class="nx">attributes</span><span class="p">),</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">));</span> + <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">diff</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span> + <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">unset</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span> + <span class="p">});</span> + + <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">model</span><span class="p">,</span> <span class="nx">data</span><span class="p">.</span><span class="nx">options</span><span class="p">);</span> <span class="p">}</span> - <span class="p">});</span> -<span class="p">};</span> + <span class="p">}</span> +<span class="p">});</span> + +<span class="c1">// Now myCollection will always be up to date.</span> +<span class="c1">// Here you can provide some way (i.e. http.createServer) to get the data from the server.</span></code></pre></div> -<span class="kd">var</span> <span class="nx">respond</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span> - <span class="c1">// Because we use [P] in htaccess we have access to this header</span> - <span class="nx">url</span> <span class="o">=</span> <span class="s1">&#39;http://&#39;</span> <span class="o">+</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">&#39;x-forwarded-host&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> - <span class="nx">getContent</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span> - <span class="p">});</span> -<span class="p">}</span> +<p>Now you can listen for all the changes to the collection and either store them in memory or even a database such as MongoDB. You can even add other business logic for validations and more. Although nodejs was an obvious choice for the demo, this code will work with any type of back end too. This is just one easy way to use the framework but be sure to check out the repository for more examples!</p> + +<p>We here at PubNub truly believe that real-time is the way of the future. Your users will not have to click a refresh button to constantly synchronize their Backbone client data with a server. Instead, with PubNub integration, your users will get data right when it happens. This is also much more extensible since any client or server can listen to the events and manipulate them as they need to. This allows business logic to lay in more places than one. We really hope this changes the way developers look at building not just Backbone applications but web applications overall.</p> -<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sr">/(.*)/</span><span class="p">,</span> <span class="nx">respond</span><span class="p">);</span> -<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span> -</code></pre></div> +<p>You can read more about PubNub at <a href="http://pubnub.com">our website</a> and more about Backbone integration at <a href="http://pubnub.github.io/backbone/">our GitHub page</a></p> +</content> + </entry> + + <entry> + <title>SEO for single page applications</title> + <link href="http://backbonetutorials.com/seo-for-single-page-apps?cachebust"/> + <updated>2012-08-01T00:00:00+10:00</updated> + <id>http://backbonetutorials.com/seo-for-single-page-apps</id> + <content type="html"><h1 id="seo-for-single-page-apps">SEO for single page apps</h1> + +<p>This tutorial will show you how to index your application on search engines. As the author I believe that servers should be completely independent of the client in the age of API’s. Which speeds up development for the ever increasing array of clients. It is on the shoulders of the search engines to conform and they should not dictate how the web is stored and accessed.</p> + +<p>In 2009 Google released the idea of <a href="http://googlewebmastercentral.blogspot.com.au/2009/10/proposal-for-making-ajax-crawlable.html">escaped fragments</a>. </p> + +<p>The idea simply stating that if a search engine should come across your JavaScript application then you have the permission to redirect the search engine to another URL that serves the fully rendered version of the page (The current search engines cannot execute much JavaScript (Some people speculate that Google Chrome was born of Google Search wishing to successfully render every web page to retrieve ajaxed content)).</p> + +<h2 id="how-does-redirecting-bots-work">How does redirecting bots work?</h2> + +<p>Using modern headless browsers, we can easily return the fully rendered content per request by redirecting bots using our web servers configuration. Here is an image made by Google depicting the setup.</p> +<p><img src="http://acris.googlecode.com/svn/wiki/images/seo_google_crawlability.png" alt="headless seo" /></p> + +<div style="clear: both;"></div> + +<h2 id="implementation-using-phantomjs">Implementation using Phantom.js</h2> + +<p><a href="http://phantomjs.org/">Phantom.js</a> is a headless webkit browser. We are going to setup a node.js server that given a URL, it will fully render the page content. Then we will redirect bots to this server to retrieve the correct content.</p> -<p>The script below is <code>phantom-server.js</code> and will be in charge of fully rendering the content. We don't return the content until the page is fully rendered. We hook into the resources listener to do this.</p> +<p>You will need to install node.js and phantom.js onto a box. Then start up this server below. There are two files, one which is the web server and the other is a phantomjs script that renders the page.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;webpage&#39;</span><span class="p">).</span><span class="nx">create</span><span class="p">();</span> +<p>```javascript +// web.js</p> + +<p>// Express is our web server that can handle request +var express = require(‘express’); +var app = express();</p> + +<p>var getContent = function(url, callback) { + var content = ‘’; + // Here we spawn a phantom.js process, the first element of the + // array is our phantomjs script and the second element is our url + var phantom = require(‘child_process’).spawn(‘phantomjs’, [‘phantom-server.js’, url]); + phantom.stdout.setEncoding(‘utf8’); + // Our phantom.js script is simply logging the output and + // we access it here through stdout + phantom.stdout.on(‘data’, function(data) { + content += data.toString(); + }); + phantom.on(‘exit’, function(code) { + if (code !== 0) { + console.log(‘We have an error’); + } else { + // once our phantom.js script exits, let’s call out call back + // which outputs the contents to the page + callback(content); + } + }); +};</p> + +<p>var respond = function (req, res) { + // Because we use [P] in htaccess we have access to this header + url = ‘http://’ + req.headers[‘x-forwarded-host’] + req.params[0]; + getContent(url, function (content) { + res.send(content); + }); +}</p> + +<p>app.get(/(.*)/, respond); +app.listen(3000); +```</p> + +<p>The script below is <code>phantom-server.js</code> and will be in charge of fully rendering the content. We don’t return the content until the page is fully rendered. We hook into the resources listener to do this.</p> + +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;webpage&#39;</span><span class="p">).</span><span class="nx">create</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;system&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">lastReceived</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">();</span> @@ -119,25 +211,21 @@ <span class="p">}</span> <span class="p">}</span> <span class="c1">// Let us check to see if the page is finished rendering</span> -<span class="kd">var</span> <span class="nx">checkCompleteInterval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="nx">checkComplete</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> -</code></pre></div> +<span class="kd">var</span> <span class="nx">checkCompleteInterval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="nx">checkComplete</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span></code></pre></div> +<p>Once we have this server up and running we just redirect bots to the server in our client’s web server configuration.</p> -<p>Once we have this server up and running we just redirect bots to the server in our client's web server configuration.</p> - -<h2>Redirecting bots</h2> +<h2 id="redirecting-bots">Redirecting bots</h2> <p>If you are using apache we can edit out <code>.htaccess</code> such that Google requests are proxied to our middle man phantom.js server.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">RewriteEngine</span> <span class="nx">on</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">RewriteEngine</span> <span class="nx">on</span> <span class="nx">RewriteCond</span> <span class="o">%</span><span class="p">{</span><span class="nx">QUERY_STRING</span><span class="p">}</span> <span class="o">^</span><span class="nx">_escaped_fragment_</span><span class="o">=</span><span class="p">(.</span><span class="o">*</span><span class="p">)</span><span class="nx">$</span> -<span class="nx">RewriteRule</span> <span class="p">(.</span><span class="o">*</span><span class="p">)</span> <span class="nx">http</span><span class="o">:</span><span class="c1">//webserver:3000/%1? [P]</span> -</code></pre></div> - +<span class="nx">RewriteRule</span> <span class="p">(.</span><span class="o">*</span><span class="p">)</span> <span class="nx">http</span><span class="o">:</span><span class="c1">//webserver:3000/%1? [P]</span></code></pre></div> <p>We could also include other <code>RewriteCond</code>, such as <code>user agent</code> to redirect other search engines we wish to be indexed on.</p> -<p>Though Google won't use <code>_escaped_fragment_</code> unless we tell it to by either including a meta tag; +<p>Though Google won’t use <code>_escaped_fragment_</code> unless we tell it to by either including a meta tag; <code>&lt;meta name="fragment" content="!"&gt;</code> or using <code>#!</code> URLs in our links.</p> @@ -148,12 +236,11 @@ using <code>#!</code> URLs in our links.</p> <p>This has been tested with Google Webmasters fetch tool. Make sure you include <code>#!</code> on your URLs when using the fetch tool.</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://seo.apiengine.io">Open source node.js Seo Server</a></li> + <li><a href="http://seo.apiengine.io">Open source node.js Seo Server</a></li> </ul> - </content> </entry> @@ -162,7 +249,7 @@ using <code>#!</code> URLs in our links.</p> <link href="http://backbonetutorials.com/organizing-backbone-using-modules?cachebust"/> <updated>2011-10-10T00:00:00+10:00</updated> <id>http://backbonetutorials.com/organizing-backbone-using-modules</id> - <content type="html"><h1>Organizing your application using Modules (require.js)</h1> + <content type="html"><h1 id="organizing-your-application-using-modules-requirejs">Organizing your application using Modules (require.js)</h1> <p>Unfortunately Backbone.js does not tell you how to organize your code, leaving many developers in the dark regarding how to load scripts and lay out their development environments.</p> @@ -172,7 +259,7 @@ using <code>#!</code> URLs in our links.</p> <p>This tutorial will get you started on combining Backbone.js with <a href="https://github.com/amdjs/amdjs-api/wiki/AMD">AMD</a> (Asynchronous Module Definitions).</p> -<h2>What is AMD?</h2> +<h2 id="what-is-amd">What is AMD?</h2> <p><a href="https://github.com/amdjs/amdjs-api/wiki/AMD">Asynchronous Module Definitions</a> designed to load modular code asynchronously in the browser and server. It is actually a fork of the Common.js specification. Many script loaders have built their implementations around AMD, seeing it as the future of modular JavaScript development.</p> @@ -183,26 +270,20 @@ using <code>#!</code> URLs in our links.</p> <p>Quick Overview</p> <ul> -<li>Modular</li> -<li>Scalable</li> -<li>Compiles well(see <a href="http://requirejs.org/docs/optimization.html">r.js</a> )</li> -<li>Market Adoption( <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 converted fully to AMD</a> )</li> + <li>Modular</li> + <li>Scalable</li> + <li>Compiles well(see <a href="http://requirejs.org/docs/optimization.html">r.js</a> )</li> + <li>Market Adoption( <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 converted fully to AMD</a> )</li> </ul> +<h2 id="why-requirejs">Why Require.js?</h2> -<h2>Why Require.js?</h2> - -<ol type="a"> -<li>Require.js has a great community and it is growing rapidly. <a href="http://tagneto.blogspot.com/">James Burke</a> the author is married to Require.js and always responds to user feedback. He is a leading expert in script loading and a contributer to the AMD specification.</li> -</ol> - - -<p><a href="https://twitter.com/jrburke" class="twitter-follow-button">Follow @jrburke</a></p> +<p>p. Require.js has a great community and it is growing rapidly. <a href="http://tagneto.blogspot.com/">James Burke</a> the author is married to Require.js and always responds to user feedback. He is a leading expert in script loading and a contributer to the AMD specification.</p> -<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script> +<p><a href="https://twitter.com/jrburke" class="twitter-follow-button">Follow @jrburke</a> +<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script></p> - -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> @@ -214,13 +295,13 @@ using <code>#!</code> URLs in our links.</p> <p>If you would like to see how a particular use case would be implemented please visit the GitHub page and create an issue.(Example Request: How to do nested views).</p> -<p>The example isn't super fleshed out but should give you a vague idea.</p> +<p>The example isn’t super fleshed out but should give you a vague idea.</p> -<h2>Example File Structure</h2> +<h2 id="example-file-structure">Example File Structure</h2> <p>There are many different ways to lay out your files and I believe it is actually dependent on the size and type of the project. In the example below views and templates are mirrored in file structure. Collections and Models are categorized into folders kind of like an ORM.</p> -<div class="highlight"><pre><code class="javascript"><span class="cm">/* File Structure</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="cm">/* File Structure</span> <span class="cm">├── imgs</span> <span class="cm">├── css</span> <span class="cm">│ └── style.css</span> @@ -259,25 +340,23 @@ using <code>#!</code> URLs in our links.</p> <span class="cm">│ └── text.js //Require.js plugin</span> <span class="cm">└── index.html</span> -<span class="cm">*/</span> -</code></pre></div> - +<span class="cm">*/</span></code></pre></div> <p>To continue you must really understand what we are aiming towards as described in the introduction.</p> -<h2>Bootstrapping your application</h2> +<h2 id="bootstrapping-your-application">Bootstrapping your application</h2> <p>Using Require.js we define a single entry point on our index page. We should setup any useful containers that might be used by our Backbone views.</p> -<p><em>Note: The data-main attribute on our single script tag tells Require.js to load the script located at "js/main.js". It automatically appends the ".js"</em></p> +<p><em>Note: The data-main attribute on our single script tag tells Require.js to load the script located at “js/main.js”. It automatically appends the “.js”</em></p> -<div class="highlight"><pre><code class="html"><span class="cp">&lt;!doctype html&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="cp">&lt;!doctype html&gt;</span> <span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">&quot;en&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;head&gt;</span> - <span class="nt">&lt;title&gt;</span>Jackie Chan<span class="nt">&lt;/title&gt;</span> - <span class="c">&lt;!-- Load the script &quot;js/main.js&quot; as our entry point --&gt;</span> - <span class="nt">&lt;script </span><span class="na">data-main=</span><span class="s">&quot;js/main&quot;</span> <span class="na">src=</span><span class="s">&quot;js/libs/require/require.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span> + <span class="nt">&lt;title&gt;</span>Jackie Chan<span class="nt">&lt;/title&gt;</span> + <span class="c">&lt;!-- Load the script &quot;js/main.js&quot; as our entry point --&gt;</span> + <span class="nt">&lt;script </span><span class="na">data-main=</span><span class="s">&quot;js/main&quot;</span> <span class="na">src=</span><span class="s">&quot;js/libs/require/require.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span> <span class="nt">&lt;/head&gt;</span> <span class="nt">&lt;body&gt;</span> @@ -287,27 +366,25 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/body&gt;</span> -<span class="nt">&lt;/html&gt;</span> -</code></pre></div> - +<span class="nt">&lt;/html&gt;</span></code></pre></div> <p>You should most always end up with quite a light weight index file. You can serve this off your server and then the rest of your site off a CDN ensuring that everything that can be cached, will be. (You can also now serve the index file off the CDN using Cloudfront)</p> -<h3>What does the bootstrap look like?</h3> +<h3 id="what-does-the-bootstrap-look-like">What does the bootstrap look like?</h3> <p>Our bootstrap file will be responsible for configuring Require.js and loading initially important dependencies.</p> <p>In the example below we configure Require.js to create a shortcut alias to commonly used scripts such as jQuery, Underscore and Backbone.</p> -<p>Unfortunately Backbone.js isn't AMD enabled so I downloaded the community managed repository and patched it on <a href="https://github.com/amdjs">amdjs</a>.</p> +<p>Unfortunately Backbone.js isn’t AMD enabled so I downloaded the community managed repository and patched it on <a href="https://github.com/amdjs">amdjs</a>.</p> <p>Hopefully if the AMD specification takes off these libraries will add code to allow themselves to be loaded asynchronously. Due to this inconvenience the bootstrap is not as intuitive as it could be.</p> -<p>We also request a module called "app", this will contain the entirety of our application logic.</p> +<p>We also request a module called “app”, this will contain the entirety of our application logic.</p> -<p><em>Note: Modules are loaded relatively to the boot strap and always append with ".js". So the module "app" will load "app.js" which is in the same directory as the bootstrap.</em></p> +<p><em>Note: Modules are loaded relatively to the boot strap and always append with “.js”. So the module “app” will load “app.js” which is in the same directory as the bootstrap.</em></p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: main.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: main.js</span> <span class="c1">// Require.js allows us to configure shortcut alias</span> <span class="c1">// There usage will become more apparent further along in the tutorial.</span> @@ -327,23 +404,21 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">App</span><span class="p">){</span> <span class="c1">// The &quot;app&quot; dependency is passed in as &quot;App&quot;</span> <span class="nx">App</span><span class="p">.</span><span class="nx">initialize</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<h2>How should we lay out external scripts?</h2> +<h2 id="how-should-we-lay-out-external-scripts">How should we lay out external scripts?</h2> <p>Any modules we develop for our application using AMD/Require.js will be asynchronously loaded.</p> <p>We have a heavy dependency on jQuery, Underscore and Backbone, unfortunately this libraries are loaded synchronously and also depend on each other existing in the global namespace.</p> -<h2>A boiler plate module</h2> +<h2 id="a-boiler-plate-module">A boiler plate module</h2> -<p>So before we start developing our application, let's quickly look over boiler plate code that will be reused quite often.</p> +<p>So before we start developing our application, let’s quickly look over boiler plate code that will be reused quite often.</p> -<p>For convenience sake I generally keep a "boilerplate.js" in my application root so I can copy it when I need to.</p> +<p>For convenience sake I generally keep a “boilerplate.js” in my application root so I can copy it when I need to.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">//Filename: boilerplate.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">//Filename: boilerplate.js</span> <span class="nx">define</span><span class="p">([</span> <span class="c1">// These are path alias that we configured in our bootstrap</span> @@ -355,19 +430,17 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="c1">// They will not be accessible in the global scope</span> <span class="k">return</span> <span class="p">{};</span> <span class="c1">// What we return here will be used by other modules</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>The first argument of the define function is our dependency array, in the future we can pass in any modules we like.</p> -<h2>App.js Building our applications main module</h2> +<h2 id="appjs-building-our-applications-main-module">App.js Building our applications main module</h2> <p>Our applications main module should always remain light weight. This tutorial only covers setting up a Backbone Router and initializing it in our main module.</p> <p>The router will then load the correct dependencies depending on the current URL.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: app.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: app.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -382,20 +455,16 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div> - - - +<span class="p">});</span></code></pre></div> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: router.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: router.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> <span class="s1">&#39;views/projects/list&#39;</span><span class="p">,</span> <span class="s1">&#39;views/users/list&#39;</span> -<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">Session</span><span class="p">,</span> <span class="nx">ProjectListView</span><span class="p">,</span> <span class="nx">UserListView</span><span class="p">){</span> +<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">ProjectListView</span><span class="p">,</span> <span class="nx">UserListView</span><span class="p">){</span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="c1">// Define some URL routes</span> @@ -430,15 +499,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="k">return</span> <span class="p">{</span> <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span> <span class="p">};</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<h2>Modularizing a Backbone View</h2> +<h2 id="modularizing-a-backbone-view">Modularizing a Backbone View</h2> <p>Backbone views usually interact with the DOM. Using our new modular system we can load in JavaScript templates using the Require.js text! plug-in.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/project/list</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/project/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -459,19 +526,17 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// Our module now returns our view</span> <span class="k">return</span> <span class="nx">ProjectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>JavaScript templating allows us to separate the design from the application logic by placing all our HTML in the templates folder.</p> -<h2>Modularizing a Collection, Model and View</h2> +<h2 id="modularizing-a-collection-model-and-view">Modularizing a Collection, Model and View</h2> <p>Now we put it altogether by chaining up a Model, Collection and View which is a typical scenario when building a Backbone.js application.</p> <p>First we will define our model</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: models/project</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: models/project</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span> @@ -483,15 +548,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// Return the model for the module</span> <span class="k">return</span> <span class="nx">ProjectModel</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> -<p>Now that we have a model, our collection module can depend on it. We will set the "model" attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> +<p>Now that we have a model, our collection module can depend on it. We will set the “model” attribute of our collection to the loaded module. Backbone.js offers great benefits when doing this.</p> -<blockquote><p>Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.</p></blockquote> +<blockquote> + <p>Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.</p> +</blockquote> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: collections/projects</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: collections/projects</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -503,13 +568,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// You don&#39;t usually return a collection instantiated</span> <span class="k">return</span> <span class="nx">ProjectCollection</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>Now we can simply depend on our collection in our view and pass it to our JavaScript template.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/projects/list</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Filename: views/projects/list</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -530,29 +593,25 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="c1">// Returning instantiated views can be quite useful for having &quot;state&quot;</span> <span class="k">return</span> <span class="nx">ProjectListView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> +<span class="p">});</span></code></pre></div> - -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>Looking forward to feedback so I can turn this post and example into quality references on building modular JavaScript applications.</p> <p>Get in touch with me on twitter, comments or GitHub!</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></li> + <li><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/dzejkej">Jakub Kozisek</a> (created modular-backbone-updated containing updated libs with AMD support)</li> + <li><a href="https://github.com/dzejkej">Jakub Kozisek</a> (created modular-backbone-updated containing updated libs with AMD support)</li> </ul> - </content> </entry> @@ -561,45 +620,44 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/cross-domain-sessions?cachebust"/> <updated>2011-05-01T00:00:00+10:00</updated> <id>http://backbonetutorials.com/cross-domain-sessions</id> - <content type="html"><h1>Cross-domain Backbone.js with sessions using CORS</h1> + <content type="html"><h1 id="cross-domain-backbonejs-with-sessions-using-cors">Cross-domain Backbone.js with sessions using CORS</h1> -<p><strong> This tutorial is a proof of concept and needs to be checked for security flaws </strong></p> +<p>** This tutorial is a proof of concept and needs to be checked for security flaws **</p> <p>This tutorial will teach you how to completely separate the server and client allowing for developers to work with freedom in their respective areas.</p> <p>On a personal note, I consider this development practice highly desirable and encourage others to think of the possible benefits but the security still needs to be proved.</p> -<blockquote><p>Cross-Origin Resource Sharing (CORS) is a specification that enables a truly open access across domain-boundaries. - <a href="http://enable-cors.org/">enable-cors.org</a></p></blockquote> +<blockquote> + <p>Cross-Origin Resource Sharing (CORS) is a specification that enables a truly open access across domain-boundaries. - <a href="http://enable-cors.org/">enable-cors.org</a></p> +</blockquote> <p><strong>Some benefits include</strong></p> <ul> -<li>The client and back end exist independently regardless of where they are each hosted and built.</li> -<li>Due to the separation of concerns, testing now becomes easier and more controlled.</li> -<li>Develop only one API on the server, your front-end could be outsourced or built by a in-house team.</li> -<li>As a front-end developer you can host the client anywhere.</li> -<li>This separation enforces that the API be built robustly, documented, collaboratively and versioned.</li> + <li>The client and back end exist independently regardless of where they are each hosted and built.</li> + <li>Due to the separation of concerns, testing now becomes easier and more controlled.</li> + <li>Develop only one API on the server, your front-end could be outsourced or built by a in-house team.</li> + <li>As a front-end developer you can host the client anywhere.</li> + <li>This separation enforces that the API be built robustly, documented, collaboratively and versioned.</li> </ul> - -<p><strong> Cons of this tutorial </strong></p> +<p>** Cons of this tutorial **</p> <ul> -<li>This tutorial doesn't explain how to perform this with cross browser support. CORS headers aren't supported by Opera and IE 6/7. Though it is do-able using <a href="http://easyxdm.net/wp/">easyXDM</a></li> -<li>Security is somewhat addressed but maybe a more thorough security expert can chime in.</li> + <li>This tutorial doesn’t explain how to perform this with cross browser support. CORS headers aren’t supported by Opera and IE 6/7. Though it is do-able using <a href="http://easyxdm.net/wp/">easyXDM</a></li> + <li>Security is somewhat addressed but maybe a more thorough security expert can chime in.</li> </ul> - -<h2>Security</h2> +<h2 id="security">Security</h2> <ul> -<li>Don't allow GET request to change data, only retrieve.</li> -<li>Whitelist your allowed domains (see <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/server.js">server.js</a>)</li> -<li>Protect again <a href="http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html">JSON padding</a></li> + <li>Don’t allow GET request to change data, only retrieve.</li> + <li>Whitelist your allowed domains (see <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/server.js">server.js</a>)</li> + <li>Protect again <a href="http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html">JSON padding</a></li> </ul> - -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> @@ -611,11 +669,11 @@ We should setup any useful containers that might be used by our Backbone views.& <p>This tutorial focuses on building a flexible Session model to control session state in your application.</p> -<h2>Checking session state at first load</h2> +<h2 id="checking-session-state-at-first-load">Checking session state at first load</h2> <p>Before starting any routes, we should really know whether the user is authenticated. This will allow us to load the appropriate views. We will simply wrap our <code>Backbone.history.start</code> in a callback that executes after <code>Session.getAuth</code> has checked the server. We will jump into our Session model next.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -645,19 +703,17 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> <span class="p">})</span> <span class="p">}</span> - <span class="p">});</span> + <span class="p">});</span> <span class="k">return</span> <span class="nx">AppView</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: We have used jQuery <code>ajaxPrefilter</code> to hook into all AJAX requests before they are executed. This is where we specify what server we want the application to hit.</em></p> -<h2>An example Session model</h2> +<h2 id="an-example-session-model">An example Session model</h2> -<p>This is a very light weight Session model which handles most situations. Read through the code and comments below. The model simply has a login, logout and check function. Again we have hooked into jQuery <code>ajaxPrefilter</code> to allow for csrf tokens and also telling jQuery to send cookies with the <code>withCredentials</code> property. The model relies heavily on it's <code>auth</code> property. Throughout your application, each view can simply bind to <code>change:auth</code> on the Session model and react accordingly. Because we return this AMD module instantiated using the new keyword, then it will keep state throughout the page. (This may not be best practice but it's highly convenient)</p> +<p>This is a very light weight Session model which handles most situations. Read through the code and comments below. The model simply has a login, logout and check function. Again we have hooked into jQuery <code>ajaxPrefilter</code> to allow for csrf tokens and also telling jQuery to send cookies with the <code>withCredentials</code> property. The model relies heavily on it’s <code>auth</code> property. Throughout your application, each view can simply bind to <code>change:auth</code> on the Session model and react accordingly. Because we return this AMD module instantiated using the new keyword, then it will keep state throughout the page. (This may not be best practice but it’s highly convenient)</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// views/app.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// views/app.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span> @@ -711,17 +767,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">SessionModel</span><span class="p">();</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: This session model is missing one useful feature. If a user looses auth when navigating your application then the application should set {auth: false} on this model. To do this, in the <code>ajaxPrefilter</code> edit outgoing <code>success</code> functions to check if the server response was {auth: false} and then call the original <code>success()</code> function.</em></p> -<h2>Hooking up views to listen to changes in <code>auth</code></h2> +<h2 id="hooking-up-views-to-listen-to-changes-in-auth">Hooking up views to listen to changes in <code>auth</code></h2> -<p>Now that we have a Session model, let's hook up our <code>login/logout</code> view to listen to changes in <code>auth</code>. When creating the view we use <code>on</code> to bind a listener to the <code>auth</code> attribute of our model. Everytime it changes we will re-render the view which will conditionally load a template depending on the value of <code>Session.get('auth')</code>.</p> +<p>Now that we have a Session model, let’s hook up our <code>login/logout</code> view to listen to changes in <code>auth</code>. When creating the view we use <code>on</code> to bind a listener to the <code>auth</code> attribute of our model. Everytime it changes we will re-render the view which will conditionally load a template depending on the value of <code>Session.get('auth')</code>.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// models/session.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// models/session.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -768,15 +822,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">ExamplePage</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>.serializeObject</code> is not a native jQuery function and I have included it as <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/cross-domain/js/views/app.js">app.js</a> in the demo folder. <code>creds</code> can be an object of any variation of inputs, regardless it will be converted to JSON and posted to the server like any normal Backbone model.</em></p> <p>Here are the templates we are using for our login view</p> -<div class="highlight"><pre><code class="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">login</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">login</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">form</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;login&quot;</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nx">label</span> <span class="k">for</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="o">&gt;</span><span class="nx">Username</span><span class="o">&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&quot;username&quot;</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">required</span> <span class="nx">autofocus</span><span class="o">&gt;</span> @@ -785,60 +837,54 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">example</span><span class="o">/</span><span class="nx">logout</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;</span><span class="nx">Hello</span><span class="p">,</span> <span class="o">&lt;%=</span> <span class="nx">username</span> <span class="o">%&gt;</span><span class="p">.</span> <span class="nx">Time</span> <span class="nx">to</span> <span class="nx">logout</span><span class="o">?&lt;</span><span class="err">/p&gt;</span> -<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;logout&quot;</span><span class="o">&gt;</span><span class="nx">Logout</span><span class="o">&lt;</span><span class="err">/button&gt;</span> -</code></pre></div> - +<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;logout&quot;</span><span class="o">&gt;</span><span class="nx">Logout</span><span class="o">&lt;</span><span class="err">/button&gt;</span></code></pre></div> <p>This wraps up setting up the client, there are some notable points to make sure this technique works.</p> <ul> -<li>You must use <code>withCredentials</code> supplied by jQuery - session.js</li> -<li>You must send your request with csrf tokens for security - session.js</li> -<li>You should wrap your applications entry pointer (router in this example) in a check auth function - app.js</li> -<li>You must point your application at the right server - app.js</li> + <li>You must use <code>withCredentials</code> supplied by jQuery - session.js</li> + <li>You must send your request with csrf tokens for security - session.js</li> + <li>You should wrap your applications entry pointer (router in this example) in a check auth function - app.js</li> + <li>You must point your application at the right server - app.js</li> </ul> - -<h2>Building a compatible server</h2> +<h2 id="building-a-compatible-server">Building a compatible server</h2> <p>This tutorial uses node.js, express.js and a modified csrf.js library. An example server.js file exist in the <code>examples/cross-domain</code> folder. When inside the folder simply type <code>npm install -d</code> to install the dependencies and then <code>node server.js</code> to start the server. Again, make sure your <code>app.js</code> points at the correct server.</p> <p>The server has to do a few things;</p> <ul> -<li>Allow CORS request</li> -<li>Implement csrf protection</li> -<li>Allow jQuery to send credentials</li> -<li>Set a whitelist of allowed domains</li> -<li>Configure the correct response headers</li> + <li>Allow CORS request</li> + <li>Implement csrf protection</li> + <li>Allow jQuery to send credentials</li> + <li>Set a whitelist of allowed domains</li> + <li>Configure the correct response headers</li> </ul> - <p>To save you sometime here are some gotchas;</p> <ul> -<li>When sending <code>withCredentials</code> you must set correct response header <code>Access-Control-Allow-Credentials: true</code>. Also as a security policy browsers do not allow <code>Access-Control-Allow-Origin</code> to be set to <code>*</code>. So the origin of the request has to be known and trusted, so in the example below we use an of white listed domains.</li> -<li>jQuery ajax will trigger the browser to send these headers to enforce security <code>origin, x-requested-with, accept</code> so our server must allow them.</li> -<li>The browser might send out a <code>pre-flight</code> request to verify that it can talk to the server. The server must return <code>200 OK</code> on these <code>pre-flight</code> request.</li> + <li>When sending <code>withCredentials</code> you must set correct response header <code>Access-Control-Allow-Credentials: true</code>. Also as a security policy browsers do not allow <code>Access-Control-Allow-Origin</code> to be set to <code>*</code>. So the origin of the request has to be known and trusted, so in the example below we use an of white listed domains.</li> + <li>jQuery ajax will trigger the browser to send these headers to enforce security <code>origin, x-requested-with, accept</code> so our server must allow them.</li> + <li>The browser might send out a <code>pre-flight</code> request to verify that it can talk to the server. The server must return <code>200 OK</code> on these <code>pre-flight</code> request.</li> </ul> - <p>Be sure to read this Mozilla <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">documentation</a> on the above.</p> -<h2>Example node server</h2> +<h2 id="example-node-server">Example node server</h2> <p>This server below implements everything we have talked about so far. It should be relatively easy to see how would translate into other frameworks and languages. <code>app.configure</code> runs the specified libraries against every request. We have told the server that on each request it should check the csrf token and check if the origin domain is white-listed. If so we edit each request to contain the appropriate headers.</p> <p>This server has 3 endpoints, that are pseudo-restful;</p> <ul> -<li>POST /session - Login - Sets the session username and returns a csrf token for the user to use</li> -<li>DELETE /session - Logout - Destroys the session and regenerates a new csrf token if the user wants to re-login</li> -<li>GET /session - Checks Auth - Simply returns if auth is true or false, if true then also returns some session details</li> + <li>POST /session - Login - Sets the session username and returns a csrf token for the user to use</li> + <li>DELETE /session - Logout - Destroys the session and regenerates a new csrf token if the user wants to re-login</li> + <li>GET /session - Checks Auth - Simply returns if auth is true or false, if true then also returns some session details</li> </ul> - -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">connect</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;connect&#39;</span><span class="p">);</span> <span class="c1">// Custom csrf library</span> @@ -904,13 +950,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="p">});</span> -<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">8000</span><span class="p">);</span> -</code></pre></div> - +<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">8000</span><span class="p">);</span></code></pre></div> -<p><em>Note: I wrote a custom csrf module for this which can be found in the example directory. It's based of connects and uses the <code>crypto</code> library. I didn't spend much time on it but other traditional csrf modules won't work because they aren't exactly built for this implementation technique.</em></p> +<p><em>Note: I wrote a custom csrf module for this which can be found in the example directory. It’s based of connects and uses the <code>crypto</code> library. I didn’t spend much time on it but other traditional csrf modules won’t work because they aren’t exactly built for this implementation technique.</em></p> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>This approach really hammers in the need for a well documented and designed API. A powerful API will let you do application iterations with ease.</p> @@ -924,14 +968,13 @@ We should setup any useful containers that might be used by our Backbone views.& <p><a href="http://backbonetutorials.com/examples/cross-domain/">Example Demo</a></p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">cross-site xmlhttprequest with CORS</a></li> -<li><a href="http://www.w3.org/TR/cors/">Cross-Origin Resource Sharing</a></li> -<li><a href="http://www.kendoui.com/blogs/teamblog/posts/11-10-04/using_cors_with_all_modern_browsers.aspx">Using CORS with All (Modern) Browsers</a></li> + <li><a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">cross-site xmlhttprequest with CORS</a></li> + <li><a href="http://www.w3.org/TR/cors/">Cross-Origin Resource Sharing</a></li> + <li><a href="http://www.kendoui.com/blogs/teamblog/posts/11-10-04/using_cors_with_all_modern_browsers.aspx">Using CORS with All (Modern) Browsers</a></li> </ul> - </content> </entry> @@ -940,9 +983,9 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/infinite-scrolling?cachebust"/> <updated>2011-04-28T00:00:00+10:00</updated> <id>http://backbonetutorials.com/infinite-scrolling</id> - <content type="html"><h1>Lightweight Infinite Scrolling using Twitter API</h1> + <content type="html"><h1 id="lightweight-infinite-scrolling-using-twitter-api">Lightweight Infinite Scrolling using Twitter API</h1> -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>In this example we are going to build a widget that pulls in tweets and when the user scrolls to the bottom of the widget Backbone.js will re-sync with the server to bring down the next page of results.</p> @@ -952,15 +995,15 @@ We should setup any useful containers that might be used by our Backbone views.& <p><em>Note: This tutorial will use <a href="http://backbonetutorials.com/organizing-backbone-using-modules">AMD</a> for modularity.</em></p> -<h2>The Twitter Collection</h2> +<h2 id="the-twitter-collection">The Twitter Collection</h2> -<p>Twitter offers a jsonp API for browsing tweets. The first thing to note is that we have to append '&amp;callback?' to allow cross domain Ajax calls which is a feature of <a href="http://en.wikipedia.org/wiki/JSONP">jsonp</a>.</p> +<p>Twitter offers a jsonp API for browsing tweets. The first thing to note is that we have to append ‘&amp;callback?’ to allow cross domain Ajax calls which is a feature of <a href="http://en.wikipedia.org/wiki/JSONP">jsonp</a>.</p> -<p>Using the 'q' and 'page' query parameters we can find the results we are after. In the collection definition below we have set some defaults which can be overridden at any point.</p> +<p>Using the ‘q’ and ‘page’ query parameters we can find the results we are after. In the collection definition below we have set some defaults which can be overridden at any point.</p> -<p>Twitter's search API actually returns a whole bunch of meta information alongside the results. Though this is a problem for Backbone.js because a Collection expects to be populated with an array of objects. So in our collection definition we can override the Backbone.js default parse function to instead choose the correct property to populate the collection.</p> +<p>Twitter’s search API actually returns a whole bunch of meta information alongside the results. Though this is a problem for Backbone.js because a Collection expects to be populated with an array of objects. So in our collection definition we can override the Backbone.js default parse function to instead choose the correct property to populate the collection. </p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// collections/twitter.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// collections/twitter.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -980,24 +1023,20 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="k">return</span> <span class="nx">Tweets</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: Feel free to attach the meta information returned by Twitter to the collection itself e.g.</em></p> -<div class="highlight"><pre><code class="javascript"><span class="nx">parse</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">)</span> <span class="p">{</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">parse</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">completed_in</span> <span class="o">=</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">completed_in</span> <span class="k">return</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">results</span><span class="p">;</span> -<span class="p">},</span> -</code></pre></div> - +<span class="p">},</span></code></pre></div> -<h2>Setting up the View</h2> +<h2 id="setting-up-the-view">Setting up the View</h2> -<p>The first thing to do is to load our Twitter collection and template into the widget module. We should attach our collection to our view in our <code>initialize</code> function. <code>loadResults</code> will be responsible for calling fetch on our Twitter collection. On success we will append the latest results to our widget using our template. Our Backbone.js <code>events</code> will listen for <code>scroll</code> on the current <code>el</code> of the view which is '.twitter-widget'. If the current <code>scrollTop</code> is at the bottom then we simply increment the Twitter collections current page property and call <code>loadResults</code> again.</p> +<p>The first thing to do is to load our Twitter collection and template into the widget module. We should attach our collection to our view in our <code>initialize</code> function. <code>loadResults</code> will be responsible for calling fetch on our Twitter collection. On success we will append the latest results to our widget using our template. Our Backbone.js <code>events</code> will listen for <code>scroll</code> on the current <code>el</code> of the view which is ‘.twitter-widget’. If the current <code>scrollTop</code> is at the bottom then we simply increment the Twitter collections current page property and call <code>loadResults</code> again.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// views/twitter/widget.js</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// views/twitter/widget.js</span> <span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> @@ -1044,28 +1083,24 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">TwitterWidget</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>triggerPoint</code> will allow you to set an offset where the user has to scroll to before loading the next page</em></p> -<h2>The widget template</h2> +<h2 id="the-widget-template">The widget template</h2> -<p>Our view above passes into our underscore template the variable tweets which we can simply iterate over with using underscore's <code>each</code> method.</p> +<p>Our view above passes into our underscore template the variable tweets which we can simply iterate over with using underscore’s <code>each</code> method.</p> -<div class="highlight"><pre><code class="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">twitter</span><span class="o">/</span><span class="nx">list</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c">&lt;!--</span> <span class="nx">templates</span><span class="o">/</span><span class="nx">twitter</span><span class="o">/</span><span class="nx">list</span><span class="p">.</span><span class="nx">html</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">ul</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;tweets&quot;</span><span class="o">&gt;</span> <span class="o">&lt;%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">tweets</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">tweet</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span> <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;&lt;%=</span> <span class="nx">tweet</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;text&#39;</span><span class="p">)</span> <span class="o">%&gt;&lt;</span><span class="err">/li&gt; </span> <span class="o">&lt;%</span> <span class="p">});</span> <span class="o">%&gt;</span> -<span class="o">&lt;</span><span class="err">/ul&gt;</span> -</code></pre></div> +<span class="o">&lt;</span><span class="err">/ul&gt;</span></code></pre></div> - -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p>This is a very lightweight but robust infinite scroll example. There are caveats to using infinite scroll in UI/UX so make sure to only use it when applicable.</p> @@ -1080,91 +1115,85 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/nodejs-restify-mongodb-mongoose?cachebust"/> <updated>2011-04-22T00:00:00+10:00</updated> <id>http://backbonetutorials.com/nodejs-restify-mongodb-mongoose</id> - <content type="html"><h1>Simple example - Node.js, Restify, MongoDb and Mongoose</h1> + <content type="html"><h1 id="simple-example---nodejs-restify-mongodb-and-mongoose">Simple example - Node.js, Restify, MongoDb and Mongoose</h1> -<p>Before I start, the Backbone.js parts of this tutorial will be using techniques described in "Organizing your application using <a href="http://backbonetutorials.com/organizing-backbone-using-modules/">Modules</a> to construct a simple guestbook.</p> +<p>Before I start, the Backbone.js parts of this tutorial will be using techniques described in “Organizing your application using <a href="http://backbonetutorials.com/organizing-backbone-using-modules/">Modules</a> to construct a simple guestbook.</p> -<h2>Getting started</h2> +<h2 id="getting-started">Getting started</h2> <p>To easily understand this tutorial you should jump straight into the example code base.</p> <p><a href="https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify">Example Codebase</a></p> -<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/">Example Demo</a></p> +<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/app">Example Demo</a></p> <p>This tutorial will assist you in saving data(Backbone.js Models) to MongoDb and retrieving a list(Backbone.js Collections) of them back.</p> -<h2>The technologies</h2> +<h2 id="the-technologies">The technologies</h2> <p>This stack is great for rapid prototyping and highly intuitive. Personal note: I love using JavaScript as my only language for the entire application (FrontEnd/BackEnd/API/Database). Restify is still in early development but is essentially just an extension of Express. So for anyone needing more stability you can easily just substitute Express in.</p> -<h3>Node.js</h3> +<h3 id="nodejs">Node.js</h3> -<p>"Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices."</p> +<p>“Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.”</p> -<h3>Restify</h3> +<h3 id="restify">Restify</h3> -<p>"Restify is a node.js module built specifically to enable you to build correct REST web services. It borrows heavily from express (intentionally) as that is more or less the de facto API for writing web applications on top of node.js."</p> +<p>“Restify is a node.js module built specifically to enable you to build correct REST web services. It borrows heavily from express (intentionally) as that is more or less the de facto API for writing web applications on top of node.js.”</p> -<h3>MongoDb</h3> +<h3 id="mongodb">MongoDb</h3> -<p>"MongoDB (from "humongous") is a scalable, high-performance, open source NoSQL database."</p> +<p>“MongoDB (from “humongous”) is a scalable, high-performance, open source NoSQL database.”</p> -<h3>Mongoose</h3> +<h3 id="mongoose">Mongoose</h3> -<p>"Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment."</p> +<p>“Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.”</p> -<h2>Building the server</h2> +<h2 id="building-the-server">Building the server</h2> <p>In the example repository there is a server.js example which can be executed by running <code>node server.js</code>. If you use this example in your own applications make sure to update the Backbone.js <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/models/message.js">Model</a> and <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/collections/messages.js">Collection</a> definitions to match your server address.</p> -<h2>Restify configuration</h2> +<h2 id="restify-configuration">Restify configuration</h2> <p>The first thing to do is require the Restify module. Restify will be in control of handling our restful endpoints and returning the appropriate JSON.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">restify</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;restify&#39;</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">restify</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;restify&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">server</span> <span class="o">=</span> <span class="nx">restify</span><span class="p">.</span><span class="nx">createServer</span><span class="p">();</span> -<span class="nx">server</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">restify</span><span class="p">.</span><span class="nx">bodyParser</span><span class="p">());</span> -</code></pre></div> - +<span class="nx">server</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">restify</span><span class="p">.</span><span class="nx">bodyParser</span><span class="p">());</span></code></pre></div> <p>Note: bodyParser() takes care of turning your request data into a JavaScript object on the server automatically.</p> -<h2>MongoDb/Mongoose configuration</h2> +<h2 id="mongodbmongoose-configuration">MongoDb/Mongoose configuration</h2> <p>We simply want to require the MongoDb module and pass it a MongoDb authentication URI e.g. mongodb://username:server@mongoserver:10059/somecollection</p> <p>The code below presupposes you have another file in the same directory called <code>config.js</code>. Your config should never be public as it contains your credentials. So for this repository I have added <code>config.js</code> to my <code>.gitignore</code> but added in a <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/config-sample.js">sample config</a>.</p> -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">mongoose</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;mongoose/&#39;</span><span class="p">);</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">mongoose</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;mongoose/&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">config</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./config&#39;</span><span class="p">);</span> <span class="nx">db</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">creds</span><span class="p">.</span><span class="nx">mongoose_auth</span><span class="p">),</span> -<span class="nx">Schema</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">;</span> -</code></pre></div> - +<span class="nx">Schema</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">;</span></code></pre></div> -<h2>Mongoose Schema</h2> +<h2 id="mongoose-schema">Mongoose Schema</h2> <p>Mongoose introduces a concept of <a href="http://mongoosejs.com/docs/model-definition.html">model/schema</a> enforcing types which allow for easier input validation etc</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// Create a schema for our data</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Create a schema for our data</span> <span class="kd">var</span> <span class="nx">MessageSchema</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Schema</span><span class="p">({</span> <span class="nx">message</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span> <span class="nx">date</span><span class="o">:</span> <span class="nb">Date</span> <span class="p">});</span> <span class="c1">// Use the schema to register a model with MongoDb</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">&#39;Message&#39;</span><span class="p">,</span> <span class="nx">MessageSchema</span><span class="p">);</span> -<span class="kd">var</span> <span class="nx">Message</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">&#39;Message&#39;</span><span class="p">);</span> -</code></pre></div> - +<span class="kd">var</span> <span class="nx">Message</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">&#39;Message&#39;</span><span class="p">);</span></code></pre></div> <p><em>Note: <code>Message</code> can now be used for all things CRUD related.</em></p> -<h2>Setting up the routes</h2> +<h2 id="setting-up-the-routes">Setting up the routes</h2> <p>Just like in Backbone, Restify allows you to configure different routes and their associated callbacks. In the code below we define two routes. One for saving new messages and one for retrieving all messages. After we have created our function definitions, we attach them to either GET/POST/PUT/DELETE on a particular restful endpoint e.g. GET /messages</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// This function is responsible for returning all entries for the Message model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// This function is responsible for returning all entries for the Message model</span> <span class="kd">function</span> <span class="nx">getMessages</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Resitify currently has a bug which doesn&#39;t allow you to set default headers</span> <span class="c1">// This headers comply with CORS and allow us to server our response to any origin</span> @@ -1193,9 +1222,7 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="c1">// Set up our routes and start the server</span> <span class="nx">server</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/messages&#39;</span><span class="p">,</span> <span class="nx">getMessages</span><span class="p">);</span> -<span class="nx">server</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/messages&#39;</span><span class="p">,</span> <span class="nx">postMessage</span><span class="p">);</span> -</code></pre></div> - +<span class="nx">server</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/messages&#39;</span><span class="p">,</span> <span class="nx">postMessage</span><span class="p">);</span></code></pre></div> <p>This wraps up the server side of things, if you follow the <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/server.js">example</a> then you should see something like</p> @@ -1203,36 +1230,33 @@ We should setup any useful containers that might be used by our Backbone views.& <p><em>Note: Again you must remember to change the <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/models/message.js">Model</a> and <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/js/collections/messages.js">Collection</a> definitions to match your server address.</em></p> -<h2>Setting up the client (Backbone.js)</h2> +<h2 id="setting-up-the-client-backbonejs">Setting up the client (Backbone.js)</h2> -<p>I've actually used the latest copy of <a href="http://backboneboilerplate.com">http://backboneboilerplate.com</a> to set up the example page.</p> +<p>I’ve actually used the latest copy of <a href="http://backboneboilerplate.com">http://backboneboilerplate.com</a> to set up the example page.</p> <p>The important files you will want to check out are;</p> <ul> -<li>views/dashboard/page.js</li> -<li>views/guestbook/form.js</li> -<li>views/guestbook/list.js</li> -<li>models/message.js</li> -<li>collections/messages.js</li> -<li>templates/guestbook/</li> + <li>views/dashboard/page.js</li> + <li>views/guestbook/form.js</li> + <li>views/guestbook/list.js</li> + <li>models/message.js</li> + <li>collections/messages.js</li> + <li>templates/guestbook/</li> </ul> - -<h2>Saving a message</h2> +<h2 id="saving-a-message">Saving a message</h2> <p>First of all we want to setup a <a href="https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/nodejs-mongodb-mongoose-restify/templates/guestbook/form.html">template</a> for showing our form that creates new messages.</p> -<div class="highlight"><pre><code class="javascript"><span class="o">&lt;</span><span class="nx">textarea</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;message&quot;</span><span class="o">&gt;&lt;</span><span class="err">/textarea&gt;</span> -<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;post-message&quot;</span><span class="o">&gt;</span><span class="nx">Post</span> <span class="nx">Message</span><span class="o">&lt;</span><span class="err">/button&gt;</span> -</code></pre></div> - +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o">&lt;</span><span class="nx">textarea</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;message&quot;</span><span class="o">&gt;&lt;</span><span class="err">/textarea&gt;</span> +<span class="o">&lt;</span><span class="nx">button</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;post-message&quot;</span><span class="o">&gt;</span><span class="nx">Post</span> <span class="nx">Message</span><span class="o">&lt;</span><span class="err">/button&gt;</span></code></pre></div> <p>This template gets inserted into the DOM by <code>views/guestbook/form.js</code>, this Backbone view also handles the interaction of the form and the posting of the new data.</p> <p>Let us create a Backbone Model that has the correct URL for our restful interface.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span> <span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">)</span> <span class="p">{</span> @@ -1240,13 +1264,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;http://localhost:8080/messages&#39;</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">Message</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>We can see how we require our predefined model for messages and also our form template.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -1274,17 +1296,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">GuestbookForm</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p><em>Note: <code>trigger</code> is from Backbone Events, I binded a listener to this view in <code>views/dashboard/page.js</code> so when a new message is submitted, the list is re-rendered. We are setting the date of the POST on the server so there is no need to pass it up.</em></p> -<h2>Retrieving a list of messages</h2> +<h2 id="retrieving-a-list-of-messages">Retrieving a list of messages</h2> <p>We setup a route on our server to generate a list of all available messages at <code>GET /messages</code>. So we need to define a collection with the appropriate <code>url</code> to fetch this data down.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -1296,13 +1316,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="k">return</span> <span class="nx">Messages</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>Now that we have a collection to use we can setup our <code>views/list.js</code> to require the collection and trigger a fetch. Once the fetch is complete we want to render our returned data to a template and insert it into the DOM.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">define</span><span class="p">([</span> <span class="s1">&#39;jquery&#39;</span><span class="p">,</span> <span class="s1">&#39;underscore&#39;</span><span class="p">,</span> <span class="s1">&#39;backbone&#39;</span><span class="p">,</span> @@ -1322,30 +1340,26 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">}</span> <span class="p">});</span> <span class="k">return</span> <span class="nx">GuestbookList</span><span class="p">;</span> -<span class="p">});</span> -</code></pre></div> - +<span class="p">});</span></code></pre></div> <p>The template file should iterate over <code>messages.models</code> which is an array and print out a HTML fragment for each model.</p> -<div class="highlight"><pre><code class="javascript"><span class="o">&lt;%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o">&lt;%</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span> <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;&lt;%=</span> <span class="nx">message</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;message&#39;</span><span class="p">)</span> <span class="o">%&gt;&lt;</span><span class="err">/p&gt;</span> <span class="o">&lt;</span><span class="nx">em</span><span class="o">&gt;&lt;%=</span> <span class="nx">message</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;date&#39;</span><span class="p">)</span> <span class="o">%&gt;&lt;</span><span class="err">/em&gt;</span> -<span class="o">&lt;%</span> <span class="p">});</span> <span class="o">%&gt;</span> -</code></pre></div> - +<span class="o">&lt;%</span> <span class="p">});</span> <span class="o">%&gt;</span></code></pre></div> <p>This actually sums up everything you need to know to implement this simple example.</p> -<h2>Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <p><a href="https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify">Example Codebase</a></p> -<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/">Example Demo</a></p> +<p><a href="http://backbonetutorials.com/examples/nodejs-mongodb-mongoose-restify/app">Example Demo</a></p> -<p>In this example you should really be using relative URL's in your collections/models and instead setting a baseUrl in a config file or by placing your index.html file on the restful server.</p> +<p>In this example you should really be using relative URL’s in your collections/models and instead setting a baseUrl in a config file or by placing your index.html file on the restful server.</p> <p>This example is hosted on GitHub therefore we had to include the absolute URL to the server which is hosted on nodejitsu.com</p> @@ -1355,7 +1369,7 @@ We should setup any useful containers that might be used by our Backbone views.& <p>Get in touch with me on twitter, comments or GitHub!</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <p><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></p> </content> @@ -1366,37 +1380,35 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/why-would-you-use-backbone?cachebust"/> <updated>2011-02-01T00:00:00+10:00</updated> <id>http://backbonetutorials.com/why-would-you-use-backbone</id> - <content type="html"><h1>Why do you need Backbone.js?</h1> + <content type="html"><h1 id="why-do-you-need-backbonejs">Why do you need Backbone.js?</h1> <p>Building single-page web apps or complicated user interfaces will get extremely difficult by simply using <a href="http://jquery.com">jQuery</a> or <a href="http://mootools.net">MooTools</a>. The problem is standard JavaScript libraries are great at what they do - and without realizing it you can build an entire application without any formal structure. You will with ease turn your application into a nested pile of jQuery callbacks, all tied to concrete DOM elements.</p> -<p>I shouldn't need to explain why building something without any structure is a bad idea. Of course you can always invent your own way of structuring your application but you miss out on the benefits of the open source community.</p> +<p>I shouldn’t need to explain why building something without any structure is a bad idea. Of course you can always invent your own way of structuring your application but you miss out on the benefits of the open source community.</p> -<h2>Why single page applications are the future</h2> +<h2 id="why-single-page-applications-are-the-future">Why single page applications are the future</h2> <p>Backbone.js enforces that communication to the server should be done entirely through a RESTful API. The web is currently trending such that all data/content will be exposed through an API. This is because the browser is no longer the only client, we now have mobile devices, tablet devices, Google Goggles and electronic fridges etc.</p> -<h2>So how does Backbone.js help?</h2> +<h2 id="so-how-does-backbonejs-help">So how does Backbone.js help?</h2> <p>Backbone is an incredibly small library for the amount of functionality and structure it gives you. It is essentially MVC for the client and allows you to make your code modular. If you read through some of the beginner tutorials the benefits will soon become self evident and due to Backbone.js light nature you can incrementally include it in any current or future projects.</p> -<h2>Other frameworks</h2> +<h2 id="other-frameworks">Other frameworks</h2> <p>If you are looking for comparisons to build your single page application, try some of these resourceful links.</p> <ul> -<li><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">A feature comparison of different frontend frameworks</a></li> -<li><a href="http://addyosmani.github.com/todomvc/">Todo MVC - Todo list implemented in the many different types of frontend frameworks</a></li> + <li><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">A feature comparison of different frontend frameworks</a></li> + <li><a href="http://addyosmani.github.com/todomvc/">Todo MVC - Todo list implemented in the many different types of frontend frameworks</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/FND">FND</a></li> + <li><a href="https://github.com/FND">FND</a></li> </ul> - <p><strong>If you questions regarding why you should choose Backbone.js as your framework, please leave a comment below</strong></p> </content> </entry> @@ -1406,31 +1418,31 @@ We should setup any useful containers that might be used by our Backbone views.& <link href="http://backbonetutorials.com/what-is-a-model?cachebust"/> <updated>2011-01-29T00:00:00+10:00</updated> <id>http://backbonetutorials.com/what-is-a-model</id> - <content type="html"><h1>What is a model?</h1> + <content type="html"><h1 id="what-is-a-model">What is a model?</h1> -<p>Across the internet the definition of <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> is so diluted that it's hard to tell what exactly your model should be doing. The authors of backbone.js have quite a clear definition of what they believe the model represents in backbone.js.</p> +<p>Across the internet the definition of <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> is so diluted that it’s hard to tell what exactly your model should be doing. The authors of backbone.js have quite a clear definition of what they believe the model represents in backbone.js.</p> -<blockquote><p>Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.</p></blockquote> +<blockquote> + <p>Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.</p> +</blockquote> -<p>So for the purpose of the tutorial let's create a model.</p> +<p>So for the purpose of the tutorial let’s create a model.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Welcome to this world&quot;</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span> -</code></pre></div> - + <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span></code></pre></div> -<p>So <em>initialize()</em> is triggered whenever you create a new instance of a model( models, collections and views work the same way ). You don't have to include it in your model declaration but you will find yourself using it more often than not.</p> +<p>So <em>initialize()</em> is triggered whenever you create a new instance of a model( models, collections and views work the same way ). You don’t have to include it in your model declaration but you will find yourself using it more often than not.</p> -<h2>Setting attributes</h2> +<h2 id="setting-attributes">Setting attributes</h2> <p>Now we want to pass some parameters when we create an instance of our model.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Welcome to this world&quot;</span><span class="p">);</span> <span class="p">}</span> @@ -1439,18 +1451,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> <span class="c1">// or we can set afterwards, these operations are equivelent</span> <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">();</span> - <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> - -</code></pre></div> - + <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span></code></pre></div> -<p>So passing a JavaScript object to our constructor is the same as calling <em>model.set()</em>. Now that these models have attributes set we need to be able to retrieve them.</p> +<p>So passing a JavaScript object to our constructor is the same as calling <em>model.set()</em>. Now that these models have attributes set we need to be able to retrieve them. </p> -<h2>Getting attributes</h2> +<h2 id="getting-attributes">Getting attributes</h2> <p>Using the <em>model.get()</em> method we can access model properties at anytime.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Welcome to this world&quot;</span><span class="p">);</span> <span class="p">}</span> @@ -1460,16 +1469,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">age</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;age&quot;</span><span class="p">);</span> <span class="c1">// 67</span> <span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">);</span> <span class="c1">// &quot;Thomas&quot;</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span> - -</code></pre></div> - + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span></code></pre></div> -<h2>Setting model defaults</h2> +<h2 id="setting-model-defaults">Setting model defaults</h2> -<p>Sometimes you will want your model to contain default values. This can easily be accomplished by setting a property name 'defaults' in your model declaration.</p> +<p>Sometimes you will want your model to contain default values. This can easily be accomplished by setting a property name ‘defaults’ in your model declaration.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Fetus&#39;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> @@ -1484,16 +1490,13 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">age</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;age&quot;</span><span class="p">);</span> <span class="c1">// 67</span> <span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">);</span> <span class="c1">// &quot;Thomas&quot;</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span> - -</code></pre></div> - + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;Ryan&#39;</span></code></pre></div> -<h2>Manipulating model attributes</h2> +<h2 id="manipulating-model-attributes">Manipulating model attributes</h2> <p>Models can contain as many custom methods as you like to manipulate attributes. By default all methods are public.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Fetus&#39;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> @@ -1509,18 +1512,15 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">,</span> <span class="nx">child</span><span class="o">:</span> <span class="s1">&#39;Ryan&#39;</span><span class="p">});</span> <span class="nx">person</span><span class="p">.</span><span class="nx">adopt</span><span class="p">(</span><span class="s1">&#39;John Resig&#39;</span><span class="p">);</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;John Resig&#39;</span> - -</code></pre></div> - + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;child&quot;</span><span class="p">);</span> <span class="c1">// &#39;John Resig&#39;</span></code></pre></div> -<p>So we can implement methods to get/set and perform other calculations using attributes from our model at any time.</p> +<p>So we can implement methods to get/set and perform other calculations using attributes from our model at any time. </p> -<h2>Listening for changes to the model</h2> +<h2 id="listening-for-changes-to-the-model">Listening for changes to the model</h2> -<p>Now onto one of the more useful parts of using a library such as backbone. All attributes of a model can have listeners bound to them to detect changes to their values. In our initialize function we are going to bind a function call everytime we change the value of our attribute. In this case if the name of our "person" changes we will alert their new name.</p> +<p>Now onto one of the more useful parts of using a library such as backbone. All attributes of a model can have listeners bound to them to detect changes to their values. In our initialize function we are going to bind a function call everytime we change the value of our attribute. In this case if the name of our “person” changes we will alert their new name.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Fetus&#39;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span> @@ -1535,13 +1535,11 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="p">});</span> <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> - <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Stewie Griffin&#39;</span><span class="p">});</span> <span class="c1">// This triggers a change and will alert()</span> -</code></pre></div> + <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Stewie Griffin&#39;</span><span class="p">});</span> <span class="c1">// This triggers a change and will alert()</span></code></pre></div> +<p>So we can bind the change listener to individual attributes or if we like simply ‘<em>this.on(“change”, function(model){});</em>’ to listen for changes to all attributes of the model.</p> -<p>So we can bind the change listener to individual attributes or if we like simply '<em>this.on("change", function(model){});</em>' to listen for changes to all attributes of the model.</p> - -<h2>Interacting with the server</h2> +<h2 id="interacting-with-the-server">Interacting with the server</h2> <p>Models are used to represent data from your server and actions you perform on them will be translated to RESTful operations.</p> @@ -1553,22 +1551,20 @@ We should setup any useful containers that might be used by our Backbone views.& <p>Our model definition shall thus look like;</p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">urlRoot</span><span class="o">:</span> <span class="s1">&#39;/user&#39;</span><span class="p">,</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s1">&#39;&#39;</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Creating a new model</h3> +<h3 id="creating-a-new-model">Creating a new model</h3> -<p>If we wish to create a new user on the server then we will instantiate a new UserModel and call <code>save</code>. If the <code>id</code> attribute of the model is <code>null</code>, Backbone.js will send a POST request to the urlRoot of the server.</p> +<p>If we wish to create a new user on the server then we will instantiate a new UserModel and call <code>save</code>. If the <code>id</code> attribute of the model is <code>null</code>, Backbone.js will send a POST request to the urlRoot of the server. </p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">urlRoot</span><span class="o">:</span> <span class="s1">&#39;/user&#39;</span><span class="p">,</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> @@ -1588,21 +1584,19 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">})</span> -</code></pre></div> - + <span class="p">})</span></code></pre></div> <p>Our table should now have the values</p> -<p>1, 'Thomas', 'thomasalwyndavis@gmail.com'</p> +<p>1, ‘Thomas’, ‘thomasalwyndavis@gmail.com’</p> -<h3>Getting a model</h3> +<h3 id="getting-a-model">Getting a model</h3> <p>Now that we have saved a new user model, we can retrieve it from the server. We know that the <code>id</code> is 1 from the above example.</p> -<p>If we instantiate a model with an <code>id</code>, Backbone.js will automatically perform a get request to the urlRoot + '/id' (conforming to RESTful conventions)</p> +<p>If we instantiate a model with an <code>id</code>, Backbone.js will automatically perform a get request to the urlRoot + ‘/id’ (conforming to RESTful conventions)</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span><span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">});</span> <span class="c1">// The fetch below will perform GET /user/1</span> @@ -1611,16 +1605,14 @@ We should setup any useful containers that might be used by our Backbone views.& <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">})</span> -</code></pre></div> - + <span class="p">})</span></code></pre></div> -<h3>Updating a model</h3> +<h3 id="updating-a-model">Updating a model</h3> <p>Now that we have a model that exist on the server we can perform an update using a PUT request. We will use the <code>save</code> api call which is intelligent and will send a PUT request instead of a POST request if an <code>id</code> is present(conforming to RESTful conventions)</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Thomas&#39;</span><span class="p">,</span> @@ -1634,15 +1626,13 @@ We will use the <code>save</code> api call which is intelligent and <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Deleting a model</h3> +<h3 id="deleting-a-model">Deleting a model</h3> <p>When a model has an <code>id</code> we know that it exist on the server, so if we wish to remove it from the server we can call <code>destroy</code>. <code>destroy</code> will fire off a DELETE /user/id (conforming to RESTful conventions).</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Thomas&#39;</span><span class="p">,</span> @@ -1655,27 +1645,22 @@ We will use the <code>save</code> api call which is intelligent and <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;Destroyed&#39;</span><span class="p">);</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Tips and Tricks</h3> +<h3 id="tips-and-tricks">Tips and Tricks</h3> <p><em>Get all the current attributes</em></p> -<div class="highlight"><pre><code class="javascript"> - <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Thomas&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> <span class="kd">var</span> <span class="nx">attributes</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">();</span> <span class="c1">// { name: &quot;Thomas&quot;, age: 67}</span> <span class="cm">/* This simply returns a copy of the current attributes. */</span> <span class="kd">var</span> <span class="nx">attributes</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">attributes</span><span class="p">;</span> - <span class="cm">/* The line above gives a direct reference to the attributes and you should be careful when playing with it. Best practise would suggest that you use .set() to edit attributes of a model to take advantage of backbone listeners. */</span> -</code></pre></div> - + <span class="cm">/* The line above gives a direct reference to the attributes and you should be careful when playing with it. Best practise would suggest that you use .set() to edit attributes of a model to take advantage of backbone listeners. */</span></code></pre></div> <p><em>Validate data before you set or save it</em></p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="c1">// If you return a string from the validate function,</span> <span class="c1">// Backbone will throw an error</span> <span class="nx">validate</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">attributes</span> <span class="p">){</span> @@ -1698,17 +1683,13 @@ We will use the <code>save</code> api call which is intelligent and <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span> <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Dr Manhatten&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">});</span> - <span class="c1">// God have mercy on our souls</span> - -</code></pre></div> - + <span class="c1">// God have mercy on our souls</span></code></pre></div> -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/utkarshkukreti">Utkarsh Kukreti</a></li> + <li><a href="https://github.com/utkarshkukreti">Utkarsh Kukreti</a></li> </ul> - </content> </entry> @@ -1717,15 +1698,15 @@ We will use the <code>save</code> api call which is intelligent and <link href="http://backbonetutorials.com/what-is-a-view?cachebust"/> <updated>2011-01-28T00:00:00+10:00</updated> <id>http://backbonetutorials.com/what-is-a-view</id> - <content type="html"><h1>What is a view?</h1> + <content type="html"><h1 id="what-is-a-view">What is a view?</h1> -<p>Backbone views are used to reflect what your applications' data models look like. They are also used to listen to events and react accordingly. This tutorial will not be addressing how to bind models and collections to views but will focus on view functionality and how to use views with a JavaScript templating library, specifically <a href="http://documentcloud.github.com/underscore/#template">Underscore.js's _.template</a>.</p> +<p>Backbone views are used to reflect what your applications’ data models look like. They are also used to listen to events and react accordingly. This tutorial will not be addressing how to bind models and collections to views but will focus on view functionality and how to use views with a JavaScript templating library, specifically <a href="http://documentcloud.github.com/underscore/#template">Underscore.js’s _.template</a>.</p> -<p>We will be using <a href="http://jquery.com/">jQuery 1.8.2</a> as our DOM manipulator. It's possible to use other libraries such as <a href="http://mootools.net/">MooTools</a> or <a href="http://sizzlejs.com/">Sizzle</a>, but official Backbone.js documentation endorses jQuery. Backbone.View events may not work with other libraries other than jQuery.</p> +<p>We will be using <a href="http://jquery.com/">jQuery 1.8.2</a> as our DOM manipulator. It’s possible to use other libraries such as <a href="http://mootools.net/">MooTools</a> or <a href="http://sizzlejs.com/">Sizzle</a>, but official Backbone.js documentation endorses jQuery. Backbone.View events may not work with other libraries other than jQuery.</p> <p>For the purposes of this demonstration, we will be implementing a search box. <a href="http://jsfiddle.net/tBS4X/1/">A live example</a> can be found on jsFiddle.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Alerts suck.&quot;</span><span class="p">);</span> <span class="p">}</span> @@ -1733,39 +1714,35 @@ We will use the <code>save</code> api call which is intelligent and <span class="c1">// The initialize function is always called when instantiating a Backbone View.</span> <span class="c1">// Consider it the constructor of the class.</span> - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">();</span> -</code></pre></div> - + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">();</span></code></pre></div> -<h2>The "el" property</h2> +<h2 id="the-el-property">The “el” property</h2> -<p>The "el" property references the DOM object created in the browser. Every Backbone.js view has an "el" property, and if it not defined, Backbone.js will construct its own, which is an empty div element.</p> +<p>The “el” property references the DOM object created in the browser. Every Backbone.js view has an “el” property, and if it not defined, Backbone.js will construct its own, which is an empty div element.</p> -<p>Let us set our view's "el" property to div#search_container, effectively making Backbone.View the owner of the DOM element.</p> +<p>Let us set our view’s “el” property to div#search_container, effectively making Backbone.View the owner of the DOM element.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Alerts suck.&quot;</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Alerts suck.&quot;</span><span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><em>Note: Keep in mind that this binds the container element. Any events we trigger must be in this element.</em></p> -<h2>Loading a template</h2> +<h2 id="loading-a-template">Loading a template</h2> -<p>Backbone.js is dependent on Underscore.js, which includes its own micro-templating solution. Refer to <a href="http://documentcloud.github.com/underscore/">Underscore.js's documentation</a> for more information.</p> +<p>Backbone.js is dependent on Underscore.js, which includes its own micro-templating solution. Refer to <a href="http://documentcloud.github.com/underscore/">Underscore.js’s documentation</a> for more information.</p> -<p>Let us implement a "render()" function and call it when the view is initialized. The "render()" function will load our template into the view's "el" property using jQuery.</p> +<p>Let us implement a “render()” function and call it when the view is initialized. The “render()” function will load our template into the view’s “el” property using jQuery.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> <span class="o">&lt;</span><span class="nx">label</span><span class="o">&gt;</span><span class="nx">Search</span><span class="o">&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_input&quot;</span> <span class="o">/&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;button&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_button&quot;</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&quot;Search&quot;</span> <span class="o">/&gt;</span> @@ -1774,30 +1751,28 @@ We will use the <code>save</code> api call which is intelligent and <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> - <span class="p">},</span> - <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="c1">// Compile the template using underscore</span> - <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="p">{}</span> <span class="p">);</span> - <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> - <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> + <span class="p">},</span> + <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="c1">// Compile the template using underscore</span> + <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="p">{}</span> <span class="p">);</span> + <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> + <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><em>Tip: Place all your templates in a file and serve them from a CDN. This ensures your users will always have your application cached.</em></p> -<h2>Listening for events</h2> +<h2 id="listening-for-events">Listening for events</h2> -<p>To attach a listener to our view, we use the "events" attribute of Backbone.View. Remember that event listeners can only be attached to child elements of the "el" property. Let us attach a "click" listener to our button.</p> +<p>To attach a listener to our view, we use the “events” attribute of Backbone.View. Remember that event listeners can only be attached to child elements of the “el” property. Let us attach a “click” listener to our button.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> <span class="o">&lt;</span><span class="nx">label</span><span class="o">&gt;</span><span class="nx">Search</span><span class="o">&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_input&quot;</span> <span class="o">/&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;button&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_button&quot;</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&quot;Search&quot;</span> <span class="o">/&gt;</span> @@ -1824,15 +1799,13 @@ We will use the <code>save</code> api call which is intelligent and <span class="p">});</span> <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> +<span class="nt">&lt;/script&gt;</span></code></pre></div> - -<h2>Tips and Tricks</h2> +<h2 id="tips-and-tricks">Tips and Tricks</h2> <p><em>Using template variables</em></p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;search_template&quot;</span><span class="nt">&gt;</span> <span class="c">&lt;!--</span> <span class="nx">Access</span> <span class="nx">template</span> <span class="nx">variables</span> <span class="kd">with</span> <span class="o">&lt;%=</span> <span class="o">%&gt;</span> <span class="o">--&gt;</span> <span class="o">&lt;</span><span class="nx">label</span><span class="o">&gt;&lt;%=</span> <span class="nx">search_label</span> <span class="o">%&gt;&lt;</span><span class="err">/label&gt;</span> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;search_input&quot;</span> <span class="o">/&gt;</span> @@ -1842,48 +1815,44 @@ We will use the <code>save</code> api call which is intelligent and <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;search_container&quot;</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> - <span class="p">},</span> - <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="c1">//Pass variables in using Underscore.js Template</span> - <span class="kd">var</span> <span class="nx">variables</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">search_label</span><span class="o">:</span> <span class="s2">&quot;My Search&quot;</span> <span class="p">};</span> - <span class="c1">// Compile the template using underscore</span> - <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="nx">variables</span> <span class="p">);</span> - <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> - <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> - <span class="p">},</span> - <span class="nx">events</span><span class="o">:</span> <span class="p">{</span> - <span class="s2">&quot;click input[type=button]&quot;</span><span class="o">:</span> <span class="s2">&quot;doSearch&quot;</span> - <span class="p">},</span> - <span class="nx">doSearch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">event</span> <span class="p">){</span> - <span class="c1">// Button clicked, you can access the element that was clicked with event.currentTarget</span> - <span class="nx">alert</span><span class="p">(</span> <span class="s2">&quot;Search for &quot;</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_input&quot;</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - - -<h3>Relevant Links</h3> + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> + <span class="p">},</span> + <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="c1">//Pass variables in using Underscore.js Template</span> + <span class="kd">var</span> <span class="nx">variables</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">search_label</span><span class="o">:</span> <span class="s2">&quot;My Search&quot;</span> <span class="p">};</span> + <span class="c1">// Compile the template using underscore</span> + <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_template&quot;</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="nx">variables</span> <span class="p">);</span> + <span class="c1">// Load the compiled HTML into the Backbone &quot;el&quot;</span> + <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> + <span class="p">},</span> + <span class="nx">events</span><span class="o">:</span> <span class="p">{</span> + <span class="s2">&quot;click input[type=button]&quot;</span><span class="o">:</span> <span class="s2">&quot;doSearch&quot;</span> + <span class="p">},</span> + <span class="nx">doSearch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">event</span> <span class="p">){</span> + <span class="c1">// Button clicked, you can access the element that was clicked with event.currentTarget</span> + <span class="nx">alert</span><span class="p">(</span> <span class="s2">&quot;Search for &quot;</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_input&quot;</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search_container&quot;</span><span class="p">)</span> <span class="p">});</span> +<span class="nt">&lt;/script&gt;</span></code></pre></div> + +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://thomasdavis.github.com/2011/02/05/backbone-views-and-templates.html">This example implemented with google API</a></li> -<li><a href="http://jsfiddle.net/thomas/C9wew/4/">This examples exact code on jsfiddle.net</a></li> -<li><a href="http://jsfiddle.net/thomas/dKK9Y/6/">Another semi-complete example on jsFiddle</a></li> + <li><a href="http://thomasdavis.github.com/2011/02/05/backbone-views-and-templates.html">This example implemented with google API</a></li> + <li><a href="http://jsfiddle.net/thomas/C9wew/4/">This examples exact code on jsfiddle.net</a></li> + <li><a href="http://jsfiddle.net/thomas/dKK9Y/6/">Another semi-complete example on jsFiddle</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/zaeleus">Michael Macias</a></li> -<li><a href="https://github.com/lawnday">Alex Lande</a></li> + <li><a href="https://github.com/zaeleus">Michael Macias</a></li> + <li><a href="https://github.com/lawnday">Alex Lande</a></li> </ul> - </content> </entry> @@ -1892,15 +1861,15 @@ We will use the <code>save</code> api call which is intelligent and <link href="http://backbonetutorials.com/what-is-a-router?cachebust"/> <updated>2011-01-27T00:00:00+10:00</updated> <id>http://backbonetutorials.com/what-is-a-router</id> - <content type="html"><h1>What is a router?</h1> + <content type="html"><h1 id="what-is-a-router">What is a router?</h1> -<p>Backbone routers are used for routing your applications URL's when using hash tags(#). In the traditional MVC sense they don't necessarily fit the semantics and if you have read "<a href="http://backbonetutorials.com/what-is-a-view">What is a view?</a>" it will elaborate on this point. Though a Backbone "router" is still very useful for any application/feature that needs URL routing/history capabilities.</p> +<p>Backbone routers are used for routing your applications URL’s when using hash tags(#). In the traditional MVC sense they don’t necessarily fit the semantics and if you have read “<a href="http://backbonetutorials.com/what-is-a-view">What is a view?</a>” it will elaborate on this point. Though a Backbone “router” is still very useful for any application/feature that needs URL routing/history capabilities. </p> <p>Defined routers should always contain at least one route and a function to map the particular route to. In the example below we are going to define a route that is always called.</p> -<p>Also note that routes interpret anything after "#" tag in the URL. All links in your application should target "#/action" or "#action". (Appending a forward slash after the hashtag looks a bit nicer e.g. http://example.com/#/user/help)</p> +<p>Also note that routes interpret anything after “#” tag in the URL. All links in your application should target “#/action” or “#action”. (Appending a forward slash after the hashtag looks a bit nicer e.g. http://example.com/#/user/help)</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script&gt;</span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;*actions&quot;</span><span class="o">:</span> <span class="s2">&quot;defaultRoute&quot;</span> <span class="c1">// matches http://example.com/#anything-here</span> @@ -1916,9 +1885,7 @@ We will use the <code>save</code> api call which is intelligent and <span class="c1">// Start Backbone history a necessary step for bookmarkable URL&#39;s</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><a href="#action">Activate route</a></p> @@ -1926,11 +1893,11 @@ We will use the <code>save</code> api call which is intelligent and <p><em>Notice the change in the url</em></p> -<h2>Dynamic Routing</h2> +<h2 id="dynamic-routing">Dynamic Routing</h2> -<p>Most conventional frameworks allow you to define routes that contain a mix of static and dynamic route parameters. For example you might want to retrieve a post with a variable id with a friendly URL string. Such that your URL would look like "http://example.com/#/posts/12". Once this route was activated you would want to access the id given in the URL string. This example is implemented below.</p> +<p>Most conventional frameworks allow you to define routes that contain a mix of static and dynamic route parameters. For example you might want to retrieve a post with a variable id with a friendly URL string. Such that your URL would look like “http://example.com/#/posts/12”. Once this route was activated you would want to access the id given in the URL string. This example is implemented below.</p> -<div class="highlight"><pre><code class="html"><span class="nt">&lt;script&gt;</span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script&gt;</span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;posts/:id&quot;</span><span class="o">:</span> <span class="s2">&quot;getPost&quot;</span><span class="p">,</span> @@ -1949,9 +1916,7 @@ We will use the <code>save</code> api call which is intelligent and <span class="c1">// Start Backbone history a necessary step for bookmarkable URL&#39;s</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> -<span class="nt">&lt;/script&gt;</span> -</code></pre></div> - +<span class="nt">&lt;/script&gt;</span></code></pre></div> <p><a href="#/posts/120">Post 120</a></p> @@ -1959,15 +1924,15 @@ We will use the <code>save</code> api call which is intelligent and <p><em>Notice the change in the url</em></p> -<h2>Dynamic Routing Cont. ":params" and "*splats"</h2> +<h2 id="dynamic-routing-cont-params-and-splats">Dynamic Routing Cont. “:params” and “*splats”</h2> -<p>Backbone uses two styles of variables when implementing routes. First there are ":params" which match any URL components between slashes. Then there are "<em>splats" which match any number of URL components. Note that due to the nature of a "</em>splat" it will always be the last variable in your URL as it will match any and all components.</p> +<p>Backbone uses two styles of variables when implementing routes. First there are “:params” which match any URL components between slashes. Then there are “<em>splats” which match any number of URL components. Note that due to the nature of a “</em>splat” it will always be the last variable in your URL as it will match any and all components.</p> -<p>Any "*splats" or ":params" in route definitions are passed as arguments (in respective order) to the associated function. A route defined as "/:route/:action" will pass 2 variables (“route” and “action”) to the callback function. (If this is confusing please post a comment and I will try articulate it better)</p> +<p>Any “*splats” or “:params” in route definitions are passed as arguments (in respective order) to the associated function. A route defined as “/:route/:action” will pass 2 variables (“route” and “action”) to the callback function. (If this is confusing please post a comment and I will try articulate it better)</p> -<p>Here are some examples of using ":params" and "*splats"</p> +<p>Here are some examples of using “:params” and “*splats”</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;posts/:id&quot;</span><span class="o">:</span> <span class="s2">&quot;getPost&quot;</span><span class="p">,</span> <span class="c1">// &lt;a href=&quot;http://example.com/#/posts/121&quot;&gt;Example&lt;/a&gt;</span> @@ -1988,99 +1953,24 @@ We will use the <code>save</code> api call which is intelligent and <span class="p">});</span> <span class="nx">app_router</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;route:loadView&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">route</span><span class="p">,</span> <span class="nx">action</span> <span class="p">){</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">route</span> <span class="o">+</span> <span class="s2">&quot;_&quot;</span> <span class="o">+</span> <span class="nx">action</span><span class="p">);</span> <span class="c1">// dashboard_graph </span> - <span class="p">});</span> -</code></pre></div> + <span class="p">});</span></code></pre></div> - -<p>Routes are quite powerful and in an ideal world your application should never contain too many. If you need to implement hash tags with SEO in mind, do a google search for "google seo hashbangs". Also check out <a href="http://seo.apiengine.io">Seo Server</a></p> +<p>Routes are quite powerful and in an ideal world your application should never contain too many. If you need to implement hash tags with SEO in mind, do a google search for “google seo hashbangs”. Also check out <a href="http://seo.apiengine.io">Seo Server</a></p> <p>Remember to do a pull request for any errors you come across.</p> -<h3>Relevant Links</h3> - +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://documentcloud.github.com/backbone/#Router">Backbone.js official router documentation</a></li> -<li><a href="http://thomasdavis.github.com/2011/02/07/making-a-restful-ajax-app.html">Using routes and understanding the hash tag</a></li> + <li><a href="http://documentcloud.github.com/backbone/#Router">Backbone.js official router documentation</a></li> + <li><a href="http://thomasdavis.github.com/2011/02/07/making-a-restful-ajax-app.html">Using routes and understanding the hash tag</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="http://schistad.info">Herman Schistad</a> - (Backbone 0.5 rename from Controller to Router)</li> -<li><a href="http://paulirish.com">Paul Irish</a></li> + <li><a href="http://schistad.info">Herman Schistad</a> - (Backbone 0.5 rename from Controller to Router)</li> + <li><a href="http://paulirish.com">Paul Irish</a></li> </ul> - -</content> - </entry> - - <entry> - <title>What is a collection?</title> - <link href="http://backbonetutorials.com/what-is-a-collection?cachebust"/> - <updated>2011-01-26T00:00:00+10:00</updated> - <id>http://backbonetutorials.com/what-is-a-collection</id> - <content type="html"><h1>What is a collection?</h1> - -<p>Backbone collections are simply an ordered set of <a href="/what-is-a-model">models</a>. Such that it can be used in situations such as;</p> - -<ul> -<li>Model: Student, Collection: ClassStudents</li> -<li>Model: Todo Item, Collection: Todo List</li> -<li>Model: Animal, Collection: Zoo</li> -</ul> - - -<p>Typically your collection will only use one type of model but models themselves are not limited to a type of collection;</p> - -<ul> -<li>Model: Student, Collection: Gym Class</li> -<li>Model: Student, Collection: Art Class</li> -<li>Model: Student, Collection: English Class</li> -</ul> - - -<p>Here is a generic Model/Collection example.</p> - -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Music is the answer&quot;</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">Album</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> - <span class="p">});</span> -</code></pre></div> - - -<h2>Building a collection</h2> - -<p>Now we are going to populate a collection with some useful data.</p> - -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> - <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Not specified&quot;</span><span class="p">,</span> - <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;Not specified&quot;</span> - <span class="p">},</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Music is the answer&quot;</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">Album</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">song1</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;How Bizarre&quot;</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;OMC&quot;</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">song2</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Sexual Healing&quot;</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;Marvin Gaye&quot;</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">song3</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Talk It Over In Bed&quot;</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">&quot;OMC&quot;</span> <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">myAlbum</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Album</span><span class="p">([</span> <span class="nx">song1</span><span class="p">,</span> <span class="nx">song2</span><span class="p">,</span> <span class="nx">song3</span><span class="p">]);</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">myAlbum</span><span class="p">.</span><span class="nx">models</span> <span class="p">);</span> <span class="c1">// [song1, song2, song3]</span> -</code></pre></div> - - - </content> </entry> diff --git a/_site/seo-for-single-page-apps/index.html b/_site/seo-for-single-page-apps/index.html index 30b9b45..fee2935 100644 --- a/_site/seo-for-single-page-apps/index.html +++ b/_site/seo-for-single-page-apps/index.html @@ -5,71 +5,54 @@ <title>SEO for single page applications - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,74 +81,72 @@ <div id="post"> -<h1>SEO for single page apps</h1> +<h1 id="seo-for-single-page-apps">SEO for single page apps</h1> -<p>This tutorial will show you how to index your application on search engines. As the author I believe that servers should be completely independent of the client in the age of API's. Which speeds up development for the ever increasing array of clients. It is on the shoulders of the search engines to conform and they should not dictate how the web is stored and accessed.</p> +<p>This tutorial will show you how to index your application on search engines. As the author I believe that servers should be completely independent of the client in the age of API’s. Which speeds up development for the ever increasing array of clients. It is on the shoulders of the search engines to conform and they should not dictate how the web is stored and accessed.</p> -<p>In 2009 Google released the idea of <a href="http://googlewebmastercentral.blogspot.com.au/2009/10/proposal-for-making-ajax-crawlable.html">escaped fragments</a>.</p> +<p>In 2009 Google released the idea of <a href="http://googlewebmastercentral.blogspot.com.au/2009/10/proposal-for-making-ajax-crawlable.html">escaped fragments</a>. </p> <p>The idea simply stating that if a search engine should come across your JavaScript application then you have the permission to redirect the search engine to another URL that serves the fully rendered version of the page (The current search engines cannot execute much JavaScript (Some people speculate that Google Chrome was born of Google Search wishing to successfully render every web page to retrieve ajaxed content)).</p> -<h2>How does redirecting bots work?</h2> +<h2 id="how-does-redirecting-bots-work">How does redirecting bots work?</h2> <p>Using modern headless browsers, we can easily return the fully rendered content per request by redirecting bots using our web servers configuration. Here is an image made by Google depicting the setup.</p> <p><img src="http://acris.googlecode.com/svn/wiki/images/seo_google_crawlability.png" alt="headless seo" /></p> -<div style='clear: both;'></div> - +<div style="clear: both;"></div> -<h2>Implementation using Phantom.js</h2> +<h2 id="implementation-using-phantomjs">Implementation using Phantom.js</h2> <p><a href="http://phantomjs.org/">Phantom.js</a> is a headless webkit browser. We are going to setup a node.js server that given a URL, it will fully render the page content. Then we will redirect bots to this server to retrieve the correct content.</p> <p>You will need to install node.js and phantom.js onto a box. Then start up this server below. There are two files, one which is the web server and the other is a phantomjs script that renders the page.</p> -<div class="highlight"><pre><code class="javascript"><span class="c1">// web.js</span> - -<span class="c1">// Express is our web server that can handle request</span> -<span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'express'</span><span class="p">);</span> -<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span> - - -<span class="kd">var</span> <span class="nx">getContent</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span> - <span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span> - <span class="c1">// Here we spawn a phantom.js process, the first element of the </span> - <span class="c1">// array is our phantomjs script and the second element is our url </span> - <span class="kd">var</span> <span class="nx">phantom</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'child_process'</span><span class="p">).</span><span class="nx">spawn</span><span class="p">(</span><span class="s1">'phantomjs'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'phantom-server.js'</span><span class="p">,</span> <span class="nx">url</span><span class="p">]);</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">setEncoding</span><span class="p">(</span><span class="s1">'utf8'</span><span class="p">);</span> - <span class="c1">// Our phantom.js script is simply logging the output and</span> - <span class="c1">// we access it here through stdout</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">content</span> <span class="o">+=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span> - <span class="p">});</span> - <span class="nx">phantom</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'exit'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> - <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'We have an error'</span><span class="p">);</span> - <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> - <span class="c1">// once our phantom.js script exits, let's call out call back</span> - <span class="c1">// which outputs the contents to the page</span> - <span class="nx">callback</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> -<span class="p">};</span> - -<span class="kd">var</span> <span class="nx">respond</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span> - <span class="c1">// Because we use [P] in htaccess we have access to this header</span> - <span class="nx">url</span> <span class="o">=</span> <span class="s1">'http://'</span> <span class="o">+</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">'x-forwarded-host'</span><span class="p">]</span> <span class="o">+</span> <span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> - <span class="nx">getContent</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span> - <span class="p">});</span> -<span class="p">}</span> - -<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sr">/(.*)/</span><span class="p">,</span> <span class="nx">respond</span><span class="p">);</span> -<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span> -</code></pre></div> - - -<p>The script below is <code>phantom-server.js</code> and will be in charge of fully rendering the content. We don't return the content until the page is fully rendered. We hook into the resources listener to do this.</p> - -<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'webpage'</span><span class="p">).</span><span class="nx">create</span><span class="p">();</span> +<p>```javascript +// web.js</p> + +<p>// Express is our web server that can handle request +var express = require(‘express’); +var app = express();</p> + +<p>var getContent = function(url, callback) { + var content = ‘’; + // Here we spawn a phantom.js process, the first element of the + // array is our phantomjs script and the second element is our url + var phantom = require(‘child_process’).spawn(‘phantomjs’, [‘phantom-server.js’, url]); + phantom.stdout.setEncoding(‘utf8’); + // Our phantom.js script is simply logging the output and + // we access it here through stdout + phantom.stdout.on(‘data’, function(data) { + content += data.toString(); + }); + phantom.on(‘exit’, function(code) { + if (code !== 0) { + console.log(‘We have an error’); + } else { + // once our phantom.js script exits, let’s call out call back + // which outputs the contents to the page + callback(content); + } + }); +};</p> + +<p>var respond = function (req, res) { + // Because we use [P] in htaccess we have access to this header + url = ‘http://’ + req.headers[‘x-forwarded-host’] + req.params[0]; + getContent(url, function (content) { + res.send(content); + }); +}</p> + +<p>app.get(/(.*)/, respond); +app.listen(3000); +```</p> + +<p>The script below is <code>phantom-server.js</code> and will be in charge of fully rendering the content. We don’t return the content until the page is fully rendered. We hook into the resources listener to do this.</p> + +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'webpage'</span><span class="p">).</span><span class="nx">create</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'system'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">lastReceived</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">();</span> @@ -199,25 +182,21 @@ <span class="p">}</span> <span class="p">}</span> <span class="c1">// Let us check to see if the page is finished rendering</span> -<span class="kd">var</span> <span class="nx">checkCompleteInterval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="nx">checkComplete</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> -</code></pre></div> - +<span class="kd">var</span> <span class="nx">checkCompleteInterval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="nx">checkComplete</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span></code></pre></div> -<p>Once we have this server up and running we just redirect bots to the server in our client's web server configuration.</p> +<p>Once we have this server up and running we just redirect bots to the server in our client’s web server configuration.</p> -<h2>Redirecting bots</h2> +<h2 id="redirecting-bots">Redirecting bots</h2> <p>If you are using apache we can edit out <code>.htaccess</code> such that Google requests are proxied to our middle man phantom.js server.</p> -<div class="highlight"><pre><code class="javascript"><span class="nx">RewriteEngine</span> <span class="nx">on</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">RewriteEngine</span> <span class="nx">on</span> <span class="nx">RewriteCond</span> <span class="o">%</span><span class="p">{</span><span class="nx">QUERY_STRING</span><span class="p">}</span> <span class="o">^</span><span class="nx">_escaped_fragment_</span><span class="o">=</span><span class="p">(.</span><span class="o">*</span><span class="p">)</span><span class="nx">$</span> -<span class="nx">RewriteRule</span> <span class="p">(.</span><span class="o">*</span><span class="p">)</span> <span class="nx">http</span><span class="o">:</span><span class="c1">//webserver:3000/%1? [P]</span> -</code></pre></div> - +<span class="nx">RewriteRule</span> <span class="p">(.</span><span class="o">*</span><span class="p">)</span> <span class="nx">http</span><span class="o">:</span><span class="c1">//webserver:3000/%1? [P]</span></code></pre></div> <p>We could also include other <code>RewriteCond</code>, such as <code>user agent</code> to redirect other search engines we wish to be indexed on.</p> -<p>Though Google won't use <code>_escaped_fragment_</code> unless we tell it to by either including a meta tag; +<p>Though Google won’t use <code>_escaped_fragment_</code> unless we tell it to by either including a meta tag; <code><meta name="fragment" content="!"></code> or using <code>#!</code> URLs in our links.</p> @@ -228,13 +207,12 @@ using <code>#!</code> URLs in our links.</p> <p>This has been tested with Google Webmasters fetch tool. Make sure you include <code>#!</code> on your URLs when using the fetch tool.</p> -<h3>Relevant Links</h3> +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://seo.apiengine.io">Open source node.js Seo Server</a></li> + <li><a href="http://seo.apiengine.io">Open source node.js Seo Server</a></li> </ul> - </div> </div> @@ -247,7 +225,8 @@ using <code>#!</code> URLs in our links.</p> <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -270,17 +249,9 @@ using <code>#!</code> URLs in our links.</p> </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/videos.html b/_site/videos.html index 3e75717..8dc51fa 100644 --- a/_site/videos.html +++ b/_site/videos.html @@ -5,71 +5,54 @@ <title>About Backbone Tutorials - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -92,17 +77,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/videos/beginner/index.html b/_site/videos/beginner/index.html index cb6c380..2f1d719 100644 --- a/_site/videos/beginner/index.html +++ b/_site/videos/beginner/index.html @@ -129,7 +129,8 @@ console.log('destroyed'); router.navigate('', {trigger:true}); } - }) + }); + return false; }, render: function (options) { var that = this; diff --git a/_site/what-is-a-collection/index.html b/_site/what-is-a-collection/index.html index 40bd3f0..b94a147 100644 --- a/_site/what-is-a-collection/index.html +++ b/_site/what-is-a-collection/index.html @@ -5,71 +5,54 @@ <title>What is a collection? - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,67 +81,60 @@ <div id="post"> -<h1>What is a collection?</h1> +<h1 id="what-is-a-collection">What is a collection?</h1> <p>Backbone collections are simply an ordered set of <a href="/what-is-a-model">models</a>. Such that it can be used in situations such as;</p> <ul> -<li>Model: Student, Collection: ClassStudents</li> -<li>Model: Todo Item, Collection: Todo List</li> -<li>Model: Animal, Collection: Zoo</li> + <li>Model: Student, Collection: ClassStudents</li> + <li>Model: Todo Item, Collection: Todo List</li> + <li>Model: Animal, Collection: Zoo</li> </ul> - <p>Typically your collection will only use one type of model but models themselves are not limited to a type of collection;</p> <ul> -<li>Model: Student, Collection: Gym Class</li> -<li>Model: Student, Collection: Art Class</li> -<li>Model: Student, Collection: English Class</li> + <li>Model: Student, Collection: Gym Class</li> + <li>Model: Student, Collection: Art Class</li> + <li>Model: Student, Collection: English Class</li> </ul> - <p>Here is a generic Model/Collection example.</p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"Music is the answer"</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> <span class="kd">var</span> <span class="nx">Album</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> - <span class="p">});</span> -</code></pre></div> - + <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> + <span class="p">});</span></code></pre></div> -<h2>Building a collection</h2> +<h2 id="building-a-collection">Building a collection</h2> <p>Now we are going to populate a collection with some useful data.</p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> - <span class="nx">name</span><span class="o">:</span> <span class="s2">"Not specified"</span><span class="p">,</span> - <span class="nx">artist</span><span class="o">:</span> <span class="s2">"Not specified"</span> - <span class="p">},</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">Song</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> + <span class="nx">name</span><span class="o">:</span> <span class="s2">"Not specified"</span><span class="p">,</span> + <span class="nx">artist</span><span class="o">:</span> <span class="s2">"Not specified"</span> + <span class="p">},</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"Music is the answer"</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> <span class="kd">var</span> <span class="nx">Album</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">song1</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"How Bizarre"</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">"OMC"</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">song2</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Sexual Healing"</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">"Marvin Gaye"</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">song3</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Talk It Over In Bed"</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">"OMC"</span> <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">myAlbum</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Album</span><span class="p">([</span> <span class="nx">song1</span><span class="p">,</span> <span class="nx">song2</span><span class="p">,</span> <span class="nx">song3</span><span class="p">]);</span> - <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">myAlbum</span><span class="p">.</span><span class="nx">models</span> <span class="p">);</span> <span class="c1">// [song1, song2, song3]</span> -</code></pre></div> + <span class="nx">model</span><span class="o">:</span> <span class="nx">Song</span> + <span class="p">});</span> + <span class="kd">var</span> <span class="nx">song1</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"How Bizarre"</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">"OMC"</span> <span class="p">});</span> + <span class="kd">var</span> <span class="nx">song2</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Sexual Healing"</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">"Marvin Gaye"</span> <span class="p">});</span> + <span class="kd">var</span> <span class="nx">song3</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Song</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Talk It Over In Bed"</span><span class="p">,</span> <span class="nx">artist</span><span class="o">:</span> <span class="s2">"OMC"</span> <span class="p">});</span> + <span class="kd">var</span> <span class="nx">myAlbum</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Album</span><span class="p">([</span> <span class="nx">song1</span><span class="p">,</span> <span class="nx">song2</span><span class="p">,</span> <span class="nx">song3</span><span class="p">]);</span> + <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">myAlbum</span><span class="p">.</span><span class="nx">models</span> <span class="p">);</span> <span class="c1">// [song1, song2, song3]</span></code></pre></div> </div> @@ -171,7 +149,8 @@ <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -194,17 +173,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/what-is-a-model/index.html b/_site/what-is-a-model/index.html index 8f8eb7f..420b29e 100644 --- a/_site/what-is-a-model/index.html +++ b/_site/what-is-a-model/index.html @@ -5,71 +5,54 @@ <title>What is a model? - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,31 +81,31 @@ <div id="post"> -<h1>What is a model?</h1> +<h1 id="what-is-a-model">What is a model?</h1> -<p>Across the internet the definition of <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> is so diluted that it's hard to tell what exactly your model should be doing. The authors of backbone.js have quite a clear definition of what they believe the model represents in backbone.js.</p> +<p>Across the internet the definition of <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> is so diluted that it’s hard to tell what exactly your model should be doing. The authors of backbone.js have quite a clear definition of what they believe the model represents in backbone.js.</p> -<blockquote><p>Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.</p></blockquote> +<blockquote> + <p>Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.</p> +</blockquote> -<p>So for the purpose of the tutorial let's create a model.</p> +<p>So for the purpose of the tutorial let’s create a model.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">"Welcome to this world"</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span> -</code></pre></div> - + <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span></code></pre></div> -<p>So <em>initialize()</em> is triggered whenever you create a new instance of a model( models, collections and views work the same way ). You don't have to include it in your model declaration but you will find yourself using it more often than not.</p> +<p>So <em>initialize()</em> is triggered whenever you create a new instance of a model( models, collections and views work the same way ). You don’t have to include it in your model declaration but you will find yourself using it more often than not.</p> -<h2>Setting attributes</h2> +<h2 id="setting-attributes">Setting attributes</h2> <p>Now we want to pass some parameters when we create an instance of our model.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">"Welcome to this world"</span><span class="p">);</span> <span class="p">}</span> @@ -129,18 +114,15 @@ <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Thomas"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> <span class="c1">// or we can set afterwards, these operations are equivelent</span> <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">();</span> - <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Thomas"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> - -</code></pre></div> - + <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Thomas"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span></code></pre></div> -<p>So passing a JavaScript object to our constructor is the same as calling <em>model.set()</em>. Now that these models have attributes set we need to be able to retrieve them.</p> +<p>So passing a JavaScript object to our constructor is the same as calling <em>model.set()</em>. Now that these models have attributes set we need to be able to retrieve them. </p> -<h2>Getting attributes</h2> +<h2 id="getting-attributes">Getting attributes</h2> <p>Using the <em>model.get()</em> method we can access model properties at anytime.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">"Welcome to this world"</span><span class="p">);</span> <span class="p">}</span> @@ -150,16 +132,13 @@ <span class="kd">var</span> <span class="nx">age</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"age"</span><span class="p">);</span> <span class="c1">// 67</span> <span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">);</span> <span class="c1">// "Thomas"</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"child"</span><span class="p">);</span> <span class="c1">// 'Ryan'</span> - -</code></pre></div> + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"child"</span><span class="p">);</span> <span class="c1">// 'Ryan'</span></code></pre></div> +<h2 id="setting-model-defaults">Setting model defaults</h2> -<h2>Setting model defaults</h2> +<p>Sometimes you will want your model to contain default values. This can easily be accomplished by setting a property name ‘defaults’ in your model declaration.</p> -<p>Sometimes you will want your model to contain default values. This can easily be accomplished by setting a property name 'defaults' in your model declaration.</p> - -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Fetus'</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> @@ -174,16 +153,13 @@ <span class="kd">var</span> <span class="nx">age</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"age"</span><span class="p">);</span> <span class="c1">// 67</span> <span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">);</span> <span class="c1">// "Thomas"</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"child"</span><span class="p">);</span> <span class="c1">// 'Ryan'</span> - -</code></pre></div> + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"child"</span><span class="p">);</span> <span class="c1">// 'Ryan'</span></code></pre></div> - -<h2>Manipulating model attributes</h2> +<h2 id="manipulating-model-attributes">Manipulating model attributes</h2> <p>Models can contain as many custom methods as you like to manipulate attributes. By default all methods are public.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Fetus'</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> @@ -199,18 +175,15 @@ <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Thomas"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">,</span> <span class="nx">child</span><span class="o">:</span> <span class="s1">'Ryan'</span><span class="p">});</span> <span class="nx">person</span><span class="p">.</span><span class="nx">adopt</span><span class="p">(</span><span class="s1">'John Resig'</span><span class="p">);</span> - <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"child"</span><span class="p">);</span> <span class="c1">// 'John Resig'</span> - -</code></pre></div> - + <span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"child"</span><span class="p">);</span> <span class="c1">// 'John Resig'</span></code></pre></div> -<p>So we can implement methods to get/set and perform other calculations using attributes from our model at any time.</p> +<p>So we can implement methods to get/set and perform other calculations using attributes from our model at any time. </p> -<h2>Listening for changes to the model</h2> +<h2 id="listening-for-changes-to-the-model">Listening for changes to the model</h2> -<p>Now onto one of the more useful parts of using a library such as backbone. All attributes of a model can have listeners bound to them to detect changes to their values. In our initialize function we are going to bind a function call everytime we change the value of our attribute. In this case if the name of our "person" changes we will alert their new name.</p> +<p>Now onto one of the more useful parts of using a library such as backbone. All attributes of a model can have listeners bound to them to detect changes to their values. In our initialize function we are going to bind a function call everytime we change the value of our attribute. In this case if the name of our “person” changes we will alert their new name.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Fetus'</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">0</span> @@ -225,13 +198,11 @@ <span class="p">});</span> <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Thomas"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> - <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">'Stewie Griffin'</span><span class="p">});</span> <span class="c1">// This triggers a change and will alert()</span> -</code></pre></div> + <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">'Stewie Griffin'</span><span class="p">});</span> <span class="c1">// This triggers a change and will alert()</span></code></pre></div> +<p>So we can bind the change listener to individual attributes or if we like simply ‘<em>this.on(“change”, function(model){});</em>’ to listen for changes to all attributes of the model.</p> -<p>So we can bind the change listener to individual attributes or if we like simply '<em>this.on("change", function(model){});</em>' to listen for changes to all attributes of the model.</p> - -<h2>Interacting with the server</h2> +<h2 id="interacting-with-the-server">Interacting with the server</h2> <p>Models are used to represent data from your server and actions you perform on them will be translated to RESTful operations.</p> @@ -243,29 +214,27 @@ <p>Our model definition shall thus look like;</p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">urlRoot</span><span class="o">:</span> <span class="s1">'/user'</span><span class="p">,</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">''</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s1">''</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Creating a new model</h3> +<h3 id="creating-a-new-model">Creating a new model</h3> -<p>If we wish to create a new user on the server then we will instantiate a new UserModel and call <code>save</code>. If the <code>id</code> attribute of the model is <code>null</code>, Backbone.js will send a POST request to the urlRoot of the server.</p> +<p>If we wish to create a new user on the server then we will instantiate a new UserModel and call <code>save</code>. If the <code>id</code> attribute of the model is <code>null</code>, Backbone.js will send a POST request to the urlRoot of the server. </p> -<div class="highlight"><pre><code class="javascript"> <span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">UserModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">urlRoot</span><span class="o">:</span> <span class="s1">'/user'</span><span class="p">,</span> <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">''</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s1">''</span> <span class="p">}</span> <span class="p">});</span> - <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">UserModel</span><span class="p">();</span> + <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">();</span> <span class="c1">// Notice that we haven't set an `id`</span> <span class="kd">var</span> <span class="nx">userDetails</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Thomas'</span><span class="p">,</span> @@ -278,22 +247,20 @@ <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">})</span> -</code></pre></div> - + <span class="p">})</span></code></pre></div> <p>Our table should now have the values</p> -<p>1, 'Thomas', 'thomasalwyndavis@gmail.com'</p> +<p>1, ‘Thomas’, ‘thomasalwyndavis@gmail.com’</p> -<h3>Getting a model</h3> +<h3 id="getting-a-model">Getting a model</h3> <p>Now that we have saved a new user model, we can retrieve it from the server. We know that the <code>id</code> is 1 from the above example.</p> -<p>If we instantiate a model with an <code>id</code>, Backbone.js will automatically perform a get request to the urlRoot + '/id' (conforming to RESTful conventions)</p> +<p>If we instantiate a model with an <code>id</code>, Backbone.js will automatically perform a get request to the urlRoot + ‘/id’ (conforming to RESTful conventions)</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> - <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">UserModel</span><span class="p">({</span><span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">});</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> + <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span><span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">});</span> <span class="c1">// The fetch below will perform GET /user/1</span> <span class="c1">// The server should return the id, name and email from the database</span> @@ -301,17 +268,15 @@ <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">})</span> -</code></pre></div> - + <span class="p">})</span></code></pre></div> -<h3>Updating a model</h3> +<h3 id="updating-a-model">Updating a model</h3> <p>Now that we have a model that exist on the server we can perform an update using a PUT request. We will use the <code>save</code> api call which is intelligent and will send a PUT request instead of a POST request if an <code>id</code> is present(conforming to RESTful conventions)</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> - <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">UserModel</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> + <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Thomas'</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s1">'thomasalwyndavis@gmail.com'</span> @@ -324,16 +289,14 @@ We will use the <code>save</code> api call which is intelligent and will send a <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">());</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Deleting a model</h3> +<h3 id="deleting-a-model">Deleting a model</h3> <p>When a model has an <code>id</code> we know that it exist on the server, so if we wish to remove it from the server we can call <code>destroy</code>. <code>destroy</code> will fire off a DELETE /user/id (conforming to RESTful conventions).</p> -<div class="highlight"><pre><code class="javascript"> <span class="c1">// Here we have set the `id` of the model</span> - <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">UserModel</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Here we have set the `id` of the model</span> + <span class="kd">var</span> <span class="nx">user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Usermodel</span><span class="p">({</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Thomas'</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s1">'thomasalwyndavis@gmail.com'</span> @@ -345,27 +308,22 @@ We will use the <code>save</code> api call which is intelligent and will send a <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="s1">'Destroyed'</span><span class="p">);</span> <span class="p">}</span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<h3>Tips and Tricks</h3> +<h3 id="tips-and-tricks">Tips and Tricks</h3> <p><em>Get all the current attributes</em></p> -<div class="highlight"><pre><code class="javascript"> - <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Thomas"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Thomas"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">67</span><span class="p">});</span> <span class="kd">var</span> <span class="nx">attributes</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">();</span> <span class="c1">// { name: "Thomas", age: 67}</span> <span class="cm">/* This simply returns a copy of the current attributes. */</span> <span class="kd">var</span> <span class="nx">attributes</span> <span class="o">=</span> <span class="nx">person</span><span class="p">.</span><span class="nx">attributes</span><span class="p">;</span> - <span class="cm">/* The line above gives a direct reference to the attributes and you should be careful when playing with it. Best practise would suggest that you use .set() to edit attributes of a model to take advantage of backbone listeners. */</span> -</code></pre></div> - + <span class="cm">/* The line above gives a direct reference to the attributes and you should be careful when playing with it. Best practise would suggest that you use .set() to edit attributes of a model to take advantage of backbone listeners. */</span></code></pre></div> <p><em>Validate data before you set or save it</em></p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="c1">// If you return a string from the validate function,</span> <span class="c1">// Backbone will throw an error</span> <span class="nx">validate</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">attributes</span> <span class="p">){</span> @@ -388,18 +346,14 @@ We will use the <code>save</code> api call which is intelligent and will send a <span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">;</span> <span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">"Dr Manhatten"</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">});</span> - <span class="c1">// God have mercy on our souls</span> - -</code></pre></div> + <span class="c1">// God have mercy on our souls</span></code></pre></div> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/utkarshkukreti">Utkarsh Kukreti</a></li> + <li><a href="https://github.com/utkarshkukreti">Utkarsh Kukreti</a></li> </ul> - </div> </div> @@ -412,7 +366,8 @@ We will use the <code>save</code> api call which is intelligent and will send a <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -435,17 +390,9 @@ We will use the <code>save</code> api call which is intelligent and will send a </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/what-is-a-router/index.html b/_site/what-is-a-router/index.html index e73f3a2..521191a 100644 --- a/_site/what-is-a-router/index.html +++ b/_site/what-is-a-router/index.html @@ -5,71 +5,54 @@ <title>What is a router? - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,15 +81,15 @@ <div id="post"> -<h1>What is a router?</h1> +<h1 id="what-is-a-router">What is a router?</h1> -<p>Backbone routers are used for routing your applications URL's when using hash tags(#). In the traditional MVC sense they don't necessarily fit the semantics and if you have read "<a href="http://backbonetutorials.com/what-is-a-view">What is a view?</a>" it will elaborate on this point. Though a Backbone "router" is still very useful for any application/feature that needs URL routing/history capabilities.</p> +<p>Backbone routers are used for routing your applications URL’s when using hash tags(#). In the traditional MVC sense they don’t necessarily fit the semantics and if you have read “<a href="http://backbonetutorials.com/what-is-a-view">What is a view?</a>” it will elaborate on this point. Though a Backbone “router” is still very useful for any application/feature that needs URL routing/history capabilities. </p> <p>Defined routers should always contain at least one route and a function to map the particular route to. In the example below we are going to define a route that is always called.</p> -<p>Also note that routes interpret anything after "#" tag in the URL. All links in your application should target "#/action" or "#action". (Appending a forward slash after the hashtag looks a bit nicer e.g. http://example.com/#/user/help)</p> +<p>Also note that routes interpret anything after “#” tag in the URL. All links in your application should target “#/action” or “#action”. (Appending a forward slash after the hashtag looks a bit nicer e.g. http://example.com/#/user/help)</p> -<div class="highlight"><pre><code class="html"><span class="nt"><script></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><script></span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"*actions"</span><span class="o">:</span> <span class="s2">"defaultRoute"</span> <span class="c1">// matches http://example.com/#anything-here</span> @@ -120,9 +105,7 @@ <span class="c1">// Start Backbone history a necessary step for bookmarkable URL's</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> -<span class="nt"></script></span> -</code></pre></div> - +<span class="nt"></script></span></code></pre></div> <p><a href="#action">Activate route</a></p> @@ -130,11 +113,11 @@ <p><em>Notice the change in the url</em></p> -<h2>Dynamic Routing</h2> +<h2 id="dynamic-routing">Dynamic Routing</h2> -<p>Most conventional frameworks allow you to define routes that contain a mix of static and dynamic route parameters. For example you might want to retrieve a post with a variable id with a friendly URL string. Such that your URL would look like "http://example.com/#/posts/12". Once this route was activated you would want to access the id given in the URL string. This example is implemented below.</p> +<p>Most conventional frameworks allow you to define routes that contain a mix of static and dynamic route parameters. For example you might want to retrieve a post with a variable id with a friendly URL string. Such that your URL would look like “http://example.com/#/posts/12”. Once this route was activated you would want to access the id given in the URL string. This example is implemented below.</p> -<div class="highlight"><pre><code class="html"><span class="nt"><script></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><script></span> <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"posts/:id"</span><span class="o">:</span> <span class="s2">"getPost"</span><span class="p">,</span> @@ -153,9 +136,7 @@ <span class="c1">// Start Backbone history a necessary step for bookmarkable URL's</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span> -<span class="nt"></script></span> -</code></pre></div> - +<span class="nt"></script></span></code></pre></div> <p><a href="#/posts/120">Post 120</a></p> @@ -163,15 +144,15 @@ <p><em>Notice the change in the url</em></p> -<h2>Dynamic Routing Cont. ":params" and "*splats"</h2> +<h2 id="dynamic-routing-cont-params-and-splats">Dynamic Routing Cont. “:params” and “*splats”</h2> -<p>Backbone uses two styles of variables when implementing routes. First there are ":params" which match any URL components between slashes. Then there are "<em>splats" which match any number of URL components. Note that due to the nature of a "</em>splat" it will always be the last variable in your URL as it will match any and all components.</p> +<p>Backbone uses two styles of variables when implementing routes. First there are “:params” which match any URL components between slashes. Then there are “<em>splats” which match any number of URL components. Note that due to the nature of a “</em>splat” it will always be the last variable in your URL as it will match any and all components.</p> -<p>Any "*splats" or ":params" in route definitions are passed as arguments (in respective order) to the associated function. A route defined as "/:route/:action" will pass 2 variables (“route” and “action”) to the callback function. (If this is confusing please post a comment and I will try articulate it better)</p> +<p>Any “*splats” or “:params” in route definitions are passed as arguments (in respective order) to the associated function. A route defined as “/:route/:action” will pass 2 variables (“route” and “action”) to the callback function. (If this is confusing please post a comment and I will try articulate it better)</p> -<p>Here are some examples of using ":params" and "*splats"</p> +<p>Here are some examples of using “:params” and “*splats”</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">routes</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"posts/:id"</span><span class="o">:</span> <span class="s2">"getPost"</span><span class="p">,</span> <span class="c1">// <a href="http://example.com/#/posts/121">Example</a></span> @@ -192,30 +173,25 @@ <span class="p">});</span> <span class="nx">app_router</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'route:loadView'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">route</span><span class="p">,</span> <span class="nx">action</span> <span class="p">){</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">route</span> <span class="o">+</span> <span class="s2">"_"</span> <span class="o">+</span> <span class="nx">action</span><span class="p">);</span> <span class="c1">// dashboard_graph </span> - <span class="p">});</span> -</code></pre></div> - + <span class="p">});</span></code></pre></div> -<p>Routes are quite powerful and in an ideal world your application should never contain too many. If you need to implement hash tags with SEO in mind, do a google search for "google seo hashbangs". Also check out <a href="http://seo.apiengine.io">Seo Server</a></p> +<p>Routes are quite powerful and in an ideal world your application should never contain too many. If you need to implement hash tags with SEO in mind, do a google search for “google seo hashbangs”. Also check out <a href="http://seo.apiengine.io">Seo Server</a></p> <p>Remember to do a pull request for any errors you come across.</p> -<h3>Relevant Links</h3> - +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://documentcloud.github.com/backbone/#Router">Backbone.js official router documentation</a></li> -<li><a href="http://thomasdavis.github.com/2011/02/07/making-a-restful-ajax-app.html">Using routes and understanding the hash tag</a></li> + <li><a href="http://documentcloud.github.com/backbone/#Router">Backbone.js official router documentation</a></li> + <li><a href="http://thomasdavis.github.com/2011/02/07/making-a-restful-ajax-app.html">Using routes and understanding the hash tag</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="http://schistad.info">Herman Schistad</a> - (Backbone 0.5 rename from Controller to Router)</li> -<li><a href="http://paulirish.com">Paul Irish</a></li> + <li><a href="http://schistad.info">Herman Schistad</a> - (Backbone 0.5 rename from Controller to Router)</li> + <li><a href="http://paulirish.com">Paul Irish</a></li> </ul> - </div> </div> @@ -228,7 +204,8 @@ <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -251,17 +228,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/what-is-a-view/index.html b/_site/what-is-a-view/index.html index 8ead238..9d5bb5f 100644 --- a/_site/what-is-a-view/index.html +++ b/_site/what-is-a-view/index.html @@ -5,71 +5,54 @@ <title>What is a view? - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,15 +81,15 @@ <div id="post"> -<h1>What is a view?</h1> +<h1 id="what-is-a-view">What is a view?</h1> -<p>Backbone views are used to reflect what your applications' data models look like. They are also used to listen to events and react accordingly. This tutorial will not be addressing how to bind models and collections to views but will focus on view functionality and how to use views with a JavaScript templating library, specifically <a href="http://documentcloud.github.com/underscore/#template">Underscore.js's _.template</a>.</p> +<p>Backbone views are used to reflect what your applications’ data models look like. They are also used to listen to events and react accordingly. This tutorial will not be addressing how to bind models and collections to views but will focus on view functionality and how to use views with a JavaScript templating library, specifically <a href="http://documentcloud.github.com/underscore/#template">Underscore.js’s _.template</a>.</p> -<p>We will be using <a href="http://jquery.com/">jQuery 1.8.2</a> as our DOM manipulator. It's possible to use other libraries such as <a href="http://mootools.net/">MooTools</a> or <a href="http://sizzlejs.com/">Sizzle</a>, but official Backbone.js documentation endorses jQuery. Backbone.View events may not work with other libraries other than jQuery.</p> +<p>We will be using <a href="http://jquery.com/">jQuery 1.8.2</a> as our DOM manipulator. It’s possible to use other libraries such as <a href="http://mootools.net/">MooTools</a> or <a href="http://sizzlejs.com/">Sizzle</a>, but official Backbone.js documentation endorses jQuery. Backbone.View events may not work with other libraries other than jQuery.</p> <p>For the purposes of this demonstration, we will be implementing a search box. <a href="http://jsfiddle.net/tBS4X/1/">A live example</a> can be found on jsFiddle.</p> -<div class="highlight"><pre><code class="javascript"> <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> +<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> <span class="nx">alert</span><span class="p">(</span><span class="s2">"Alerts suck."</span><span class="p">);</span> <span class="p">}</span> @@ -112,39 +97,35 @@ <span class="c1">// The initialize function is always called when instantiating a Backbone View.</span> <span class="c1">// Consider it the constructor of the class.</span> - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">();</span> -</code></pre></div> - + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">();</span></code></pre></div> -<h2>The "el" property</h2> +<h2 id="the-el-property">The “el” property</h2> -<p>The "el" property references the DOM object created in the browser. Every Backbone.js view has an "el" property, and if it not defined, Backbone.js will construct its own, which is an empty div element.</p> +<p>The “el” property references the DOM object created in the browser. Every Backbone.js view has an “el” property, and if it not defined, Backbone.js will construct its own, which is an empty div element.</p> -<p>Let us set our view's "el" property to div#search_container, effectively making Backbone.View the owner of the DOM element.</p> +<p>Let us set our view’s “el” property to div#search_container, effectively making Backbone.View the owner of the DOM element.</p> -<div class="highlight"><pre><code class="html"><span class="nt"><div</span> <span class="na">id=</span><span class="s">"search_container"</span><span class="nt">></div></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">id=</span><span class="s">"search_container"</span><span class="nt">></div></span> <span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">></span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="nx">alert</span><span class="p">(</span><span class="s2">"Alerts suck."</span><span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_container"</span><span class="p">)</span> <span class="p">});</span> -<span class="nt"></script></span> -</code></pre></div> - + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="nx">alert</span><span class="p">(</span><span class="s2">"Alerts suck."</span><span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_container"</span><span class="p">)</span> <span class="p">});</span> +<span class="nt"></script></span></code></pre></div> <p><em>Note: Keep in mind that this binds the container element. Any events we trigger must be in this element.</em></p> -<h2>Loading a template</h2> +<h2 id="loading-a-template">Loading a template</h2> -<p>Backbone.js is dependent on Underscore.js, which includes its own micro-templating solution. Refer to <a href="http://documentcloud.github.com/underscore/">Underscore.js's documentation</a> for more information.</p> +<p>Backbone.js is dependent on Underscore.js, which includes its own micro-templating solution. Refer to <a href="http://documentcloud.github.com/underscore/">Underscore.js’s documentation</a> for more information.</p> -<p>Let us implement a "render()" function and call it when the view is initialized. The "render()" function will load our template into the view's "el" property using jQuery.</p> +<p>Let us implement a “render()” function and call it when the view is initialized. The “render()” function will load our template into the view’s “el” property using jQuery.</p> -<div class="highlight"><pre><code class="html"><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/template"</span> <span class="na">id=</span><span class="s">"search_template"</span><span class="nt">></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/template"</span> <span class="na">id=</span><span class="s">"search_template"</span><span class="nt">></span> <span class="o"><</span><span class="nx">label</span><span class="o">></span><span class="nx">Search</span><span class="o"><</span><span class="err">/label></span> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">id</span><span class="o">=</span><span class="s2">"search_input"</span> <span class="o">/></span> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"button"</span> <span class="nx">id</span><span class="o">=</span><span class="s2">"search_button"</span> <span class="nx">value</span><span class="o">=</span><span class="s2">"Search"</span> <span class="o">/></span> @@ -153,30 +134,28 @@ <span class="nt"><div</span> <span class="na">id=</span><span class="s">"search_container"</span><span class="nt">></div></span> <span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">></span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> - <span class="p">},</span> - <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="c1">// Compile the template using underscore</span> - <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_template"</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="p">{}</span> <span class="p">);</span> - <span class="c1">// Load the compiled HTML into the Backbone "el"</span> - <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_container"</span><span class="p">)</span> <span class="p">});</span> -<span class="nt"></script></span> -</code></pre></div> - + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> + <span class="p">},</span> + <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="c1">// Compile the template using underscore</span> + <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_template"</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="p">{}</span> <span class="p">);</span> + <span class="c1">// Load the compiled HTML into the Backbone "el"</span> + <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_container"</span><span class="p">)</span> <span class="p">});</span> +<span class="nt"></script></span></code></pre></div> <p><em>Tip: Place all your templates in a file and serve them from a CDN. This ensures your users will always have your application cached.</em></p> -<h2>Listening for events</h2> +<h2 id="listening-for-events">Listening for events</h2> -<p>To attach a listener to our view, we use the "events" attribute of Backbone.View. Remember that event listeners can only be attached to child elements of the "el" property. Let us attach a "click" listener to our button.</p> +<p>To attach a listener to our view, we use the “events” attribute of Backbone.View. Remember that event listeners can only be attached to child elements of the “el” property. Let us attach a “click” listener to our button.</p> -<div class="highlight"><pre><code class="html"><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/template"</span> <span class="na">id=</span><span class="s">"search_template"</span><span class="nt">></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/template"</span> <span class="na">id=</span><span class="s">"search_template"</span><span class="nt">></span> <span class="o"><</span><span class="nx">label</span><span class="o">></span><span class="nx">Search</span><span class="o"><</span><span class="err">/label></span> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">id</span><span class="o">=</span><span class="s2">"search_input"</span> <span class="o">/></span> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"button"</span> <span class="nx">id</span><span class="o">=</span><span class="s2">"search_button"</span> <span class="nx">value</span><span class="o">=</span><span class="s2">"Search"</span> <span class="o">/></span> @@ -203,15 +182,13 @@ <span class="p">});</span> <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_container"</span><span class="p">)</span> <span class="p">});</span> -<span class="nt"></script></span> -</code></pre></div> - +<span class="nt"></script></span></code></pre></div> -<h2>Tips and Tricks</h2> +<h2 id="tips-and-tricks">Tips and Tricks</h2> <p><em>Using template variables</em></p> -<div class="highlight"><pre><code class="html"><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/template"</span> <span class="na">id=</span><span class="s">"search_template"</span><span class="nt">></span> +<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/template"</span> <span class="na">id=</span><span class="s">"search_template"</span><span class="nt">></span> <span class="c"><!--</span> <span class="nx">Access</span> <span class="nx">template</span> <span class="nx">variables</span> <span class="kd">with</span> <span class="o"><%=</span> <span class="o">%></span> <span class="o">--></span> <span class="o"><</span><span class="nx">label</span><span class="o">><%=</span> <span class="nx">search_label</span> <span class="o">%><</span><span class="err">/label></span> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">id</span><span class="o">=</span><span class="s2">"search_input"</span> <span class="o">/></span> @@ -221,49 +198,45 @@ <span class="nt"><div</span> <span class="na">id=</span><span class="s">"search_container"</span><span class="nt">></div></span> <span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">></span> - <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> - <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> - <span class="p">},</span> - <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> - <span class="c1">//Pass variables in using Underscore.js Template</span> - <span class="kd">var</span> <span class="nx">variables</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">search_label</span><span class="o">:</span> <span class="s2">"My Search"</span> <span class="p">};</span> - <span class="c1">// Compile the template using underscore</span> - <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_template"</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="nx">variables</span> <span class="p">);</span> - <span class="c1">// Load the compiled HTML into the Backbone "el"</span> - <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> - <span class="p">},</span> - <span class="nx">events</span><span class="o">:</span> <span class="p">{</span> - <span class="s2">"click input[type=button]"</span><span class="o">:</span> <span class="s2">"doSearch"</span> - <span class="p">},</span> - <span class="nx">doSearch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">event</span> <span class="p">){</span> - <span class="c1">// Button clicked, you can access the element that was clicked with event.currentTarget</span> - <span class="nx">alert</span><span class="p">(</span> <span class="s2">"Search for "</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_input"</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">);</span> - <span class="p">}</span> - <span class="p">});</span> - - <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_container"</span><span class="p">)</span> <span class="p">});</span> -<span class="nt"></script></span> -</code></pre></div> - - -<h3>Relevant Links</h3> + <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> + <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span> + <span class="p">},</span> + <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> + <span class="c1">//Pass variables in using Underscore.js Template</span> + <span class="kd">var</span> <span class="nx">variables</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">search_label</span><span class="o">:</span> <span class="s2">"My Search"</span> <span class="p">};</span> + <span class="c1">// Compile the template using underscore</span> + <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_template"</span><span class="p">).</span><span class="nx">html</span><span class="p">(),</span> <span class="nx">variables</span> <span class="p">);</span> + <span class="c1">// Load the compiled HTML into the Backbone "el"</span> + <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span> <span class="nx">template</span> <span class="p">);</span> + <span class="p">},</span> + <span class="nx">events</span><span class="o">:</span> <span class="p">{</span> + <span class="s2">"click input[type=button]"</span><span class="o">:</span> <span class="s2">"doSearch"</span> + <span class="p">},</span> + <span class="nx">doSearch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">event</span> <span class="p">){</span> + <span class="c1">// Button clicked, you can access the element that was clicked with event.currentTarget</span> + <span class="nx">alert</span><span class="p">(</span> <span class="s2">"Search for "</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_input"</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">);</span> + <span class="p">}</span> + <span class="p">});</span> + + <span class="kd">var</span> <span class="nx">search_view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span> <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#search_container"</span><span class="p">)</span> <span class="p">});</span> +<span class="nt"></script></span></code></pre></div> + +<h3 id="relevant-links">Relevant Links</h3> <ul> -<li><a href="http://thomasdavis.github.com/2011/02/05/backbone-views-and-templates.html">This example implemented with google API</a></li> -<li><a href="http://jsfiddle.net/thomas/C9wew/4/">This examples exact code on jsfiddle.net</a></li> -<li><a href="http://jsfiddle.net/thomas/dKK9Y/6/">Another semi-complete example on jsFiddle</a></li> + <li><a href="http://thomasdavis.github.com/2011/02/05/backbone-views-and-templates.html">This example implemented with google API</a></li> + <li><a href="http://jsfiddle.net/thomas/C9wew/4/">This examples exact code on jsfiddle.net</a></li> + <li><a href="http://jsfiddle.net/thomas/dKK9Y/6/">Another semi-complete example on jsFiddle</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/zaeleus">Michael Macias</a></li> -<li><a href="https://github.com/lawnday">Alex Lande</a></li> + <li><a href="https://github.com/zaeleus">Michael Macias</a></li> + <li><a href="https://github.com/lawnday">Alex Lande</a></li> </ul> - </div> </div> @@ -276,7 +249,8 @@ <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -299,17 +273,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/_site/why-would-you-use-backbone/index.html b/_site/why-would-you-use-backbone/index.html index e3a4a43..214c8c4 100644 --- a/_site/why-would-you-use-backbone/index.html +++ b/_site/why-would-you-use-backbone/index.html @@ -5,71 +5,54 @@ <title>Why would you use Backbone.js? - Backbone.js Tutorials</title> <link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml"> <meta name="author" content="Backbone Tutorials" /> - <!-- syntax highlighting CSS --> <!-- syntax highlighting CSS --> <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - <link rel="stylesheet" href="http://cdn.moot.it/1.1/moot.css"/> <!-- Homepage CSS --> - <link rel="stylesheet" href="/css/bootstrap.css" type="text/css" media="screen, projection" /> + <link rel="stylesheet" href="//bootswatch.com/sandstone/bootstrap.min.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" /> - + <link href="https://fonts.googleapis.com/css?family=Arvo:400,700&subset=latin" rel="stylesheet" type="text/css"> <!-- Typekit --> <script type="text/javascript">try{Typekit.load();}catch(e){}</script> - <script type="text/javascript"> -/* <![CDATA[ */ - (function() { - var s = document.createElement('script'), t = document.getElementsByTagName('script')[0]; - s.type = 'text/javascript'; - s.async = true; - s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto'; - t.parentNode.insertBefore(s, t); - })(); -/* ]]> */ -</script> - <!-- (1) Moot depends on jQuery v1.7 or greater --> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> + </head> <body> -<div class="container"> <div class="row"> - <div class="col-lg-12"> - <div class="navbar" style="margin-top:10px;"> - <div class="container"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Backbone Tutorials</a> - <div class="nav-collapse collapse navbar-responsive-collapse"> - <ul class="nav navbar-nav"> - <li class=""><a href="/">Home</a></li> - - </ul> - <ul class="nav navbar-nav pull-right"> - <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> - <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> - </ul> - </div><!-- /.nav-collapse --> - </div><!-- /.container --> - </div> + <div class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/">Backbone Tutorials</a> + </div> + <div class="navbar-collapse collapse navbar-responsive-collapse"> + <ul class="nav navbar-nav"> + <li class=""><a href="/">Home</a></li> - </div> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="http://prerender.io"><strong>Need SEO?</strong></a></li> + <li><a href="http://feeds.feedburner.com/BackboneTutorials">Subscribe</a></li> + <li><a href="https://leanpub.com/backbonetutorials">Download eBook (.pdf, .MOBI, .ePub)</a></li> + </ul> </div> </div> +</div> + -<div style=""></div> <div class="container"> <div class="row"> <div class="col-lg-4"> @@ -79,12 +62,14 @@ </div> <p>Backbone Tutorials is a collection of tutorials written by <a href="http://thomasdav.is">Thomas Davis</a>. Everything is open source and I try my best to keep the tutorials updated. Though I am busy and only work on this is my spare time so many <a href="https://github.com/thomasdavis/backbonetutorials/graphs/contributors">contributors</a> have also help me put this resource together.</p> - </div> +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> + </div> </div> <div class="col-lg-8"> <h3 >Backbone.js Beginner Video Tutorial</h3> <img src="/backbone.png" style="float: left;" /><p>I have put extra effort into making a very easy to understand Backbone.js video which is also free. It is 70mins long and covers everything you need to know when getting started.</p> - <a href="http://gum.co/backbone-beginner-screencast" class="btn btn-primary">Watch Video</a> + <a href="https://www.youtube.com/watch?v=FZSjvWtUxYk" class="btn btn-primary">Watch Video</a> </div> </div> <div class="container"> @@ -96,37 +81,35 @@ <div id="post"> -<h1>Why do you need Backbone.js?</h1> +<h1 id="why-do-you-need-backbonejs">Why do you need Backbone.js?</h1> <p>Building single-page web apps or complicated user interfaces will get extremely difficult by simply using <a href="http://jquery.com">jQuery</a> or <a href="http://mootools.net">MooTools</a>. The problem is standard JavaScript libraries are great at what they do - and without realizing it you can build an entire application without any formal structure. You will with ease turn your application into a nested pile of jQuery callbacks, all tied to concrete DOM elements.</p> -<p>I shouldn't need to explain why building something without any structure is a bad idea. Of course you can always invent your own way of structuring your application but you miss out on the benefits of the open source community.</p> +<p>I shouldn’t need to explain why building something without any structure is a bad idea. Of course you can always invent your own way of structuring your application but you miss out on the benefits of the open source community.</p> -<h2>Why single page applications are the future</h2> +<h2 id="why-single-page-applications-are-the-future">Why single page applications are the future</h2> <p>Backbone.js enforces that communication to the server should be done entirely through a RESTful API. The web is currently trending such that all data/content will be exposed through an API. This is because the browser is no longer the only client, we now have mobile devices, tablet devices, Google Goggles and electronic fridges etc.</p> -<h2>So how does Backbone.js help?</h2> +<h2 id="so-how-does-backbonejs-help">So how does Backbone.js help?</h2> <p>Backbone is an incredibly small library for the amount of functionality and structure it gives you. It is essentially MVC for the client and allows you to make your code modular. If you read through some of the beginner tutorials the benefits will soon become self evident and due to Backbone.js light nature you can incrementally include it in any current or future projects.</p> -<h2>Other frameworks</h2> +<h2 id="other-frameworks">Other frameworks</h2> <p>If you are looking for comparisons to build your single page application, try some of these resourceful links.</p> <ul> -<li><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">A feature comparison of different frontend frameworks</a></li> -<li><a href="http://addyosmani.github.com/todomvc/">Todo MVC - Todo list implemented in the many different types of frontend frameworks</a></li> + <li><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">A feature comparison of different frontend frameworks</a></li> + <li><a href="http://addyosmani.github.com/todomvc/">Todo MVC - Todo list implemented in the many different types of frontend frameworks</a></li> </ul> - -<h3>Contributors</h3> +<h3 id="contributors">Contributors</h3> <ul> -<li><a href="https://github.com/FND">FND</a></li> + <li><a href="https://github.com/FND">FND</a></li> </ul> - <p><strong>If you questions regarding why you should choose Backbone.js as your framework, please leave a comment below</strong></p> </div> @@ -141,7 +124,8 @@ <a href="https://plus.google.com/101608559187380638042?rel=author">Google Profile</a> <a href="https://twitter.com/neutralthoughts">Twitter</a> <a href="https://github.com/thomasdavis">Github</a> - +<a href="https://twitter.com/neutralthoughts" class="twitter-follow-button" data-show-count="true">Follow @neutralthoughts</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </div> <div class="panel panel-info"> <div class="panel-heading"> @@ -164,17 +148,9 @@ </div> </div> -<!-- AddThis Button BEGIN --> -<div class="addthis_toolbox addthis_floating_style addthis_counter_style" style="left:50px;top:50px;"> -<a class="addthis_button_facebook_like" fb:like:layout="box_count"></a> -<a class="addthis_button_tweet" tw:count="vertical"></a> -<a class="addthis_button_google_plusone" g:plusone:size="tall"></a> -<a class="addthis_counter"></a> -</div> -<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-520b31815dc3cdc8"></script> -<!-- AddThis Button END --> <script src="//static.getclicky.com/js" type="text/javascript"></script> <script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script> <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript> + </body> </html> diff --git a/css/style.css b/css/style.css index 8397263..3dd5ca0 100644 --- a/css/style.css +++ b/css/style.css @@ -7,3 +7,15 @@ #post h3 { font-size: 20px !important; } + +.container { + max-width: 840px !important ; +} +/* +body { + font: 1em "Arvo","Helvetica Neue",Helvetica,Arial,sans-serif !important; + text-shadow: 0 0 4px #CCC !important; + color: #333; + font-size: 14px !important; +} +*/
\ No newline at end of file |