# Routes Configuration

## Defining and Accessing the Routes

The route configuration can be specified during the bootstrap process via the `routes` configuration option:

    function MyRouter () {
      var self = fw.router.boot({
        namespace: 'Router',
        routes: [
          {
            path: '/',
            controller: function () { /* ... */ }
          },
          {
            path: '/dashboard',
            controller: function () { /* ... */ }
          }
        ]
      });
    }

The routes are also accessible at the observable array `router.routes` after being bootrapped as well:

    function MyRouter () {
      var self = fw.router.boot({
        namespace: 'Router'
      });

      self.routes([
        {
          path: '/',
          controller: function () { /* ... */ }
        },
        {
          path: '/dashboard',
          controller: function () { /* ... */ }
        }
      ]);
    }

Since the routes property is an observable array you can do things like:

- Add a route by pushing it onto the array:

      self.routes.push({
        path: '/news',
        controller: function () { /* ... */ }
      });

- Remove a route by removing it from the array:

      var newsRoute = {
        path: '/news',
        controller: function () { /* ... */ }
      };

      self.routes.push(newsRoute);
      // ...
      self.routes.remove(newsRoute);

- Listen for and respond to changes to the routes:

      self.routes.subscribe(function (routesList) {
        console.info('Routes changed, they are now:', routesList);
      });

See observable arrays for full information on all operations available.

## Configuration Options

When specifying an individual route, you can pass along several options:

    {
      path: /* see below */,
      name: /* see below */,
      title: /* see below */,
      controller: /* see below */,
      predicate: /* see below */
    }

- path (string | array)
- name (string)
- title (string | callback)
- controller (callback)
- predicate (callback)

Callback Context

All callback functions execute with the context of the `router` instance.

### path (string | array)

It is the string which is used to match against the url. Routes are matched according to the pattern you provide in the route string.

There are a few available patterns you can define in your route string:

#### Static Routes

This is an explicitly defined path:

    path: '/path/for/route'

This is a simple explicitly defined route that will match when the browser navigates to `/path/for/route`.

#### Required Parameter

This is a path with a required parameter:

    path: '/user/:id'

This route will match anything that starts with `/user/` followed by something after, such as '/user/123'.

#### Optional Parameter

This is a path with an optional parameter:

    path: '/books(/:isbn)'

This route will match anything that starts with `/books` and optionally followed by something after, such as '/books' and '/books/123'.

Path Array

Note that you can provide a list of paths for a route by supplying them with an array:

    path: ['/path/for/route', '/other/path/for/route']

All supplied route strings will be matched against when determining if a route matches a url.

#### Route Splat

A splat is a pattern which will match anything:

    path: '/settings*details'

This route will match anything that starts with `/settings` and ends with `details`, such as '/settings/history/details' and '/settings/profile/details'.

### name (string)

Routes can also be addressed via a name. To define one for a route you do so with the `name:` parameter:

    name: 'user-profile'

For information on how to trigger via a named route, see Explicit Named Routing below.

### title (string | callback)

If provided, this will set the title on the document after the route has been triggered.

#### Title String

    title: 'Home Page'

#### Title Callback

If you provide a callback function, it will be evaluated each time the route is triggered:

    title: function () {
      if(this.currentState() === '/profile') {
        return 'My Profile Page';
      }
      return 'Acme Corp';
    }

### controller (callback)

The callback evaluator which is run each time the route is triggered. This is the callback which is typically used to manipulate any outlets as a result of the route being triggerd (such as a page change manipulating the main content area).

It is passed an object containing any parameters expressed by the current route.

    path: '/user/:id',
    controller: function (params) {
      console.info('user id', params.id);
    }

The controller is where you will generally do any outlet changes. Since the context of the controller callback is the router instance itself, you can access it via `this.outlet`:

    path: '/news',
    controller: function (params) {
      this.outlet('main', 'news');
    }

For more information on outlets, see the outlet documentation.

### predicate (callback)

If provided this callback will evaluated prior to a route change, its result (true/false) will determine whether or not the route controller is triggered. When being called it is provided the current state being changed to:

    predicate: function (url) {
      if (url.match(/^\/profile/) && !loggedIn) {
        return false; // do not trigger controller
      }
      return true; // trigger controller, route to page
    }

Router Predicate

Remember that the router configuration also has an option for a `predicate` callback. If provided, either/both callbacks will be evaluated and both must return true for the route to be triggered.