zen of coding

Overriding default URL's (aka persistent routes)

CakePHP’s routes allow for an easy way to serve content by using URL aliases.

Let’s take an example from the manual:

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

By having the user access the URL such as example.com/cooks/index simply shows the default view for example.com/users/index (as was our intention).

However, if you have a bunch of links on that page, which point to other actions in the Users controller, the URL’s will remain as example.com/users/some_other_action. In some cases it may not be desired, i.e. if a visitor entered the section of your site by using the “cooks” URL, you don’t want to suddenly confuse them by presenting a completely different link to other actions. Otherwise, you may simply wish to be consistent (or sneaky).

A simple override of the Helper::url() method allows us to solve this problem.
(Place the following in your app_helper.php)

public function url($url = NULL, $full = FALSE) {
  if(strstr($this->params['url']['url'], 'cooks') && $url['controller'] == 'users') {
    $url['controller'] = 'cooks';
  }

  return parent::url($url, $full);
}

That’s it, now any link that would otherwise point to example.com/users/some_other_action will now point to example.com/cooks/some_other_action.

p.s. You might want to add an additional check: isset($url[‘controller’])

  • Pingback: Tweets that mention Overriding default URL’s (aka persistent routes) « nuts and bolts of cakephp -- Topsy.com()

  • Hellbot

    Maybe
    Router::connect(
    ‘/cooks/:action/*’, array(‘controller’ => ‘users’)
    );

    will works too ?

  • @Hellbot

    Depends on what you are trying to do…

  • Yes,
    Router::connect(
    ‘/cooks/:action/*’, array(‘controller’ => ‘users’)
    );

    ..will work also i think.

  • Phally

    It took me a while to figure out what the problem really was. Looking at the comments above, I wasn’t the only one. The key was in: “In some cases it may not be desired, i.e. if a visitor entered the section of your site by using the “cooks” URL, you don’t want to suddenly confuse them by presenting a completely different link to other actions.”

    So two different URLs and the same controller/action, but this means you are deliberately serving duplicate content (ignoring the changed links)? It’s a bit odd design, client requirement? It is DRY though.

  • @Phally

    I think it’s more applicable in an intranet situation, where duplicate content served over the same URL makes little difference.

    Like, example.org/user/do_some_things as well as example.org/specialist/do_some_things… essentially the actions are exactly the same, however the URL would not change for “specialist” if she browses to a different section. And all logic remains in a single controller.

%d bloggers like this: