Skip to content
millermedeiros edited this page Dec 5, 2011 · 17 revisions

Read the documentation for a detailed explanation of available methods and features.

Basic usage

crossroads.addRoute('/news/{id}', function(id){
  console.log(id);
});
crossroads.parse('/news/123'); //will match '/news/{id}' route passing 123 as param

Optional parameters

Optional segments are very useful since they can drastically reduce the amount of routes required to describe the whole application.

//{id} is required, :date: is optional
crossroads.addRoute('/news/{id}/:date:', function(id, date){
  console.log(id +' - '+ date);
});
crossroads.parse('/news/123'); //match route and pass "123" as param
crossroads.parse('/news/45/2011-09-31'); //match route passing "45" and "2011-09-31" as param

RegExp route

//capturing groups are passed as parameters to listeners
crossroads.addRoute(/^news\/([0-9]+)$/, function(id){
  console.log(id);
});
crossroads.parse('/news/123'); //will match route passing "123" as param
crossroads.parse('/news/qwerty'); //won't match route

Store route reference and attach mutiple listeners

var articleRoute = crossroads.addRoute('/article/{category}/{name}');
articleRoute.matched.add(function(category, name){
  console.log(category);
});
articleRoute.matched.add(function(category, name){
  console.log(name);
});
 //will match articleRoute passing "lol_catz" and "keyboard_cat" as param
crossroads.parse('/article/lol_catz/keyboard_cat');

Use RegExp to validate params

var specialNews = crossroads.addRoute('/news/{id}');
specialNews.matched.add(function(id){
  console.log(id);
});
specialNews.rules = {
  id : /[0-9]+/ //match only numeric ids
};
crossroads.parse('/news/asd'); //won't match since ID isn't numeric
crossroads.parse('/news/5'); //will match `specialNews` and pass "5" as param to all listeners

Use functions to validate params

This feature is very useful and gives a lot of flexibility on the validation.

var specialNews = crossroads.addRoute('/news/{category}/{id}');
specialNews.matched.add(function(id){
  console.log(id);
});
specialNews.rules = {
  //function should return a boolean value
  id : function(val, request, values){
    return val !== 'foo' && values.category !== 'bar';
  }
};
crossroads.parse('/news/world/asd'); //will match
crossroads.parse('/news/bar/5'); //won't match

Use arrays to validate params

var specialNews = crossroads.addRoute('/news/{id}');
specialNews.matched.add(function(id){
  console.log(id);
});
specialNews.rules = {
  //segments are treated as strings unless `crossroads.shouldTypecast = true` (default = false)
  id : ['asd', '5', '123', '23456', 'qwerty']
};
crossroads.parse('/news/asd'); //will match
crossroads.parse('/news/5'); //will match
crossroads.parse('/news/loremipsum'); //won't match

Validate whole request

var specialNews = crossroads.addRoute('/news/{id}');
specialNews.matched.add(function(id){
  console.log(id);
});
specialNews.rules = {
  //request_ will accept any kind of validation rule (function, array, RegExp)
  request_ : ['/news/asd', '/news/5']
};
crossroads.parse('/news/asd'); //will match
crossroads.parse('/news/5'); //will match
crossroads.parse('/news/loremipsum'); //won't match

Normalize parameters & add default parameters

This feature is very powerful and can simplify a lot the logic of you application, it makes it easy to create multiple alias to the same route (see #21) and to set default parameters to the matched signal.

function onSectionMatch(sectionId, subId){
    console.log(sectionId +' - '+ subId);
}

var newsRoute = crossroads.addRoute('/news/{date}/{id}', onSectionMatch);
newsRoute.rules = {
  normalize_ : function(request, vals){
      //return parameters that should be passed to matched signal listeners
      return ['editorial', vals.id];
  }
};
crossroads.parse('/news/2011-08-32/123'); //will log "editorial - 123"

If you are using crossroads to route nodejs requests you can use the normalizeFn to pass request and response objects to your route handlers:

var http = require('http'),
    url = require('url'),
    crossroads = require('crossroads');

http.createServer(function (req, res) {
  crossroads.normalizeFn = function(str, vals){
    // handlers will receive request as 1st param, response as 2n and an object with all captured
    // parameters as 3rd argument.
    return [req, res, vals];
  };
  crossroads.parse( url.parse(req.url).pathname );
}).listen(1337, "127.0.0.1");

Typecast parameters

crossroads.addRoute('/foo/{val}', function(val){
    console.log(typeof val);
});

crossroads.shouldTypecast = false; //default = false
crossroads.parse('/foo/false'); //log "string"
crossroads.parse('/foo/true'); //log "string"
crossroads.parse('/foo/123'); //log "string"
crossroads.parse('/foo/abc'); //log "string"

crossroads.shouldTypecast = true; //default = false
crossroads.parse('/foo/false'); //log "boolean"
crossroads.parse('/foo/true'); //log "boolean"
crossroads.parse('/foo/123'); //log "number"
crossroads.parse('/foo/abc'); //log "string"

Check if route match a string

var myRoute = crossroads.addRoute('/foo/{id}');
console.log( myRoute.match('/foo/bar') ); //true

Dispose route

var myRoute = crossroads.addRoute('/foo/{id}');
myRoute.dispose(); //remove route from crossroads and also remove all listeners from route.matched

Create a new Router instance

You can create multiple Routers if needed. The new instance will work exactly like the crossroads object and it is totally independent.

   var sectionRouter = crossroads.create();
   sectionRouter.addRoute('/foo');
   console.log( sectionRouter.getNumRoutes() ); // 1

Validate RegExp route capturing groups

You can also validate each capturing group (the same way you do with the normal segments):

var awesomeRoute = crossroads.addRoute(/^(\w+)\/(\w+)$/, function(a, b){
  console.log(a +' - '+ b);
});
awesomeRoute.rules = {
  //keys match index of capturing groups
  '0' : ['asd', 'qwe', 'zxc'];
  '1' : function(val, request, values){
    if(values[0] == 'asd' && val == '123'){
      return false
    } else {
      return true;
    }
  }
};
crossroads.parse('asd/123'); //wont match
crossroads.parse('asd/456'); //match

Execute an action every time crossroads matches any route

Useful for tracking, debugging and any other action that may need to happen every time the app changes the current route.

//log all routes
crossroads.routed.add(console.log, console);

Execute an action every time crossroads can't match any route

Useful for tracking, debugging or handling errors.

//log all requests that were bypassed
crossroads.bypassed.add(console.log, console);

Set Route priority

Routes with higher priority will be tested before. Routes are tested by order of creation if priority is omitted. The default priority is 0.

crossroads.addRoute('/lorem');
crossroads.addRoute('/{foo}', null, 5);
crossroads.addRoute('/{bar}');
crossroads.parse('/lorem'); //will match second route since it has higher priority

Chaining

Some people loves chaining... if that's your thing, crossroads API can be chained till a certain extent, use it with care, code may become harder to read:

crossroads
    .addRoute('{section}', loadSection)
    .rules = {
        section : ['home', 'login', 'contact']
    };

More Examples

For more examples check the unit tests.

Clone this wiki locally