Cakephp routing: prefixes and forms
Prefixes are a nice way to define routes for groups of actions, (see the cookbook).
All admin_ actions go with the /admin/
For my project i needed both an admin route and a dashboard route, so i made prefixes for them like:
(/app/config/routes.php)
Router::connect('/dashboard/:controller/:action/*', array('prefix' => 'dashboard'));
Now in the view you can use the following:
echo $html->link('Profile', array('controller'=>'users', 'action'=>'dashboard_profile'), array('title'=>'Edit profile'))
But when it comes to forms things start to break.
For example the following:
echo $form->create('User', array('action'=>'dashboard_profile'));
or this one:
echo $form->create('User', array('url'=>array('controller'=>'users', 'action'=>'dashboard_edit')));
generate the following (wrong) link: /users/dashboard_profile/1
While it does point to the right action (dashboard_profile) you get an error message explaining that this is a private action. The only way to use this private action is to use the prefix method.
The reason for this is that the form generate part in the cake code doesn’t do anything with the routing, thus ignoring the prefix we’ve set.
After some digging in the api i found a cake-way to generate the right url:
echo $form->create('User', array('url'=>$html->url(array('action'=>'dashboard_profile'))));
We use the html helper, that does parse the prefix part and generates a nice correct url, namely: /dashboard/user/profile
The html helper does check for any prefixes in the routing and generates the right url.
Combining the form->create and the html->url we get the right url.


7 Comments
comments rss [?] | trackback uri [?]Just stuck in the same buggy issue this week and used the same approach. Might open a ticket - but as my time is really short, you could do it to! ;-)
If i have the time, i’ll write a testcase :)
There’s a problem with this approach, though, if your cake directory isn’t the root directory. Say your app is in the
cakesubdir. In your example above, you would want the action to be/cake/dashboard/user/profile. But$form->create()will send the output string from$html->url()throughRouter::url()a second time, giving you an action like/cake/cake/dashboard/user/profile.Any idea how to work around this?
OK, here I go answering my own question: if you give
$html->url()a second parameter oftrue, you get an absolute URL. So instead of/cake/dashboard/user/profile, you gethttp://example.com/cake/dashboard/user/profile. On passing through Router::url() again, you get the same URL back, rather than having an extra “cake” appended.Great! you can even:
echo $form->create(’User’, array(’url’=>array(’controller’=>’users’, ‘action’=>’edit’, ‘dashboard’=>true), true));
@jonathan thank for ur tip. It is not fixed yet in cake 1.2.5
After digging into
$form->create()code, i notice the$options['url']['id']mess the custom routing. My solution is set $url['id'] to null, for example, $form->create(’User’, array(’url’=>array(’controller’=>’users’, ‘action’=>’edit’, ‘id’=>null, $user_id)Submit your comment
XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>