Backbone.js Wine Cellar Tutorial — Part 1: Getting Started

One of the challenges when building nontrivial Web applications is that JavaScript’s non-directive nature can initially lead to a lack of structure in your code, or in other words, a lack of… backbone. JavaScript is often written as a litany of free-hanging and unrelated blocks of code, and it doesn’t take long before it becomes hard to make sense of the logic and organization of your own code.

Backbone.js is a lightweight framework that addresses this issue by adding structure to JavaScript-heavy Web applications.

Self-contained building blocks

Backbone.js provides several classes (Model, Collection, View, Router) that you can extend to define the building blocks of your application. To build an app with Backbone.js, you first create the Models, Collections, and Views of your application. You then bring these components to life by defining a “Router” that provides the entry points of your application through a set of (deep-linkable) URLs.

With Backbone.js, your code is organized in self-contained entities (Models, Collections, Views): No more free-hanging and unrelated blocks of code.

Data Binding

With Backbone.js, you bind Views to Models so that when a Model’s data changes, all the Views bound to that Model automatically re-render. No more complex UI synchronization code.

Elegant REST Integration

Backbone.js also provides a natural / magical / elegant integration with RESTful services. If your back-end data is exposed through a pure RESTful API, retrieving (GET), creating (POST), updating (PUT), and deleting (DELETE) models is incredibly easy using the Backbone.js simple Model API.

Sample Application

In this three-part tutorial, you’ll create a Wine Cellar application. You can browse through a list of wines, as well as add, update, and delete wines.

  • In Part 1 (this post), you define the basic infrastructure. You create a “read-only” version of the application: you’ll be able to retrieve a list of wine and get the details of each wine.
  • In Part 2, you add the code to add, update and delete wines. You leverage Backbone’s powerful REST integration.
  • In Part 3, you add complete support for history management and deep linking.

NOTE: I also blogged a non-Backbone version of the application here (Java back-end) and here (PHP back-end), which you can look at for comparison.

Part 1: The Read-Only Wine Cellar Application

You can run the application (Part 1) here.

Here is the code:

// Models
window.Wine = Backbone.Model.extend();

window.WineCollection = Backbone.Collection.extend({

// Views
window.WineListView = Backbone.View.extend({


    initialize:function () {
        this.model.bind("reset", this.render, this);

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


window.WineListItemView = Backbone.View.extend({



    render:function (eventName) {
        return this;


window.WineView = Backbone.View.extend({


    render:function (eventName) {
        return this;


// Router
var AppRouter = Backbone.Router.extend({


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

    wineDetails:function (id) { = this.wineList.get(id);
        this.wineView = new WineView({});

var app = new AppRouter();

Code Highlights:

  1. WineModel (line 2): Notice that we don’t need to explicitly define the attributes (name, country, year, etc). You could add validation, default values, etc. More on that in Part 2.
  2. WineCollection (lines 4 to 7): “model” indicates the nature of the collection. “url” provides the endpoint for the RESTFul API. This is all that’s needed to retrieve, create, update, and delete wines with Backbone’s simple Model API.
  3. WineListView (lines 10 to 25): The render() function iterates through the collection, instantiates a WineListItemView for each wine in the collection, and adds it to the wineList.
  4. WineListItemView (lines 27 to 38): The render() function merges the model data into the “wine-list-item” template (defined in index.html). By defining a separate View for list items, you will make it easy to update (re-render) a specific list item when the backing model changes without re-rendering the entire list. More on that in Part 2.
  5. WineView (lines 40 to 49): The view responsible for displaying the wine details in the Wine form. The render() function merges the model data (a specific wine) into the “wine-details” template retrieved from index.html.
  6. AppRouter (lines 52 to 71): Provides the entry points for the application through a set of (deep-linkable) URLs. Two routes are defined: The default route (“”) displays the list of wine. The “wines/:id” route displays the details of a specific wine in the wine form. Note that in Part 1, this route is not deep-linkable. You have to start the application with the default route and then select a specific wine. In Part 3, you will make sure you can deep-link to a specific wine.


The source code for this application is hosted on GitHub here. And here is a quick link to the download.

You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download.

UPDATE (1/11/2012): A version of this application with a Java back-end (using JAX-RS and Jersey) is also available on GitHub here. You can find more information on the Java version of this application here.

Part 2 is available here.

175 Responses to Backbone.js Wine Cellar Tutorial — Part 1: Getting Started

  1. Raymond Camden December 6, 2011 at 5:42 pm #

    Just an FYI, when I click to view a wine I end up with this in the URL:

    If I cut and paste that into a new tab, it is throwing an error and not loading the wine. (Well, in console anyway ;)

  2. Christophe December 6, 2011 at 5:45 pm #

    As mentioned in the post, this is the normal behavior in Part 1. Part 3 of this tutorial covers deep linking.

    • Mira December 12, 2012 at 6:25 am #

      White Wine Glasses Related Posts:Hair Loss Help TipsSimple Methods To Help Grow Your Hair OutAdvancing Self Confidence, Appearance And Prettiness Using Hairstyles To Hide Hair LossSaw Palmetto Hair Loss TreatmentHair Loss 101Share and Enjoy: Posted in Health Wellness | Tagged hair loss, hair loss prevention, hair loss putorcds, hair loss treatment for men, laser hair loss treatment, natural hair loss treatment, new hair loss treatment

  3. Raymond Camden December 6, 2011 at 6:29 pm #

    Doh! Helps if I read closer. :)

  4. José Adenaldo Bittencourt December 6, 2011 at 7:07 pm #

    Where are the adobe flex posts?

  5. JCLang December 6, 2011 at 9:16 pm #

    Hello Christophe,
    thanks, your blog is top quality.
    I hope you’ll focus back to Flex soon! :)

    • K5nobi October 1, 2013 at 7:04 pm #

      In your router#list function why do you initialize the view with the wine collection stored to a model attribute?
      I think it would be much better suited to the collection attribute like so:

      61| this.wineListView = new WineListView({collection:this.wineList});

  6. Jeremy December 7, 2011 at 4:19 am #

    I will definitely try this one. My prefered client side implementation of those posts

  7. Stefan Richter December 7, 2011 at 10:29 am #

    thanks for this tutorial. It would be great of Ray could add the CF backend to this :-)

    What IDE do you use or recommend for JS development?



    • Robin January 13, 2012 at 2:28 pm #

      Aptana is a great IDE for front-end development. Back-end too but it supports javascript code completion very well.

  8. Dimitris December 7, 2011 at 10:54 am #

    Great tutorial.
    I’ve read only Ruby on Rails RESTful services.
    php approach is great
    I am waiting for part 2.

    from Thessaloniki Greece

  9. Christophe Coenraets December 7, 2011 at 12:59 pm #

    @jose, @JCLang… Thanks. I have a couple a Flex posts lined up. Stay tuned.

  10. Christophe Coenraets December 7, 2011 at 1:03 pm #

    @Stefan. Still using TextMate for now.

  11. joshua Gonzalez December 8, 2011 at 2:05 pm #

    what if your are not using a restful service to connect?

    • Robin January 13, 2012 at 2:29 pm #

      I’m curious about that too. It doesn’t seem to work without a rest service…

  12. cole\ December 23, 2011 at 6:05 pm #

    Great tutorial. really helped me a lot.
    I noticed in your demo every time you choose a wine and then hit the back button you are making another call for data. any thoughts? I added code that checks for the collection b4 calling fetch. Am i missing something?

    thanks again for this great work!!!

  13. Hecky January 5, 2012 at 11:14 am #

    The link to the part 2 of the tutorial seems broken, ;)

  14. Christophe January 5, 2012 at 2:07 pm #

    @Hecky: Thanks. Fixed.

  15. Seth Stone January 11, 2012 at 4:55 am #

    Thanks for the great post; I’m really enjoying the topics you’re working through. On this app I’m having a bit of trouble with the PHP. Do you happen to know if there’s a min version (of PHP) required to run this? I have 5.1.6 and I’m getting: PHP Fatal error: Uncaught exception ‘ErrorException’ with message ‘setcookie() expects at most 6 parameters, 7 given’. Also, since I’m not too interested in the server side at this point is there a way I could point the JS (served from my server) to the REST API hosted on your system?

    • Seth Stone February 13, 2012 at 5:11 am #

      In case anyone runs into the issues I did… for this to work I had to have a version of PHP higher than 5.1 (5.3.3 worked for me when 5.1.6 did not). Apache has to be configured to AllowOverride FileInfo for the api directories, as this is necessary for .htaccess files to be processed which Slim.php depends on. On RHEL also had to have the php-mysql package installed. Thanks!

      • Faz February 14, 2012 at 6:28 am #

        Thanks for the heads up Seth. Was facing this issue on the Twitter Bootstrap+Backbone tutorial and found your suggestions. Working fine now.

      • Mike May 20, 2012 at 8:34 am #

        I can not get this application to show the data. If I navigate to the api url it returns the JSON data, but the front end is not connecting. I pulled over all of the source and attached it to mysql as instructed, but either the folder needs a different .htaccess connection or there is something I am missing. I saw your note about changing the .htaccess file. Do you have more detail about how you structured it. Which folder you put the rule into? Any help would be fantastic.

  16. Justin February 7, 2012 at 6:08 pm #

    Like it and as other post indicated I really think there should be a version with CF back end.


  17. Benjamin February 18, 2012 at 8:44 pm #

    I think it is a bad idea to present an introductory tutorial like this and teach people to pollute the global namespace.

    There are better ways of handling that situation.

  18. jbcavarec February 21, 2012 at 4:45 pm #

    every time i use fetch() i need to wait for complete download of datas before doing templatinf for example.
    You seem not need to wait for asynchronous call in your example:
    how is it possible ?
    thank you

  19. Dan Nguyen February 28, 2012 at 4:02 am #

    Thanks for the tutorial…One thing that I haven’t been able to figure out: Why do you have the model attribute for WineListView point to a collection (WineCollection), instead of setting the collection attribute to said collection of wines?

  20. Pawan Bhole February 29, 2012 at 4:10 pm #

    Nice post
    Very helpful. :)
    You can add a file names “wines” in folder api containing json response so that anyone can directly extract zip and run it.

  21. Andy Matthews March 23, 2012 at 3:42 am #


    I took a stab at rewriting your app using Ember.js. I’d love your feedback:

  22. switcherdav April 13, 2012 at 8:12 pm #

    Thanks for your tutorial,

    Can you tell me how you catch PHP errors ?

    for exemple, imagine that the creation failed, you return json object but I think that header code return stay 200 so only success event will be fire.

    so how do this ?
    test response like that :
    if( response.error ){ } ?

    I think it’s interesting to wait for the server return before add (or update, or delete) item in the collection (like in Flex for exemple)

  23. Chris April 14, 2012 at 10:19 am #

    Thank you for your Tutorial. I’m still having a hard time getting your part1 sample to work. I try to put together the PHP sample with the Jersey sample (as the Jersey Sample isn’t using backbone.js). One thing I have discovered, as Jersey outputs the namespace “wine” that I had to use the parse method within the Collection:

    window.WineCollection = Backbone.Collection.extend({
    parse: function(data) {
    return data.wines;


    JSON Output:
    “description”:”With hints of ginger and spice, this wine makes an excellent complement to light appetizer and dessert fare for a holiday gathering.”,
    “grapes”:”Pinot Noir”,
    “name”:”BLOCK NINE”,

    Now I don’t see any errors in Firebug, everything seems to be fine, JSON is parsed, but only the HTML part is displayed. All the templates seem not to be loaded. Without any errors that point me to the problem I’m feeling quite lost :-|

    • Jose Miguel October 23, 2013 at 2:06 pm #

      I had the same problem as you and it worked with the parse function. I think the problem in your code is that you wrote “return data.wines” and the correct code is “return” (without the “s”).

  24. delai April 19, 2012 at 2:59 am #

    can not run this app in my place, not wines list was loaded

  25. delai April 19, 2012 at 3:20 am #

    like Pawan Bhole said:
    lost a file named ‘wines’ in api folder, the context is like

    • delai April 20, 2012 at 3:46 am #

      finally, found out, mac built-in apache REWRITE feature can not work correctly without additional configuring.
      anyway , there is a fast way to let this app work: change the “url:”../api/wines” to url:”../api/index.php/wines” in main.js

      • Sean McAuliffe May 23, 2012 at 6:30 am #

        I know this is a little old – if you have a moment, can you elaborate on the “additional configuring” part? Many thanks.

        • Sean McAuliffe May 23, 2012 at 6:41 am #

          Figured it out (used the .htaccess file in one of my local wordpress installs as a base):

          RewriteEngine On
          RewriteBase /~/tutorial/api/
          RewriteRule ^index\.php$ – [L]
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule . /~/tutorial/api/index.php [L]


      • Adam K September 1, 2012 at 4:11 pm #

        If memory serves you also have to change some of your httpd.conf settings too.
        I never could get it to quite work so I just started using MAMP. MySQL included was definitely a bonus

  26. Ash April 20, 2012 at 1:00 pm #

    how do we make our app available for people to download from the app store? I guess after the html and css files are ready we go to and create a build for different devices . where and how do i create the signing keys ofr android , ios ? Please your help will be greatly appreciates .. There might be so many people like me looking for the same information..

  27. Yash April 28, 2012 at 11:43 am #


    The Wine Cellar application assumes that a single person is managing his wine cellar. Had this been a multi-tenant application where every user would login and manage his own cellar, how would we pass the session data to the REST service? Would we send the username and password along with every REST URL?


  28. Mike Baxter May 9, 2012 at 2:15 am #

    Trying to get this running on MAMP (OSX Lion) and strangely only the /bootstrap version included in the git repo seems to successfully connect to the DB and access the data. Can anyone suggest why the /tutorial versions seem unable to connect and access the wine data? It’s very frustrating to debug when a relative newby to php.

    • Mike Baxter May 9, 2012 at 2:32 am #

      In reply to my own question… user: root had no privileges on the cellar database and my fix to this in mamp required going into phpMyAdmin, creating a user, assigning a password and then updating the database connection details at the bottom of /api/index.php

      The bootstrap version of the app uses memorystore.js to create a local database for testing purposes and was displaying this local data instead of the database version, thus hiding the inability to connect to the DB.

      Sorry for the posts but this might help some other newcomers to diagnose localhost issues.

  29. Chiite May 11, 2012 at 9:49 am #

    Oh very good.


  30. Jim Simpson May 12, 2012 at 1:41 am #

    I’ve never written any code before and would love to have access to someone that could create code for my affiliates that use my wysiwyg web app development dashboard. Would you be interested?

  31. skusunam May 14, 2012 at 3:25 pm #

    Very helpful and easy to read through and try out Backbone.js. Thanks for taking time and writing these posts.

  32. jsannn May 15, 2012 at 6:36 pm #

    Amazing tutorial ! I’ve been searching whole day for tutorial to get started using backbone.js and all others I managed to find were incomplete, bugged or using horrible coding. But this one is perfect. Thank you for putting your time in it and keep the good work!

  33. Greg May 22, 2012 at 2:14 pm #

    re: window.Wine = Backbone.Model.extend();
    is there a specific reason you bind to ‘window’? it’s obviously the trend/convention, but since you’re using jquery to bind to the dom, just seems erroneous (or redundant?).

    Learning amd/pattern, so if i ask something relevant, let me know :-D

    Thank you for sharing.

    • Guy August 3, 2012 at 8:51 am #

      Did you ever get an answer to the question? Been wondering the same thing here

  34. Levi May 23, 2012 at 3:14 pm #

    Man this stuff is neat! I dont this its a good idea to bind all your variables to the window object. Rather create a new scope and declare them as standard variables

  35. Tom June 1, 2012 at 1:39 pm #

    I implemented a simple test api to get the wines collection. For the wine list I return

    [{“id”:”1″, name”:”wine1″,”grapes”:”red”,country”:”england”, “region”:”europe”, “description”:”some desc”, “picture”:”aaa.jpg”}]

    The problem is that collection.fetch() fails and I don’t understand why. i did not implement the api calls for getting a single wine. Should this be the pb ?

    • Tom June 3, 2012 at 1:06 pm #

      Stupid me… The JSON string was badly formatted. How can I get the clear error message for such cases ?

  36. Praveen June 20, 2012 at 4:52 am #

    Congrats , Great Effort.. A Small DOubt
    How can we run only part1 with the database connectivity

  37. Kevin Davies June 21, 2012 at 11:06 am #

    For the for the SlimPHP API to work on MacOS X 10.7 (Lion) I had to add Options +FollowSymlinks to my .htaccess file (and adjust the RewriteBase path accordingly). My .htaccess file:

    Options +FollowSymlinks
    RewriteEngine On

    # Some hosts may require you to use the `RewriteBase` directive.
    # If you need to use the `RewriteBase` directive, it should be the
    # absolute physical path to the directory that contains this htaccess file.
    RewriteBase /api/

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]

  38. Marco Pegoraro June 21, 2012 at 1:36 pm #

    Hi to all, good tutorial!
    I wrote another tutorial app focusing my attention in Observe Model implementation.

    The app search Twitter and display tweets so I called – TwitterSarch App

  39. Jason July 16, 2012 at 12:23 am #

    You have the most straight forward example of how to use backbone.js on the entire internet.

  40. Vladimir Sizov July 24, 2012 at 11:15 pm #

    If you’re using WAMP and having troubles retrieving list of wines or any results from “api”, check (make checkbox appear) on “rewrite_module” in list of modules in WAMP taskbar menu.

  41. Rob von Nesselrode July 27, 2012 at 1:00 am #

    Any tips on how to get the Slim stuff to work on Windows 7. I already have PHP running under IIS and the SLIM doco says it needs a Web Server as a pre-requisite. Do I have to create a local virtual and point it to the index.php? In which case what do I have to modify to get the sample to use it?

  42. Jan August 30, 2012 at 2:30 pm #

    Hi Christophe,

    Thanks a lot for the tutorial. This is the one I have been looking for all the time! Clear, step-by-step how to with details. Great job!


  43. Helen November 10, 2012 at 6:45 pm #

    The following training video explains this backbone Celler app well.

  44. Paul November 11, 2012 at 10:59 pm #

    Syntax highlighter seems to be broken. And the following class declaration looks weird:

    Here is the code:

  45. falz December 3, 2012 at 1:30 am #

    Wow! This three part tutorial helped me a lot. Thanks for sharing your ideas. =)

  46. maoshuyu January 15, 2013 at 4:02 pm #


  47. Joe January 30, 2013 at 11:58 pm #

    Hey Christophe.

    In case anyone is interested I created a simple Node.js/MongoDB back end for this tutorial (part 1).

    • marko February 19, 2013 at 1:58 pm #

      Line 20, shouldn’t it be: new WineListItemView({model:wine}).render().el ?

  48. Mike February 21, 2013 at 6:26 pm #

    Hey thanks a lot for the tutorial, hope to see one on how to fun Flex so I can see it in action!

    Also I have an error in my code: “Uncaught TypeError: Cannot call method ‘render’ of undefined ” (line 63)

    Thanks for this, I really appreciate people spreading knowledge on Backbone :)

    • Mike February 21, 2013 at 6:28 pm #

      Jk, it was just a typo! Can’t wait to get started on the next two!

  49. Chinna February 28, 2013 at 7:08 am #

    Hi All,

    Please let me know how we could pass the text box values from index.html to Models–>winemodel.js to the API Url in the Part 1.


  50. March 7, 2013 at 3:36 am #

    Demo App is not showing the wine record, it simply shows a blank list and the heading “Welcome to Backbone Wine Cellar”. I checked with my database its working fine and the connections are all working. No exception or errors either. Can you please give some guidance to troubleshoot this issue.


  51. rd March 9, 2013 at 8:15 am #

    sir i full version on github for cellar set properties file after running the then only page display as heading “Welcome to Backbone Wine Cellar” and a vertical box on left hand side
    then what should i do for execute the application,please reply fast………

  52. Telmo March 20, 2013 at 3:40 pm #

    Hi Christophe, thanks a lot for this. I just finished the code school tuts and i was looking for some real life example on the basic structure. I’m glad i found your site. I now know where to start a project with Backbone + extra bonus track Slim for a easy RESTful in PHP (that little thing is sweet :)

  53. May 5, 2013 at 11:35 am #

    I have been lurking around this wineceller for a while but still not able to get it working in my local WebLogic with Apache Derby backend. I debug and made sure the DAO part is not the issue.

    So I like to go back to basics and get the backbone Java version of Part 1 from GitHub. I get this errror:

    503 Service Unavailable.

    Appreciate if the archives are made available for newbies to get this started and understand the code in a simple example.

    Thank you

  54. adika86 May 17, 2013 at 5:04 pm #

    Very nice job! Really enjoyed it and understood a lot! I think there are too few apps which use backbone… Recently I found an app on google play, which used backbone and looked pretty nice. I think it was called close2u. Anyway really nice job, keep up the good work and we want more of these! :)

  55. David Cosgrove June 1, 2013 at 11:05 pm #

    Hey Christophe,

    First of all, thanks for your series of blogs – they’ve been important resources in my learning web technologies.

    I tried to build this example myself and ran into some issues that prevented it from working – namely, the ItemListView was not rendering. After researching this issue, it seems that the problem stems from a change in a more recent version of Backbone.js which requires parameters to fetch() in order to properly bind the rendering to the model updates.

    Changing line 62:



    this.wineList.fetch({reset: true});

    Fixes the issue.

    Thanks again

  56. Simon B July 19, 2013 at 12:42 am #

    Great tutorial

    Am having trouble getting the winelist from the api

    when i go directly to it

    eg: http://localhost/cellar/api/wines — i get the full list of details yet the new WineCollection call doesnt return anything

    I installed the php backend version and it ran fine


    • Simon B July 19, 2013 at 1:16 am #

      Ok as it turns out my WineCollection does return this when in the console (when i log this.model.models)

      0: r
      _changing: false
      _events: Object
      _pending: false
      _previousAttributes: Object
      attributes: Object
      wine: Array[12]
      0: Object
      1: Object
      2: Object
      3: Object
      4: Object
      5: Object
      6: Object
      7: Object
      8: Object
      9: Object
      10: Object
      11: Object
      length: 12

      But _.each doesnt run thru it once

  57. Prabhakaran August 13, 2013 at 5:40 am #

    Nice article.

    But the demo link is not working,

  58. Rene August 31, 2013 at 7:45 am #

    I’m trying to get the upload filenames to be the ‘record-id.jpg’, any idea what would be a good aproach to accomplish that. So instead of just the filename, i would like to tie it more to the created records, and make it unique.

    Any help would be very appreciated!



  59. K5nobi October 1, 2013 at 7:06 pm #

    In your router#list function why do you initialize the view with the wine collection stored to a model attribute?
    I think it would be much better suited to the collection attribute like so:

    61| this.wineListView = new WineListView({collection:this.wineList});

    Also you’re form is bugged to post comments to to the first opened “leave reply” on the page instead of the one the submit event is actually coming from.

  60. Hi are using WordPress for your site platform? I’m new to the blog world but I’m trying to get
    started and create my own. Do you require any html coding expertise to make your own blog?

    Any help would be greatly appreciated!

  61. Ursula January 12, 2014 at 4:33 pm #

    I know this is a bit old but… does anybody know why would slim framework fail to load the wine list when I set up your app “as is” in an external web hosting? I can make it work locally on my machine but when I uploaded to another server it doesnt load the wine list, page just loads the menu bar and teh rest is blank. I developed a test app to see if it wasnt communicating with teh sql database and that wasnt the problem. It is as if it doesnt find the index.php file to load the wines. It seems to me as if it has to do with htaccess but I am not sure how to set it up, ive been researching but nogo. Help is appreciated, thanks.

  62. Sid January 21, 2014 at 2:38 pm #

    Please correct me if I’m wrong, but I see a race condition in your code.

    Line 62 – 63:

    You already bounce the WineListView render method to the wineList ‘reset’ event on line 15.

    When you call this.wineList.fetch(), won’t wine list view render method will invoke in response to the collection’s “reset” event? If so, then explicitly invoking wineListView.render() on line 63 causes a race condition because you never know if the fetch() method’s ajax call completes before hitting line 63.

    Maybe a better solution would be to change line 63 to:


    That way, you append the wine list view “el” to the DOM, and when the “reset” event fires on the collection, the render() method will render the collection inside “el”.

    Would appreciate your feedback about this. Thanks


    • Sid January 21, 2014 at 2:44 pm #


  63. Shubham January 31, 2014 at 2:18 am #

    Very elaborate and concise article and better contender to impress.js

  64. Roman January 31, 2014 at 8:40 am #


    It looks like something wasn’t substituted on Server Side here: (‘>).
    Am I right?

  65. Roman January 31, 2014 at 8:43 am #

    Sorry for repost, but tags are filtered.

    It looks like something wasn’t substituted on Server Side here: (‘>)

    Am I right?

  66. Roman January 31, 2014 at 8:44 am #

    The are filtered even after spaces were added between < and %.

    It looks like something wasn’t substituted on Server Side here: (Line 31 in the source)

    Am I right?

  67. user1084321 February 15, 2014 at 3:09 pm #

    C:\Users\USER>curl -i
    HTTP/1.1 200 OK
    Date: Sat, 15 Feb 2014 20:08:38 GMT
    Server: Apache
    X-Powered-By: PHP/5.3.28
    Set-Cookie: PHPSESSID=a7f99f71f15111f0464fec40e865fd7f; path=/
    Content-Length: 124
    Set-Cookie: a7f99f71f15111f0464fec40e865fd7f=flash%7Ca%3A0%3A%7B%7D; path=/
    Connection: close
    Content-Type: text/html; charset=UTF-8

    {“error”:{“text”:SQLSTATE[HY000] [2002] Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2)}}

  68. Karl February 17, 2014 at 2:03 pm #

    Hi Christophe,
    I understand this tutorial is pretty old, but is there a chance that the sample app as referenced here:

    can be fixed to see it in all its glory?

  69. Rajesh March 1, 2014 at 6:21 am #


    I’m looking forward to develop bootstrap mobile application in Visual studio with SQL as backend.

    Is it possible to develop on Visual Studio IDE.

    Please write me back ASAP. I’m waiting for your response.

    I want more info on this..

    Thank You.

  70. Josh Bedo March 7, 2014 at 5:46 pm #

    Doesn’t it worry you that your exposing everything globally on the window object? If you have any methods that send data and return data then it’s open to anyone who feels like looking for it. Opening you up to many security invulnerabilities like script injection, someone could insert whatever code they want to execute into your view and then run a method that saves data.

    – Josh

  71. Android Games April 19, 2014 at 10:52 am #

    I read this paragraph fully on the topic of the comparison of hottest
    and previous technologies, it’s amazing article.

  72. I am a engineer and I have just come up with a innovative online dating internet site.
    I will be looking out for ‘beta’ evaluators to search and try it out.

    Do you wish to opt in? We are able to pay you.

  73. May 12, 2014 at 6:25 pm #

    C’est bizɑrre je pensais justement faire un petit article similaire à celui là

  74. forum May 19, 2014 at 8:08 am #

    I’m not sure why but this web site is loading very slow for me.

    Is anyone else having this problem or is it a problem
    on my end? I’ll check back later and see if the problem still exists.

  75. Lora May 21, 2014 at 7:16 pm #

    Hi to all, the contents existing at this web site are actually amazing forr people knowledge, well, kesep up the good work fellows.

  76. oferte cazare mamaia 2014 June 5, 2014 at 7:36 am #

    Awesome blog! Is your theme custom made or did you download it from
    somewhere? A theme like yours with a few simple tweeks would really make my blog stand out.
    Please let me know where you got your theme. Cheers

  77. vikash kumar June 16, 2014 at 9:15 pm #

    I Love your all post. very-very nice post. Thank you so much.

  78. ทัวร์เกาหลี June 20, 2014 at 10:57 pm #

    Hey I know this is off topic but I was wondering if you
    knew of any widgets I could add to my blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience
    with something like this. Please let me know if you run into anything.
    I truly enjoy reading your blog and I look forward to your new updates.

  79. Instant VPS Servers June 25, 2014 at 2:30 pm #

    I’m keen on the precious information a person give the articles you write. We’ll take a note of ones site and appearance one more time the following usually. I’m relatively specific I am advised numerous new stuff the following! All the best for the next!

  80. ทัวร์สิงคโปร์ June 27, 2014 at 11:35 am #

    It’s genuinely very complicated in this busy life to listen news on Television,
    therefore I only use the web for that reason, and get the most up-to-date information.

  81. ipad repair in schaumburg June 30, 2014 at 6:19 am #

    I loved as much as you’ll receive carried out right here. The sketch
    is tasteful, your authored material stylish. nonetheless, you command get bought an impatience over that you wish be delivering the following.

    unwell unquestionably come more formerly again as exactly the same nearly very often inside case you shield this

  82. ipad repair in schaumburg July 9, 2014 at 7:48 pm #

    I was recommended this blog by my cousin. I’m not sure whether this post is written by him as no one else know such detailed about my
    trouble. You are amazing! Thanks!

  83. computer repair in schaumburg July 9, 2014 at 8:05 pm #

    Yesterday, while I was at work, my sister stole my apple ipad and
    tested to see if it can survive a twenty five foot drop,
    just so she can be a youtube sensation. My iPad is now destroyed and she has 83 views.
    I know this is entirely off topic but I had to share it with someone!

  84. Joe August 27, 2014 at 5:12 pm #

    Thanks for the info and link to GitHub.

  85. çelik raf April 27, 2015 at 6:11 pm #

    The view responsible for displaying

  86. futbol çorapları September 10, 2015 at 4:42 pm #

    I’d like to know how can I add this project to Eclipse

  87. çelik raf October 15, 2015 at 7:51 am #

    ı mean this work like many peaples

  88. forma imalatı November 16, 2015 at 3:55 am #

    Все качества продукции

  89. forma imalatı November 16, 2015 at 3:57 am #

    Everything quality production

  90. forma imalatı November 19, 2015 at 9:46 am #

    kalite,fiyat uygunlugu ve imalattan.profesyonel ekip eşliğinden güvenilir işler yapılmaktadır.

  91. futbol çorapları November 19, 2015 at 9:50 am #

    quality, reliable, cost-effectiveness and the associated jobs are done imalattan.profesyonel team.

  92. Superonline yalın İnternet December 19, 2015 at 12:27 pm #

    superonline Yalın internet kampanyası ile ev telefonunuzla bizi tercih ederseniz 24 ay boyunca sabit hat ücreti ödemezsiniz. Herhangi bir sabit hattın olmasa da Turkcell Superonline’dan superonline yalın internet hizmeti alabilirsin.

    Ev numaranı Turkcell Superoline’a taşıyarak telefon faturanda avantajlı tarifelerden yararlanabilirsin. Ayrıca 24 ay boyunca her yöne 100 dakika konuşma paketini de ücretsiz olarak kullanabilirsin. Taahhüt süresince aktivasyon, kurulum ücreti ve aboneliğiniz süresince modem ücreti ödemezsin.

  93. vodafone adsl December 19, 2015 at 12:51 pm #

    Vodafone ADSL ile internet ve sabit telefon hizmeti bir arada.
    Vodafone NET internet + Sabit Telefon + 3000 Dk Ücretsiz görüşme. 59,90 TL

    Vodafone ADSL ile diğer operatordeki taahhüt bedeliniz bizden. 120 TL kadarını vodafone net karşılıyor.

    Vodafon Net ile internetin keyfini çıkarın.

  94. Resim Kursu December 22, 2015 at 7:16 am #

    Türkiye’nin en kaliteli resim kursu olan Taksim Resim Kursu ile eğitimlerinizi alarak hayal ürünü eserlerinizi somutlaştırabilirsiniz.
    3 şubemiz ve onlarca atölyemiz ile eğitimlerimizi sanatsal bir ortamda üretmekle beraber yeni sanat eserleri üretebilecek bir ortam ile yeni ürünler ortaya çıkarmaktayız.
    Taksimdeki şubemizi Zafer GAZİOĞLU hocamız yönetmektedir. Asistanları eşliğinde eğitimleri yürütmektedir. Taksim Güzel Sanatlara Hazırlık konusunda eğitimlerimiz için sizleride bekliyoruz.

  95. vodafone fiber internet December 23, 2015 at 1:49 pm #

    Yeni yıla sayılı günler kala 2015 te vodafone ye geçmek isteyenler müşterilerimize özel indirimler ve ayrıcalıklar sizlerle. Vodafone fiber internet ile doyasıya internette gezinmek ve internet donmasına son verin. Üstün fiber alt yapısı ile Gbytlık verileri dklar içinde indirerek sizleri saatlerce bekletme derdine son veriyor.
    Evinizde telefon yoksa eğer vodafone yalın adsl ile sabit hat ücreti ödemeden interneti kullanabilmektesiniz. Bir çok avantajlı paketi internet sitemizde kulabilirsiniz.

  96. vodafone supernet December 24, 2015 at 10:07 am #

    Evinizdeki sabit telefonun masrafları çok oluyorsa ve önüne geçemiyorsanız üstelik birde internet masrafınız varsa derdiniz büyük !

    Vodafone adsl ile sabit telefonunuza ayda 3000 dakika hediye fırsatları ve vodafone internet ile 49.90 TL sabit fiyat garantisi versek nasıl olur ?
    Herkes konuşur biz yaparız vodafone ile anı yaşamak dileğiyle.

  97. resim kursu December 25, 2015 at 7:04 am #

    Tüm Hristiyan aleminin Noel bayramını kutlarız…
    Biz müslümanlar olarak her dile ve her inanca saygımız var ve islamın hoşgörü anlayışı sizi sarsın…

    Resim kursu ihtiyacınız varsa taksim resim kursu ile irtibata geçebilirsiniz. Sanatsal bir ortamda eğitiminizi tamamlamak için bizi tercih etmenizi öneriyoruz. Sizden aldığımız destek ile 3.şubemizden sonra 4. şubemizi açma düşüncemiz bulunmaktadır.

  98. vodafone adsl December 26, 2015 at 6:46 pm #

    Telefonlu evinize bir masrafta internetten çıksın istemiyorsanız telefon ücretiniz bizden olsun internet ise sizden ne dersiniz ?

    Vodafone adsl ile 3000 dakika telefon konuşması internetinize ek ücretsizdir ayrıca internet faturanıza ek bir masraf geleden.
    Siz neden bizi tercih etmeyesiniz ki ?

    Sizleri HOŞGELDİN 2016 kampanyası ile aramızda görmek , müşterilerimiz iseniz yeni seçenekler ile sizlerleyiz.

  99. Yeni yılın ilk şansını yakalamaya ne dersiniz ?
    Bakırköy Güzel Sanatlara hazırlık kursları adı altında verilen eğitimlerimizde %50 ye varan indirimli fiyatlar ile siz sanat aşığı bireylerin resim kursu muza gelebilmelerine vesile olmaktayız. Sizleri Eşsiz sanat eserleri ürettiğimiz atölyemizde görmek isteriz. Eserlerimizi incelemeniz ve sizlerinde sanata olan ilginizi bir çok kesime göstermenizi istiyoruz.

    Avcılar Metrobüs durağının hemen yanındaki atölyemize haftanın her günü gelebilirsiniz.

  100. Taksim Resim Kursu December 29, 2015 at 10:14 am #

    Sevdiklerimiz ile bir yılı daha iyisi ve kötüsüyle geride bırakmaya çok yakınız . Yeni yılın ilk şansını ayağınıza getiriyoruz. Taksim Resim Kursu ile resim kursu ihtiyacınızı eğitmenlerimizce inceleyerek en kaliteli eğitim modelimiz ile kişisel gelişiminizi tamamlamaya çalışmaktayız.

    Güzel Sanatlara Hazırlık Fakültelerine hazırlanmak istiyorsanız en ideal adrestesiniz çünkü Mimar Sinan Üniversite mezunlarından oluşmakta olan ekibimiz sizleri ideal yönlendirme ile geleceğe hazırlanmanıza vesile olacaktır.

  101. vodafone filbox tv December 30, 2015 at 9:37 am #

    Sinamayı evinize getirmeye ne dersiniz ? Vodafone filbox tv ile yüzlerce hd film ve belgesel size özel fırsatlarla …
    Tek yapmanız gereken web sitemizdeki formu doldurup sizi aramamızı veya bizi arayıp sizleri bilgilendirmemiz.
    Evdeki huzuru ve mutluluğu başka hiç bir yerde bulamıyorsanız sizin için evinizde bir sinamadan daha güzeli olamaz.
    Vodafone televizyonlu internet seçeneklerini inceleyerek dilediğiniz avantajlardan yararlanma fırsatını yakalayabilirsiniz.

  102. Taksim Resim Kursu December 30, 2015 at 1:35 pm #

    Taksim güzel sanatlara hazırlık kursu olarak eğitmenlerimiz sektörün en prestijli sanatçıları olmakla beraber kurumunuz güzel sanatlara hazırlık söz konusu olduğunda öğrencilerinin %100 başarı elde etmesi bir tesadüf değildir.

    Taksim Resim Kursu ile Güzel sanatlara hazırlık alanında kendinizi geliştirebilir. Düşlemiş olduğunuz sanat eserlerini somutlaştırarak kağıtlara , tablolara kısacası hayata sunabilirsiniz.

    3 şubemiz ile Türkiye geneline hizmet vermekle birlikte eğitmen kadromuz Mimar Sinan Güzel Sanatlar Fakültesinden mezun ve gören almaktadırlar.

    Sizde kalite arıyorsanız bunun içinse ayrıcalıklar istiyorsanız bizi tercih etmenizi öneririz…

  103. Taksim Resim Kursu December 31, 2015 at 11:21 am #

    31 Aralık 2015 yılın son günü ve yeni yıla başlangıç yapılacak bu günde 2016 yılının size, sevdiklerinize kısacası hepimize sağlık, mutluluk, huzur getirmesi dileğiyle HOŞ GELDİN 2016 diyerek mutluluğun bizi bulması , şansın bizlerle olması dileğiyle…

    Güzel sanatlara hazırlık alanında eğitimlerinizi almak için 2016 yılına özel fiyat seçenekleri ile sizleri atölyemizde görmek istiyoruz. Sanat alanına bakış ve kişisel gelişiminizi bizlerle geliştirmeye ne dersiniz.

    Taksim Resim Kursu ile sizler aramızda görmek istiyoruz…

  104. Güzel Sanatlara Hazırlık January 7, 2016 at 5:46 am #

    Sanat eserleri üretmek hiç bu kadar zevkli olmamıştı. Güzel sanatlara hazırlık konusunda eşsiz bir eğitim seçeneği sunan arkhesanat taksim resim kursu adı altında eğitim vermektedir.

    Kişisel gelişiminizi bizlerle tamamlamak istiyorsanız irtibata geçiniz.

  105. backlink ekle February 4, 2016 at 8:05 am #

    harika bir backlink ve firma ekle sitesi tavsiye ederiz.

  106. Antalya Airport Taxi February 16, 2016 at 4:21 pm #

    ntalya Airport Transfer to Hotels & private residences using a modern fleet of fully licensed & insured vans. We will take you from Antalya Airport to your destination and back in comfort and safety, at a low price and with great customer service.

    Transfers to/from Side, Belek, Antalya, Kemer, Alanya, Okurcalar, Konakli, Lara, Avsallar, Incekum, Mahmutlar, Kargicak, Finike, Gocek, Dalaman, Tekirova, Kas and Camyuva

  107. Quotes Giant March 7, 2016 at 2:56 am #

    Wow! This three part tutorial helped me a lot. Thanks for sharing your ideas. =)

  108. Salomon Chaussures March 10, 2016 at 3:11 am #

    while I was at work, my sister stole my apple ipad and
    tested to see if it can survive a twenty five foot drop,

  109. sonal March 21, 2016 at 11:39 pm #


    I tried running the code, as is but i am unable to do it. I am getting the followinf error

    jquery-2.1.3.min.js:4 XMLHttpRequest cannot load file:///C:/Users/sonkhare.PARTNERS/Desktop/api/wines. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

    Please help

  110. çelik raf March 28, 2016 at 6:24 am #

    The jQuery client below sends data to the server using JSON (addWine() and updateWine() methods

  111. attitude April 24, 2016 at 4:25 am #

    i thought it would be real tough but you made it quite easy, simple and interesting


  1. Backbone.js Wine Cellar Tutorial — Part 2: CRUD - December 7, 2011

    […] Part 1 of this tutorial, we set up the basic infrastructure for the Wine Cellar application. The […]

  2. Backbone.js Wine Cellar Tutorial — Part 1: Getting Started | Wine Bottle Covers - December 8, 2011

    […] here: Backbone.js Wine Cellar Tutorial — Part 1: Getting Started Share and […]

  3. Backbone.js Wine Cellar Tutorial — Part 1: Getting Started « lolososo - December 15, 2011

    […] Backbone.js Wine Cellar Tutorial — Part 1: Getting Started. Share this:TwitterFacebookLike this:LikeBe the first to like this post. […]

  4. Confluence: Mobile Devices Development - December 26, 2011



  5. Backbone.js Wine Cellar Tutorial — Part 3: Deep Linking and Application States - January 9, 2012

    […] Part 1 of this tutorial, we set up the basic infrastructure for the Wine Cellar application. In Part 2, we […]

  6. Using Backbone.js with a RESTful Java Back-End - January 10, 2012

    […] follow-up posts, “Backbone.js Wine Cellar Tutorial” (part1, part 2, part 3), I showed how to add structure to the client-side of the Wine Cellar application […]

  7. The LiveCycle Post | Using Backbone.js with a RESTful Java Back-End - January 17, 2012

    […] follow-up posts, “Backbone.js Wine Cellar Tutorial” (part1, part 2, part 3), I showed how to add structure to the client-side of the Wine Cellar application […]

  8. Javascript Resources[updated] « Blog - January 25, 2012

    […] Backbone.js Wine Cellar Tutorial […]

  9. Backbone.js Lessons Learned and Improved Sample App - January 30, 2012

    […] few weeks ago, I posted a three-part Backbone.js tutorial (part 1, part 2, part 3). Since then, I spent more time building a real-life application with Backbone. I […]

  10. Sample Application with Angular.JS - February 2, 2012

    […] I blogged a three-part Backbone.js tutorial (part 1, part 2, part 3), a number of people asked me to try Angular.js. So I decided to take it for a test […]

  11. Sample Mobile App with Backbone.js and PhoneGap - February 6, 2012

    […] recently blogged a tutorial (part 1, part 2, part 3, and postface) that takes you through the process of building a CRUD application […]

  12. Christophe Coenraets On Backbone.js And PhoneGap | Hire Flash Developers - February 7, 2012

    […] Adobe evangelist Christophe Coenraets recently posted a three part article on building a CRUD application using HTML and the Backbone.js framework. He […]

  13. Sample App with Backbone.js and Twitter Bootstrap - February 13, 2012

    […] you are new to Backbone.js, you may want to start with the tutorial (part 1, part 2, part 3, and postface) I blogged recently. “Backbone Directory” includes some […]

  14. Good Tutorials | Wesley Duff - February 14, 2012

    […] Backbone […]

  15. Robert McGhee » February 14th - February 14, 2012

    […] Bookmarked Backbone.js Wine Cellar Tutorial — Part 1: Getting Started […]

  16. Confluence: Front End Development Portal - February 16, 2012

    Javascript school…

    Javascript school This page is a resource for javascript development at TheLadders. It will host javascript content and examples for writing code at TheLadders. Conventions See Front End Coding Guideline Links Understanding “this” in javascript…

  17. A Spine.js with Handlebars.js JavaScript Tutorial | simple mind - February 29, 2012

    […] area they differ in is the number of tutorials. Backbone has many working native JavaScript tutorials. Spine’s are largely written in Coffeescript. While I appreciate […]

  18. Collection of Backbone.js tutorials | SpiderSoft Sydney developers - May 30, 2012

    […] time only short list of good backbone.js tutorials:Getting to Know Backbone.js – Nettuts+Backbone.js Wine Cellar TutorialHello Backbone.js Mac OS X Window ManagerLeave a Reply CancelYour Name *Your Email *Your […]

  19. Links June 10, 2012 » Metodiev Research - June 11, 2012

    […] Backbone.js tutorials […]

  20. jQuery Birthday Picker and others « William Jiang - June 29, 2012

    […] Sample App with Backbone.js and Twitter Bootstrap […]

  21. Backbone 介绍及学习资料索引 | Hugo Web前端开发 - July 7, 2012

    […] is your friends  作者很粗糙的翻译了下,还没翻译完整,建议看E文原版。Wine Cellar Tutorial   […]

  22. Algunas notas sobre Backbone JS | Kinetica Solutions Blogs - July 24, 2012

    […] Wine Cellar Tutorial: […]

  23. Backbone.js and Twitter Bootstrap tutorials - Adriel Blog | Adriel Blog - August 6, 2012

    […] […]

  24. Single-Page CRUD Application with Backbone.js and Twitter Bootstrap | Christophe Coenraets - November 16, 2012

    […] demonstrate these features, I decided to revisit my wine cellar application, which was in need of a serious UI […]

  25. Learn Backbone.js Completely | JavaScript is Sexy - January 14, 2013

    […] Read the entire tutorial at the link below and study and understand it carefully (but don’t try to build the app just yet): Backbone.js Wine Cellar Tutorial — Part 1: Getting Started […]

  26. Javascript Practice: Decided to include Node.js and MongoDB | by Alex Ionica - February 11, 2013

    […] – Christophe Coenraets […]

  27. Anonymous - February 12, 2013

    […] […]

  28. Part 6: Displaying Wildfires | - March 22, 2013

    […] […]

  29. Baby steps to Backbone.js: Exploring collections | Tu Ngoc Man - April 10, 2013

    […] Backbone.js Wine Cellar Tutorial […]

  30. How can I get Tweet Timeline with using Backbone.js? - How-To Video - April 20, 2013

    […] a beginner for Backbone.js. I’ve finished some…I want to create a non-tutorial app by myself and try to create simple app that display tweet […]

  31. Sample App with Backbone.js and Twitter Bootstrap | HTML CSS3 - June 28, 2013

    […] you are new to Backbone.js, you may want to start with the tutorial (part 1, part 2, part 3, and postface) I blogged recently. “Backbone Directory” includes some […]

  32. Backbone Example Sites with Tutorials | Hugo Mineiro Portfolio - July 21, 2013

    […] Part 1: Getting Started, Part 2: CRUD, Part 3: Deep Linking and Application […]

  33. Where to Learn backbone.js online | Learn Web Tutorials - October 7, 2013

    […] has a three-part tutorial on building an wine-cellar backbone app. […]

  34. Backbone, Django and Tastypie – view item is not populating view list | Technology & Programming Answers - November 1, 2013

    […] For reference, I’m trying to follow this tutorial: […]

  35. Week 0, Day 3 | - November 6, 2013

    […] quiet here. I’ve been helping Ava with her game and looking at some basic tutorials for Backbone and Angular. Then I got sidetracked into learning […]

  36. Render function of view is not working | Technology & Programming - November 11, 2013

    […] example is from this […]

  37. Getting started with Backbone.js | Anders Grendstadbakk - December 12, 2013

    […] Backbone tutorial by Christophe Coenraets […]

  38. In One Post: Backbone.js | Day of the Duck - April 18, 2014

    […] and turning it into a single-page-application with history management. Sure, I will use tutorials for my investigation and I may spend hours pouring over the documentation, but let’s face it: […]

  39. How to hoop a demonstrate router slight outcome in BackBone.js controlling ajax - Abram - September 10, 2014

    […] This should work for you. A good educational array we found when removing started was […]

  40. backbone.js | mauroprogram's Blog - February 18, 2015

    […] […]

  41. Материалы для изучения backbone.js « Blog — organiser - April 30, 2015

    […] Backbone.js Wine Cellar Tutorial — Part 1: Getting Started […]

  42. » Libraries - @ fake's - July 14, 2015

    […] Backbone.js in particular could use some work, though.. The documentation is rather poor, to be honest – it details the functionality of the library but doesn’t actually show you how you’re supposed to build with it. Instead, the creators just link to various projects built with it. This has the sad consequence of you finding better documentation about the library in a three-part blog post than on the page of the library itself. Specifically, I’ve based my new project off of the blogging by Christophe Coenraets about a wine celler project. […]

Leave a Reply