First steps - llorsat/wonkajs GitHub Wiki

Install

Wonka.js is not a backend framework, but has been built with their help so you need to install node.js and npm to make it works.

Follow these instructions to install node.js and npm on your OS

Also you'll need to install git

Now that you have installed node.js and git, just have to install wonka.js, on your console write:

$ sudo npm install -g wonkajs

At the end, verify that wonka has been installed successfuly:

$ wonkajs --version

This command must return the version number 1.6.0.

Create new project

The first step is create a project, to help you understand how does wonka works, write on your console:

$ wonkajs project library

With this will be created a new folder called library on your current path, with the next files structure:

library:
  core/
  icons/
  stylesheets/
  libraries/
  root/
  manifest.webapp
  package.json
  index.hbs

Run server

To run the project, just do:

$ wonkajs server

Now, visit your project on the next url:

http://localhost:9300

If for any reason, the port 9300 is unavailable, you can choose another port:

$ wonkajs server 9700

In this case, visit your project on:

http://localhost:9700

Create application

An application or app is a section inside your project, for example, if you are making a project about library, you could define the applications:

  • users
  • books

For the case of our library, we'll create an application called books with next command:

$ wonkajs app books

Now we've created the application and our project has a new folder with the next file structure:

books:
  templates/
    main.hbs
  models.js
  collections.js
  views.js
  router.js
  init.js

Now refresh and go to:

http://localhost:9300/#books

How it works?, let's explain.

When you go to http://localhost:9300/#books, this url calls the route "books" defined on router.js, this route execute the method "main" inside router.js too, this method loads the view "Main", defined inside views.js and this view draw on the browser the content from the template main.hbs.

This flow is repetead for each application created on your project.

If you want to add another url on this application, you could do it. First defining on router.js the url and a function that will be invoked by this url:

router.js

(function(namespace) {

  var views = namespace.views;

  var Router = Backbone.Router.extend({
    
    routes: {
      'books': 'main',
      //Here define the route and the method name to invoke:
      'books/science': 'science'
    },

    main: function() {
      App.loadingBar.show();
      new views.Main({
        el: $('#container')
      });
    },
    
    //Here your method:
    science: function() {
      //We show a progress bar to indicate that our web project is loading
      App.loadingBar.show();
      new views.Science({
        //By default the views must load on the #container selector, unless the view acts as subview
        el: $('#container')
      });
    }

  });

  new Router();

})(books);

views.js

We've defined the route and function, now we have to write the view, so we open views.js file and update as follow:

(function(namespace) {

  var views = namespace.views;
  var collections = namespace.collections;
  var models = namespace.models;

  var getTemplate = function(name) {
    return hbs.compile($('#books-' + name + '-template').html());
  }

  views.Main = Bb.View.extend({
    template: getTemplate('main'),
    initialize: function() {
      var me = this;
      me.render();
    },
    render: function() {
      var me = this;
      me.$el.html(me.template());
      App.loadingBar.set(100);
      App.loadingBar.changed(App.loadingBar.hide);
      return me;
    }
  });

  //Here the new view
  views.Science = Bb.View.extend({
    //Set the template to use
    template: getTemplate('science'),
    initialize: function() {
      var me = this;
      me.render();
    },
    render: function() {
      var me = this;
      //Here fill the container with template content
      me.$el.html(me.template({}));
      //When our view has loaded, let's hide the progress bar
      App.loadingBar.set(100);
      App.loadingBar.changed(App.loadingBar.hide);
      return me;
    }
  });

})(books);

templates/

Our view is ready, but we have to write the template, so let's create a new file on the templates folder called science.hbs.

<script type="text/x-handlebars" id="books-science-template">
  <!-- Our project will be localizable, so we'll use the handlebars helper __ -->
  <h1>{{ __ "Science books" }}</h1>
  <h2>{{ __ "This is the section for science books" }}</h2>
</script>

Now we've finished everything to make our new route works and draw the template content inside the main container, just run the server and load http://localhost:9300/#books/science.

collections.js

Now we'll modify the template that is draw when the url http://localhost:9300/#books loads, let's add the feature to add a book inside a books list.

Let's declare our collection on books/collections.js:

(function(namespace) {

  var models = namespace.models;
  var collections = namespace.collections;

  //TODO: Add collections below
  collections.Books = Bb.Collection.extend({
    model: models.Book
  });

})(books);

models.js

Let's define the model, that is the kind of objetcts that our collection will contain.

(function(namespace) {

  var models = namespace.models;

  //TODO: Add models below
  models.Book = Bb.Model.extend({});

})(books);

Now, let's make a modifications to the "Main" view on books/views.js:

(function(namespace) {

  var views = namespace.views;
  var collections = namespace.collections;
  var models = namespace.models;

  //ENTER key constant
  var ENTER = 13;

  var getTemplate = function(name) {
    return hbs.compile($('#books-' + name + '-template').html());
  }

  views.Main = Bb.View.extend({
    template: getTemplate('main'),
    //Here we define the event when the keys are pressed inside the #book selector
    events: {
      'keypress #book': 'onAddBook',
    },
    initialize: function() {
      var me = this;
      me.collection = new collections.Books();
      me.render();
    },
    render: function() {
      var me = this;
      me.$el.html(me.template());
      App.loadingBar.set(100);
      App.loadingBar.changed(App.loadingBar.hide);
      return me;
    },
    //Here our method when the keypress event is launched
    onAddBook: function(e) {
      e.preventDefault();
      e.stopPropagation();
      var me = this;
      var target = me.$(e.currentTarget)
      if (target.val() != '' && e.keyCode == ENTER) {
        //We add a new object to our collection
        me.collection.add({name: target.val()});
        //We clean the text field
        target.val('');
        //We generate the results view, we set when this view will draw their content and the books list.
        new views.Result({
          el: me.$('#result'),
          collection: me.collection
        });
      }
    }
  });

  views.Result = Bb.View.extend({
    template: getTemplate('result'),
    initialize: function() {
      var me = this;
      me.render();
    },
    render: function() {
      var me = this;
      me.$el.html(me.template({
        books: me.collection.toJSON()
      }));
      return me;
    }
  });

})(books);

On this file we are calling the result template, so let's create the file books/templates/result.hbs.

<script type="text/x-handlebars" id="books-result-template">
  <ul>
  {{# each books }}
    <li>{{ name }}</li>
  {{/ each }}
  </ul>
</script>

And finally, we modify the template books/templates/main.hbs as follow:

<script type="text/x-handlebars-template" id="books-main-template">
  <div class="container">
    <input type="text" id="book">
  </div>
  <div id="result" class="container"></div>
</script>

Now load the url http://localhost:9300/#books, type a book name and then press ENTER, this name must be added to the books list below and the textfield must be cleared.

For more information

⚠️ **GitHub.com Fallback** ⚠️