1

I am using a PagesController (not the same that Cake has built in) and I would like to connect a new route:

Router::connect('/*', array('controller' => 'pages', 'action' => 'view'));

I really want Cake to ONLY use this route if all other (default) routes fail. However, I can't seem to get it to work with just routes. I have a hunch that I will need to use a custom CakeRoute class, but I have absolutely no idea how to get it to do what I want it to do.

Could somebody please help me with this?

[edit] Oh and it might be useful to know that I'm using CakePHP 2.2.0

[2nd edit] On request, a little more info. My router currently looks like this:

Router::connect('/', array('controller' => 'pages', 'action' => 'index'));
CakePlugin::routes();
require CAKE . 'Config' . DS . 'routes.php';
Router::connect('/*', array('controller' => 'pages', 'action' => 'view'));

And when I go to /home/about I get "Error: HomeController could not be found." I also tried this:

Router::connect('/', array('controller' => 'pages', 'action' => 'index'));
CakePlugin::routes();
Router::connect('/*', array('controller' => 'pages', 'action' => 'view'));
require CAKE . 'Config' . DS . 'routes.php';

But then EVERYTHING is routed to my pages controller and I don't want that. I only want that route to be used if all other routes fail.

Again, I have a hunch that this can only be done with a custom CakeRoute class, but I have no idea how exactly.

Evert
  • 2,022
  • 1
  • 20
  • 29

2 Answers2

1

try to put your general route at the end but before the CakePlugin::routes(); line. Something like this:

Router::connect('/', array('controller' => 'pages', 'action' => 'index'));
//all your routes
Router::connect('/*', array('controller' => 'pages', 'action' => 'view'));

CakePlugin::routes();
require CAKE . 'Config' . DS . 'routes.php';

hope this helps

EDITED: I have a website with the same principle.. and I used this route

Router::connect('/:slug', array('controller' => 'users', 'action' => 'view'),array('pass'=>array('slug'),'slug'=>"[a-z0-9\-]+"));

at the end (before CakePlugin::routes()) and its working fine for me.

pleasedontbelong
  • 19,542
  • 12
  • 53
  • 77
  • I already tried that, but then everything is routed to my pages/view, while I only want the URLs that fail to route to route to my pages/view – Evert Jul 13 '12 at 18:19
  • maybe the problem is the `*`... have you tried passing a variable? i edited my answer with an example of one of my websites – pleasedontbelong Jul 13 '12 at 21:39
  • For me that only works with URLs that have only one word. When I do /home it works, but when I try to get a subpage, for example /home/about then it doesn't work anymore. – Evert Jul 13 '12 at 22:06
  • hmm maybe adding `/**` route after the one I gave you, check this http://book.cakephp.org/2.0/en/development/routing.html#connecting-routes – pleasedontbelong Jul 13 '12 at 22:25
  • Then I get the same problem as before, the route is used for every URL instead of just for the URLs that fail to route which is what I really want. – Evert Jul 13 '12 at 23:03
1

I know this is an old post, but for anyone struggling with catch-all routing in Cake, here's the skinny:

When you create a catch-all route such as /* then you're allowing that definition to grab anything and everything in the URL. It's very greedy, in other words. As far as I can tell, there's no way to enable this kind of definition conditionally. This means if the URL does not match any route definition before the /* is defined, then the /* definition will pick it up. So always define catch-all routes last, which we already know, of course :-)

Now, in order to ensure that Cake continues to operate "normally" - meaning that a URL such as /posts/view/4 will route to PostsController::view($id = 4) - you actually need to explicitly define it in the routes file, before the /* definition. Yes, if you're using catch-all routes in Cake, you'll need to explicitly define every Controller::method() route ahead of it to utilize the standard Cake routing conventions.

While this may sound daunting, it's not that bad if you alphabetize all your route definitions in routes.php. Simply look at your project's /Controller directory and list them off in the same order. I also implement a comment above each controller grouping as some require more than one route definition. Here's an example extracted from one of my routes.php files:

/**
 * CaseStudiesController
 */
Router::connect('/case-studies', array('controller' => 'case_studies', 'action' => 'index'));
Router::connect('/case-studies/:action', array('controller' => 'case_studies'));
Router::connect('/case-studies/:action/*', array('controller' => 'case_studies'));
Router::connect('/case-studies/*', array('controller' => 'case_studies', 'action' => 'index'));

/**
 * PostsController
 */
Router::connect('/posts', array('controller' => 'posts', 'action' => 'index'));
Router::connect('/posts/:action', array('controller' => 'posts'));
Router::connect('/posts/:action/*', array('controller' => 'posts'));
Router::connect('/posts/*', array('controller' => 'posts', 'action' => 'index'));

Generally speaking, you'll only need 4 route definitions per Controller. Lastly, here's the bottom end of routes.php in my case:

/**
 * UrlAliasesController
 *
 * This catch-all route is very greedy and even grabs the default CakePHP /:controller/:action URL format
 * Above this line, all public controller methods must be accounted for in specific routes
 */
Router::connect('/*', array('controller' => 'url_aliases', 'action' => 'check', 'admin' => false));

/**
 * Load all plugin routes. See the CakePlugin documentation on
 * how to customize the loading of plugin routes.
 */
CakePlugin::routes();

/**
 * Load the CakePHP default routes. Only remove this if you do not want to use
 * the built-in default routes.
 */
require CAKE . 'Config' . DS . 'routes.php';
etipaced
  • 125
  • 1
  • 11