I am facing some problems in routing under cakephp
there are three actions in my controller
they are as below
www.example.com/photos/newphotos
www.example.com/photos/random
www.example.com/photos/popular
I want them as
www.example.com/newphotos
www.example.com/random
www.example.com/popular
so i routes file under config file I wrote as
Router::connect('/:newphotos', array('controller' => 'photos', 'action' => 'newphotos'));
Router::connect('/:popular', array('controller' => 'photos', 'action' => 'popular'));
Router::connect('/:random', array('controller' => 'photos', 'action' => 'random'));
its working fine when I hit the url
www.example.com/newphotos
but when I hit url www.example.com/random or www.example.com/popular , its again point to action newphotos.
so how can I solve it
(In other words I need to remove controller name "photos" from url for every action)
Many thanks
Why not remove the : from the routes?
If you want to stick with /: paths, then you would need to supply a third parameter to Router::connect() in which to specify patterns for the added options. That is, if you have /:popular as the first parameter, you would need array('popular' => 'popular') as the third parameter, making the rule look like:
Router::connect('/:popular', array('controller' => 'photos', 'action' => 'popular'), array('popular' => 'popular'));
This means that :popular will be matched against the given regex, that is the literal 'popular'. See CakePHP's docs for more info.
Nevertheless, this is useless and silly, so you should stick with paths without colons.
Just delete the colon from the first parameter. They are kind of "capturing variables", so now you basically are routing all / with some parameters to photos/newphotos, and the parameters being captured to :newphotos. As it always will match the first route, then it will not look for the others.
Related
I've been setting up some routes like this:
Router::connect('/background/a-page', array('controller' => 'background', 'action' => 'a_page'));
Router::connect('/background/another-page', array('controller' => 'background', 'action' => 'another_page'));
Router::connect('/background/my-third-page', array('controller' => 'background', 'action' => 'my_third_page'));
// More routes here
I would like to replace them with a route like this:
Router::connect('/background/:action', array('controller' => 'background'));
where the url /background/my-third-page would map to the action my_third_page (in the background controller). Note that the url has dashes and the action has underscores.
Currently Cake fails to map the conversion from dashes to underscores, so with my new route this fails: /background/my-third-page but this works: /background/my_third_page
I want to keep dashes in the urls. Is there any way to make Cake map the dashes to underscores?
I'd also like the reverse routing to map from underscores to dashes, so:
$this->Html->link('View',
array('controller' => 'background', 'action' => 'my_third_page')
);
would map to: background/my-third-page.
Thanks!
This is fighting against CakePHP's naming conventions for URLs http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html. You are better off using mod rewrite for this sort of thing - and again, since this is against the way URLs are normally done in cake, cake will fight you tooth and nail.
http://book.cakephp.org/2.0/en/installation/url-rewriting.html may give you some ideas for what you want to do.
I asked a related question some time ago.
Is it possible to use Route::Connect to route to a query string parameter?
I'm making my first page which requires a parameter called $hash. My route is currently this:
Router::connect('/activate/*', array('controller' => 'users', 'action' => 'activate'));
which works almost perfectly, but if I enter a URL like:
http://localhost/activate/something/somethingelse/long/url
it matches the route. I want it to only match one 32 character long parameter like this:
http://localhost/activate/ajsheeugnbloiuffheogysswhvnntpdd
and for everything else to lead to a 404. What's the correct method of doing this?
You can set the regex matching for the route something like
Router::connect(
'/activate/:id',
array('controller' => 'users', 'action' => 'activate'),
array('id' => '[a-zA-Z]{32}')
);
you can adjust the regex, currently it's just letters.
Here's the reference: http://book.cakephp.org/2.0/en/development/routing.html#route-elements
I'm try to create search engine friendly URLs for the pages controller, i.e. /about instead of /pages/about.
I've tried setting up the following routes (at the bottom of routes.php):
Router::connect('/*', array('controller' => 'pages', 'action' => 'display'));
and
Router::connect('/:page', array('controller' => 'pages',
'action' => 'display'), array('pass' => array('page'), 'page' => '[a-z]+'));
Both properly match /about, /support, etc. However, failed when I had a action/method pair. For example, /contact should route to PagesController->contact(). However, the above routed it to PagesController->display().
There has to be a way to accomplish this without making a specific route for each page. How can I create a route or set of routes that:
Mimics the default route behavior for
the PagesController. That is routes
to display() unless a action/method
pair exists.
Does so with search engine friendly URL. That is coming from root / not /pages.
Demonstrate both the Router::connect() and Html->link()
I have checked for examples in the CakePHP Book and viewed other questions such as CakePHP routing in pages controller. Nothing seems to satisfy the specification above.
You need to create a second route for the contact method call and put it before the more generic rule to match "everything [a-z] after /pages". Try that before your rule:
Router::connect('/contact', array('controller' => 'pages', 'action' => 'contact'));
Always keep in mind that the order of routes is important. The more generic a rule is the more will it match. So put more specific rules in front of the more generic ones.
I've got a question considering Zend_Controller_Router. I'm using a a modular-structure in my application. The application is built upon Zend-Framework. The normal Routes are like this:
/modulename/actionname/
Since I always use an IndexController within my modules, it's not necessary to provide it in the url. Now I am able to append params like this:
/modulename/actionname/paramkey/paramvalue/paramkey/paramvalue
So this is normal in ZF, I guess. But in some cases I don't want to provide a paramkey within the url. For example I want a blog-title to be shown within the url. Of course this is intended for SEO:
/blog/show/id/6/this-is-the-blog-title
In this case, blog is the module, show is the action. id is a paramkey and 6 is the id of the blogpost I want to show. this-is-the-blog-title is of course the headline of the blogpost with the id 6. The problem is, that if I do use the assemble()-method of the router like this:
assemble(array('module' =>'blog',
'action' => 'show',
'id' => $row['blog_id'],
$row['blog_headline_de'] . '.html'));
the url results in:
blog/show/id/6/0/this-is-the-blog-title.html
As you can see a 0 is inserted as a key. But I want this 0 to be omitted. I tried this by using the blogtitle as key, like this:
assemble(array('module' =>'blog',
'action' => 'show',
'id' => $row['blog_id'],
$row['blog_headline_de'] . '.html' => ''));
This results in:
blog/show/id/6/this-is-the-blog-title.html/
Now the 0 is omitted, but I've got the slash at the end.
Do you have any solution to get an url without 0 as key and without an ending slash?
Regards,
Alex
You might want to use a custom route for this:
$router->addRoute(
'blogentry',
new Zend_Controller_Router_Route('blog/show/:id/:title',
array('controller' => 'index', 'module' => 'blog'
'action' => 'info'))
);
And call your assemble with the route as second parameter. See the Zend_Controller_Router_Route section of the documentation for more details (they even provide examples with assemble).
Or in a more general way:
$router->addRoute(
'generalseo',
new Zend_Controller_Router_Route(':module/:action/:id/:title',
array('controller' => 'index'))
);
I'm setting up a search system which has urls eg. all parameters are optional and there are 15 possible params in total
http://example.com/search/key1-value/key2-value/key3-value/key13-value/key15-value
Is there a better way to set up the route than this?
Route::set('search', 'search(/<param1>(/<param2>(/<param3>(/<param4>(/<param5>(/<param6>(/<param7>(/<param8>(/<param9>(/<param10>(/<param11>(/<param12>(/<param13>(/<param14>(/<param15>)))))))))))))))')
->defaults(array(
'controller' => 'search',
'action' => 'index',
));
I would then test for them in the controller and parse them to a neat array. Is there any way to specify a route with any number of optional /key-value/ parameters?
EDIT
I noticed the request object has a nice parameter array already -- this leads me back to the Route::set question.. is there a way to phrase it allowing any number of parameters without the ugly ...(/<param14>(/<param15>))))))))... nesting?
No.
PS: someone can say again that short answers are bad, but there is nothing to say more: No, there is no such way.
Route::set('search', 'search(/<params>/)',array('params'=>'\.*'))
->defaults(array(
'controller' => 'search',
'action' => 'index',
));
tried?