The most important thing about routes: Routes are matched in the order they are added. Reversing the order of your routes was correct, but the problem is that your route admin/author
also matches admin/author{/action}
. What you could do: make the controller and action mandatory:
// Does not match admin/author/add
Route::set('admin/author', 'admin/author/<controller>/<action>(/<id>)')
->defaults(array(
'directory' => 'admin/author',
));
Route::set('admin', 'admin(/<controller>(/<action>(/<id>)))')
->defaults(array(
'directory' => 'admin',
'controller' => 'Main',
'action' => 'index',
));
There are several approaches, another one would be to create a "whitelist" of controllers:
// Does not match admin/author/add
Route::set('admin/author', 'admin/author/<controller>(/<action>(/<id>))',
array(
'controller' => '(book|another-controller)'
))
->defaults(array(
'directory' => 'admin/author',
));
Route::set('admin', 'admin(/<controller>(/<action>(/<id>)))')
->defaults(array(
'directory' => 'admin',
'controller' => 'Main',
'action' => 'index',
));