CakePHP reverse routing: Html link not showing correct link - cakephp

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

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 - Routing with parameters not working

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'))
);

CakePHP routes for index with parameter

In my cake application, I have a referral program for salespersons. For each signup the user can pass a referral id. Normally, my website has a default route which does the following:
//www.mydomain.com -> www.mydomain.com/pages/home
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Now I want to route to another controller/action like this:
//www.mydomain.com/r:1234 -> www.mydomain.com/users/signup/r:1234
Router::connectNamed(array('r'));
Router::connect('/*', array('controller' => 'users', 'action' => 'signup'));
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
The routing for the signup works fine now, but the default route doesn't work anymore. I think the order is ok. Any ideas?
If i understood your issue than It should be look like this:
//www.mydomain.com/r:1234 -> www.mydomain.com/users/signup/r:1234
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/signup', array('controller' => 'users', 'action' => 'signup'));
Try this one.
Thanks

CakePHP Routers with language, slug, pagination

Using CakePHP 1.3 I am trying to get routers with language, slug, pagination, order .
Currently I have these:
Router::connect('/', array('controller' => 'pages', 'action' => 'index'));
Router::connect("/:controller/:slug", array('action' => 'view'), array('pass' => array('slug')));
Router::connect("/:lang", array('controller' => 'pages', 'action' => 'index'), array('lang' => 'fr|en|de'));
Router::connect("/:lang/:controller/:slug", array('action' => 'view'), array('lang' => 'fr|en|de', 'pass' => array('slug')));
and those are working with language and slug set or slug and pagination , but all three of them fails:
OK - /pages/view/page-slug/page:2
OK - /fr/pages/page-slug
FAIL - /pages/view/page-slug/page:2/lang:fr
I have tried
<?php $this->Paginator->options(array('url' => $this->passedArgs)); ?>
before the paginator but still the same result
Just try this code
Router::connectNamed(array('language','pagination','order','slug'));
Router::connect('/lang/pagination/:slug:order', array(
'plugin' => false,
'controller' => 'pages',
'action' => 'index',
),array(
"pass"=>array("lang","pagination","slug","order")
),array(
'pagination' => '[0-9]+',
'order' => '[0-9]+',
)
);

Resources