views:

26

answers:

2

I need to create routes that include a colon to produce URLs like http://app.com/prjct:a9b5c. Obviously it's currently simple to use a slash instead with the default routing.

$SLUG = array('slug' => '[-_A-Za-z0-9]+');
Router::connect('/prjct/:slug', array('controller' => 'projects', 'action' => 'show'), $SLUG);

But routes specifications use the colon character as a special indicator, which interferes with my naive attempt to replace the second slash above with another colon.

How do I use colons in this case for a route?

+1  A: 

I think this is indeed out of scope for simple routes. I see two options:

  1. Use a custom route parsing class, as described here. There isn't a whole lot of documentation on the topic, but you can extend the existing class and play around with it to get a hang of what it's doing. Then customize it to your needs.

    class MyRoute extends CakeRoute {
        public function parse($url) {
            debug($url);    // input
            $route = parent::parse($url);
            debug($route);  // output
            return $route;
        }
    }
    
  2. Route these URLs with a catch-all route to a controller, where the parameter will be available as a named parameter in $this->params['named']. Do what you need to do there.

deceze
+1  A: 

You can use named parameter as explained in CakePHP Cookbook. Write code below in your app/config/routes.php:

// Parse only the 'prjct' parameter if the current action is 'show' and the controller is 'projects'.
Router::connectNamed(array('prjct' => array('action' => 'show', 'controller' => 'projects')));

// Then set default route to controller 'projects' and action 'show
Router::connect('/', array('controller' => 'projects', 'action' => 'show'));

In your projects_controller.php :

function show(prjct = null) {
    // Check if prjct match the pattern
    $pattern = '[-_A-Za-z0-9]+';
    if(!preg_match($pattern, prjct)){
        // Redirect somewhere else
    }
    // Rest of your code here
} 
Jamal Aziz