Skip to content
tmcw edited this page Oct 17, 2011 · 9 revisions

This documentation may not be up to date with bones releases

  • Install node 0.4.x and npm 1.x
  • Create a package.json file by typing npm init
  • Add bones as a dependency (or clone it to ./node_modules/bones for development)
  • In your index.js file, add:
#!/usr/bin/env node
require('bones').load(__dirname);

if (!module.parent) {
    require('bones').start();
}

Application layout

Bones expect you to organize your application in a certain way, and treats a few directories in special ways.

  • /models – Backbone models

  • /views – Backbone views

  • /routers - Backbone routers

  • /controllers – Backbone controllers

  • /templates – Templates

  • /commands – CLI commands

  • /servers – Servers and Middleware

    mkdir {models,views,routers,controllers,templates,commands,servers}

With the exception of /templates/, these directories will be populated with .bones files. These files have a couple of variables predefined that you can just use, otherwise they are regular files containing JavaScript code. This allows Bones to easily send the same file to the client as well..

Files in each of these directories are expected to provide a single model/view/controller/template etc. The file should be named as the class is name, capitalization is important! A BlogPost model should be defined in a BlogPost.bones file.

See https://github.com/developmentseed/bones/tree/master/examples/simple for an example app using that layout.

Creating a server

Servers can be used to add both middleware and/or routes to an existing server instance or to create new server instances. Servers that will bind to a port number are called root-level servers.

To create a server named Main, add a file named Main.bones to the servers directory containing server = Bones.Server.extend(). Each Bones application can have multiple servers. You can view all predefined variables available in a servers/*.bones file, by looking at the prefix header for that file type.

In a .bones file, you have to assign the objects you create to a variable named server/model/view/controller, corresponding to the type of the object. This variable is automatically exported and made available to other .bones files.

The Core server will automatically add all models/views/controllers/templates defined in your application or any of the child plugins it uses. If you only want to have a certain subset of models/views/controllers associated with a particular server or if you want to pass additional configuration options, you have to redefine the initialize method:

server = Bones.Server.extend({
    initialize: function() {
        controllers['Home'].register(this);
        templates['Home'].register(this);
        views['Home'].register(this);
    }
});

To mount a server as additional middleware, use:

servers['Middleware'].augment({
    initialize: function(parent, plugin) {
        parent.call(this, plugin);
        this.use(new servers['Auth']({
            secret: plugin.config.secret
        }));
    }
});

The .augment method is an easy way to override an existing function on an object. Defining it works very similar to using Backbone's .extend, except that the first parameter is the previous function of that name. .augment also concatenates arrays and clones/extends hashes.

Starting the server

After making your index.js file executable, just run the file. The core server should be available at http://localhost:3000. However, since you haven't added any other files yet, most paths will return a 404 page.

Adding a router

Unlike Ruby on Rails, Backbone application typically have just one controller that contains all the routes for the application. Start by creating a file named Default.bones in your module's routers directory:

router = Backbone.Router.extend({
    routes: {
        '/': 'home'
    },

    home: function() {
        // This code is executed on the client.
        // Do nothing.
    }
});

You can override the home function to send page content or do other actions within a Default.server.bones file.

routers['Default'] = routers['Default'].extend({
    home: function() {
        this.res.send('hello world');
    }
});

When you restart your server, and go to http://localhost:3000, you should see the return message of the controller. When running on the server, the this context of a controller callback contains req and req. To determine whether you're on the server or on the client, you can use Bones.server.

NOTE: All code in *.bones files are sent to client, so make sure you don't have critical information in them. For code that is strictly server side, you can create files named *.server.bones. Those files will never be sent to the client and are only executed on the server, in addition to the regular file if it exists.

Route Precedence

Routes are ordered by:

  1. When their Server is included. Servers are typically included manually from the Core.bones server.
  2. When their router is included. Routers are included automatically in alphabetical order.
  3. When the route is defined. The object of { '/route': 'route' } mappings keeps its order, with routes at the beginning tested first.