There's nothing particular exotic about the routes you're trying to build. Without a description of exactly how your routes/dispatches are breaking, it's hard to identify any esoteric routing behaviours you might be running into (and believe me, there are some).
Before getting to specifics, I will recommend strongly that you always use reverse-routing to build your URLs (ie. $html->url(array('controller'=>'homes','action'=>'index'));
instead of $html->url('/homes/index')
. It's a small performance hit that will eventually save you from some massive headaches.
Let's run through your example routes, and I'll try to explain how to build a matching URL in your views, and highlight potential issues you're running into.
Router::connect('/:filter/h/:id', array('controller'=>'homes','action'=>'view'));
You would build a URL in your view with the following reverse-route:
$html->url( array(
'controller'=>'homes','action'=>'view',
'id'=>$some_id,'filter'=>$some_filter
));
Note that I've passed in 'id'
and 'filter'
keys, instead of just passing the corresponding variables. This is because Cake treats reverse-route parameters without keys in order. So if you called:
$some_filter = 'foobar';
$some_id = 1234;
$html->url( array('controller'=>'homes','action'=>'view',$some_id,$some_filter));
You'd end up with this URL:
/1234/h/foobar
Which is backwards.
The other issue you may be running into is how this route gets dispatched to a controller action. By default, Cake will pass all parameters of the route request in the order they appear in the route definition, unless instructed otherwise. So, with the route above, Cake would call:
HomesController::view( $filter, $id );
If you want the first parameter to HomesController::view
to be $id
, you will need to specify such in the route definition:
// This route definition...
Router::connect(
'/:filter/h/:id',
array( 'controller'=>'homes', 'action'=>'view' ),
array(
'pass' => array( 'id', 'filter' )
)
);
// ...invokes the controller action:
// HomesController::view( $id, $filter );
The 'pass'
element of the third array parameter to Router::connect
tells Cake which route parameters, and in what order, to pass to the controller action. You could remove 'filter'
from the array, and Cake would invoke the action thus:
HomesController::view( $id );
In this case, Cake still captures $filter
and makes it available to the controller, as an element of the Controller::params
property. You could access its value by addressing $this->params['filter']
.
The second route you provided is:
Router::connect('/admin/:controller/:action/:id');
For admin routing, you don't actually need to define specific routes preceded by 'admin'
. You only need to turn on admin routing. In your /app/config/core.php
, look for and uncomment the line:
Configure::write('Routing.admin', 'admin');
This allows you to define a set of actions with the admin_
prefix (e.g. admin_edit
, admin_publish
, etc.), which are dispatched-to by a URL like /admin/homes/edit/1234
. In your views, you would structure your reverse-routes like so:
$html->url( array(
'controller'=>'homes','action'=>'edit',1234
'admin'=>true
));
Note the 'admin'=>true
part, which informs Cake you're requesting an admin-prefixed route.