Tim
Tim

Reputation: 7056

cakephp routing for multiple post types

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

Answers (1)

thaJeztah
thaJeztah

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

Related Questions