CakePHP - Routing with parameters not working - cakephp

I'm trying to connect this:
http://example.com/activate/A1B2C3
To this:
http://example.com/users/activate/A1B2C3
Router::connect('/activate/:token', array('controller' => 'users', 'action' => 'activate'), array('pass' => 'token'));
But the parameter is not being passed along. What am I doing wrong here?

pass must be an array.
Router::connect('/activate/:token',
array('controller' => 'users', 'action' => 'activate'),
array('pass' => array('token'))
);

Related

How to use internationalization in cakephp with custom URL and extensions

I am using cakephp 2.0 for an application...
everything is fine but I am getting some problem with custom URL or SEO friendly URL.
Here are Route rules that I am using
Router::parseExtensions('html', 'rss', 'xml','json');
Router::connect('/:language/:controller/:action/*',array(),array('language' => 'eng|chi'));
Router::connect('/', array('controller' => 'homes', 'action' => 'index'),array('language' => 'eng|chi'));
Router::connect('/backend/*', array('controller' => 'users', 'action' => 'login', 'lab' => true));
Router::connect('/about-us/*', array('controller' => 'homes', 'action' => 'about_us'));
Router::connect('/contact/*', array('controller' => 'homes', 'action' => 'contact'));
Router::connect('/:slug', array('controller' => 'homes', 'action' => 'page'), array('pass' => array('slug'), 'slug'=>'[a-zA-Z0-9-]*'));
Here for "about-us", 'contact-us' and 3rd and main one is ":slug" ( dynamic )
Two problems:
When I try to change language, url is showing lang/controller/action ( abc.com/eng/homes/about_us ) instead of abc.com/eng/about-us.html or abc.com/chi/about-us.html
for other dynamic url eg. abc.com/page-1.html, abc.com/page-2.html, abc.com/page-3.html so on... how to use abc.com/lang/slug with .html ( abc.com/eng/page-1.html or abc.com/chi/page-1.html)
For this I am using the
Router::connect('/:slug', array('controller' => 'homes', 'action' => 'page'), array('pass' => array('slug'), 'slug'=>'[a-zA-Z0-9-]*'))
rule.
When i try to change language, url is showing lang/controller/action ( abc.com/eng/homes/about_us )
The route definitions in the question have this first:
Router::connect(
'/:language/:controller/:action/*',
array(),
array('language' => 'eng|chi')
);
Routes are tested in the order they are declared - this route will match any url which has the language eng or chi passed to it, as all urls have a controller and an action this route will always match.
instead of abc.com/eng/about-us.html or abc.com/chi/about-us.html
If there needs to be a route match for /:lang/:slug - then there has to be a route defined matching that pattern - currently there isn't.
for other dynamic url eg abc.com/page-1.html, abc.com/page-2.html, abc.com/page-3.html so on ... how to use abc.com/lang/slug with .html ( abc.com/eng/page-1.html or abc.com/chi/page-1.html)
I don't fully understand the question but the answer is probably to ensure that all routes exist with a prefix and are defined before the routes without a prefix. e.g.:
Router::parseExtensions('html', 'rss', 'xml','json');
// Define Chinese language routes first as they have a prefix
Router::connect('/chi/', ['controller' => 'homes', 'action' => 'index'],['language' => 'chi']);
Router::connect('/chi/backend/*', ['controller' => 'users', 'action' => 'login', 'lab' => true],['language' => 'chi']);
Router::connect('/chi/about-us/*', ['controller' => 'homes', 'action' => 'about_us'],['language' => 'chi']);
Router::connect('/chi/contact/*', ['controller' => 'homes', 'action' => 'contact'],['language' => 'chi']);
Router::connect('/chi/:slug', ['controller' => 'homes', 'action' => 'page'], ['pass' => ['slug'], 'slug'=>'[a-zA-Z0-9-]*'],['language' => 'chi']);
Router::connect('/chi/:controller/:action/*',[],['language' => 'chi']);
// Define English language routes last as they don't have a prefix
Router::connect('/', ['controller' => 'homes', 'action' => 'index'],['language' => 'eng']);
Router::connect('/backend/*', ['controller' => 'users', 'action' => 'login', 'lab' => true],['language' => 'eng']);
Router::connect('/about-us/*', ['controller' => 'homes', 'action' => 'about_us'],['language' => 'eng']);
Router::connect('/contact/*', ['controller' => 'homes', 'action' => 'contact'],['language' => 'eng']);
Router::connect('/:slug', ['controller' => 'homes', 'action' => 'page'], ['pass' => ['slug'], 'slug'=>'[a-zA-Z0-9-]*'],['language' => 'eng']);
Router::connect('/:controller/:action/*',[],['language' => 'eng']);
In this way all routes can be parsed unambiguously, and generated unambiguously too - assuming language is always passed when generating a url; the persist parameter can help with that.

How can I manage two different routings for a single given user in CakePHP?

For example :
Router::connect(
'/:username',
array('controller' => 'users', 'action' => 'profile'),
array('pass' => array('username'))
);
If the username parameter is prefixed by #, then it will redirect to a method. If not, it will redirect to different method.
Note : I'm using version 2.8
This should work:
Router::connect(
'/#:username',
array('controller' => 'users', 'action' => 'action1'),
array('pass' => array('username'))
);
Router::connect(
'/:username',
array('controller' => 'users', 'action' => 'action2'),
array('pass' => array('username'))
);

CakePHP: redirect via Router::redirect does not preserve params

I am trying to redirect /my-old-url/$slug to /news/$slug in CakePHP with the following code:
Router::redirect(
'/my-old-url/*',
array('controller' => 'news', 'action' => 'view'),
array('persist' => true)
);
Using this code throws an error (may be a bug?)
Warning (2): Invalid argument supplied for foreach() [CORE/Cake/Routing/Route/CakeRoute.php, line 381]
public function persistParams($url, $params) {
foreach ($this->options['persist'] as $persistKey) {
Even trying the following code does not work:
Router::redirect(
'/my-old-url/:slug',
array('controller' => 'news', 'action' => 'view'),
array('persist' => array('slug'))
);
This code redirects my to /news/view without any parameters.
I use the following code to connect the news URLs:
Router::connect('/news',
array('controller' => 'news', 'action' => 'index')
);
Router::connect('/news/:slug',
array('controller' => 'news', 'action' => 'view'),
array('pass' => array('slug'))
);
What to do?
Have you properly setup your routing for the new url?
Router::connect(
'/news/:slug',
array('controller' => 'news', 'action' => 'view'),
array('pass' => array('slug'), 'slug' => '[\w]')
);
Then have it do the redirect with
Router::redirect(
'/old-url/:slug',
array('controller' => 'news', 'action' => 'view'),
array('persistent' => true, 'pass' => array('slug'))
);
I don't believe you need to define slug again ([\w]) in the redirect but if it doesn't work then try it ('slug' => '[\w]' after 'pass').
Obviously you need to test if /news/test works as expected with the routing before trying the redirect.
Try following code
Router::connect('/my-old-url/*', array('controller' => 'News','action' => 'view'),array('params' => '[a-zA-Z0-9]+'));
There probably was a bug in CakePHP. Upgrading to the latest version (currently v2.3.9) did the trick. The code in my question does work.

CakePHP reverse routing: Html link not showing correct link

Firstly, I understand there have been many questions and solutions about this but none I've found fix my issue.
In summary, the Html helper is not reverse routing correctly and instead of URLs like this:
http://website.com/user_of_website/slug_name
I get URLs like this:
http://website.com/things/view/username:user_of_website/slug:a_thing
Here is my router setup:
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
/**
* ...and connect the rest of 'Pages' controller's urls.
*/
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
//User routes
Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
Router::connect('/logout', array('controller' => 'users', 'action' => 'logout'));
Router::connect('/register', array('controller' => 'users', 'action' => 'add'));
Router::connect('/users/:action/*', array('controller' => 'users'));
Router::connect('/things/:action/*', array('controller' => 'things'));
Router::connect(
'/:username/:slug',
array(
'controller' => 'things',
'action' => 'view'
),array(
'username' => '[a-zA-Z0-9_]+',
'slug' => '[a-zA-Z0-9_]+',
'pass'=>array(
'username',
'slug'
)
)
);
Router::connect('/:userName', array('controller' => 'things', 'action' => 'user'),array('pass'=>array('userName')));
And my Html helper:
echo $this->Html->link('View', array(
'controller' => 'things',
'action' => 'view',
'username' => 'user_of_website',
'slug' => 'a_thing'
),array(
'class' => 'text-warning'
));
I really can't see what I'm doing wrong. Any help greatly appreciated.
NB, I'm using CakePHP 2.3
Have you tried if it works if you disable the 'regular' routes for things? E.g. /things/:action/*.
My guess is that, because of the wildcard, this route will match the URL as well, and, because it is defined before your custom route, will be matched in stead.
If that resolves the problem, you may try to move that route below your 'custom' route

In url routing named parameters are not found

I have a about us page url like below:
base_url/cmsPages/index/cmsid:1
And in routes.php i have defined
Router::connect(
'/about_us',
array('controller' => 'cmsPages', 'action' => 'index', 'cmsid' => 1),
);
But i am not getting cmsid in $this->request->params['named']['cmsid'] at index action.
Please help, how can i achieve this.
You can use following:
public function index($cmsid = null) {
// some code here...
}
// routes.php
Router::connect(
'/about_us',
array('controller' => 'cmsPages', 'action' => 'index'),
array('pass'=>array('cmsid'=>1))
);
for detailed information please visit following link :
http://book.cakephp.org/2.0/en/development/routing.html#passing-parameters-to-action
Try this code for getting named parameter
Router::connectNamed(array('id'));
Router::connect('/about-us:id', array(
'plugin' => false
'controller' => 'cmsPages',
'action' => 'index'
),array(
"pass"=>array("id")
),array(
'id' => '[0-9]+'
)
);
If you are using named parameters, you can define this route
Router::connect(
'/about_us',
array('controller' => 'cmsPages', 'action' => 'index'),
array('cmsid'=>1)
);

Resources