Reputation: 7056
I'm using Cakephp 2+ and I have a model called 'posts', and posts can be different types, for example - blog post, message, etc.
In config/routes.php, How do I set up my routing so that I have /posts/12/post-title
or /blog/14/blog-title
?
At the moment I have this:
Router::connect('/:type/add', array('controller' => 'posts', 'action' => 'add'),
array('pass' => array('type')));
Router::connect('/:type/:action', array('controller' => 'posts'),
array('pass' => array('type')));
# Custom posts router
Router::connect('/:type/:id/:slug',
array('controller' => 'posts', 'action' => 'view'),
array('pass' => array('type', 'id', 'slug'), 'id' => '[0-9]+'));
But the problem is that this is then used for every URL, so cakephp thinks that my user profile page should look at my posts controller because it think's i'm passing in a :type -
...
#View Profile
Router::connect('/profile/:id', array('controller' => 'users', 'action' => 'view'),
array('pass' => array('id'), 'id' => '[0-9]+'));
Does anyone know the means of doing this properly? Many thanks
Upvotes: 1
Views: 1493
Reputation: 29037
First of all, the order of your routes matter, if multiple routes will match an URL, the first matching route will be handled
Next, you can limit 'what' will be considered a 'type' by setting a regular expression for the 'type' key in the last argument of Router::connect(), just as you did for 'id'. You might be able to either include all valid types in the regular expression, or add a 'negative' part to the regular expression that excludes values, e.g. Controller names
Something like this:
Router::connect(
'/:type/:action',
array(
'controller' => 'posts',
),
array(
/**
* Custom type:
* only allow 'post', 'blog' or 'message' as type here
* to prevent overlapping with 'controllers'
*/
'type' => '(post|blog|message)',
// Define what should be passed to the 'view' action as arguments
'pass' => array('type'),
/**
* Optionally, define what parameters should be automatically preserved
* when creating URLs/links
*/
'persist' => array('type'),
)
);
Router::connect(
'/:type/:id/:slug',
array(
'controller' => 'posts',
'action' => 'view',
),
array(
/**
* Custom type:
* only allow 'post', 'blog' or 'message' as type here
* to prevent overlapping with 'controllers'
*/
'type' => '(post|blog|message)',
'id' => '[0-9]+',
// Define what should be passed to the 'view' action as arguments
'pass' => array('type', 'id', 'slug'),
/**
* Optionally, define what parameters should be automatically preserved
* when creating URLs/links
*/
'persist' => array('type'),
)
);
Upvotes: 1