CakePHP routing to controller and page - cakephp-2.0

Is it possible to identify a controller and pagename in the same url
Router::connect('/:controller/');
Router::connect('/:pagename/', array('controller' => 'home','action'=>'index'));
www.example.com/controller
so that the controller goes to the :controller/index
www.example.com/pagename
so that the page goes to home/index

Its really confusing what really you wants. If a url ends with :controller like www.example.com/posts its generally map index action. Now if the url ends with pagename, means action, like www.example.com/mypage, you can map that as-
Router::connect('/mypage', array('controller' => 'homes', 'action' => 'index'));
So when a user browse www.example.com/mypage, it will map to HomesController and index action.

Try following code for pagename:
Router::connect('/:slug', array('controller' => 'home', 'action' => 'index'));
UPDATE 1
If you want to treat www.example.com/user as same as www.example.com/users then you need to add following, because CakePHP controller name is plural as per CakePHP naming convention:
Router::connect('/user/:action/*', array('controller' => 'users'));
UPDATE 2
Router::connect(':slug') overwrite all of default routing. So you need to use custom routing class as like as :
App::uses('SlugRoute', 'Routing/Route');
Router::connect(
'/:slug',
array('controller' => 'home', 'action' => 'index'),
array('routeClass' => 'SlugRoute')
);

Related

Routing all but certain parameters in CakePHP

I'm trying to set up a routing definition in my project which will allow users to have profiles accessible by simply using their username as the only parameter in the url, like www.example.com/username as opposed to www.example.com/user/view/username
I've set up a catch all route to go to an action which checks if the user exists, as the last route in the config file, and it works, but it over rides all of the basic routing that cake does. Meaning that I would have to define a route for every controller I want to provide access to just to make sure I never make it to the catchall. My routes:
Router::connect('/events/edit/*', array('controller' => 'events', 'action' => 'edit'));
Router::connect('/events/view/*', array('controller' => 'events', 'action' => 'view'));
Router::connect('/events/add', array('controller' => 'events', 'action' => 'add'));
Router::connect('/events/*', array('controller' => 'events', 'action' => 'index'));
Router::connect('/*', array('controller' => 'users', 'action' => 'view'));
So, this will allow me to access my events page, but any other pages get sent to the second router, expectedly.
What I'd like is to have is a route that does the basic cake function of /controller/action/param if the controller exists, but have it fall through to the last route which goes to the user/view page otherwise.
My question is, for what I'm trying to accomplish, am I doing this the right way? If I need to define a route for every controller I want access to, I will, but I have to think there's a better way to accomplish this.
Thanks
According to the my understanding of your question, I think You can proceed like this.
App::uses('UserRoute','Lib');
Router::connect('/:user_name', array('controller' => 'users', 'action' => 'view'),
array('routeClass'=>'UserRoute', 'pass' => array('user_name')));
and in your app/lib create a file UserRoute.php like this
<?php
App::uses('Lib', 'CakeRoute');
class UserRoute extends CakeRoute {
function parse($url) {
$params = parent::parse($url);
if (empty($params)) {
return false;
}
App::import('Model', 'User');
$User = new User();
$user_count = $User->find('count',array(
'conditions' => array('User.username' => $params['user_name']),
'recursive' => -1
));
if ($user_count) {
return $params;
}
return false;
}
}
Hope this will help you..

CakePHP Routing: Changing pretty URLs site-wide

Let's say I want a page to have a pretty URL:
Config/routes.php
Router::connect('/profile', array('controller' => 'users', 'action' => 'profile'));
If I want to send visitors to that page, I can use the URL like:
$this->redirect('/profile');
$this->Html->link('Your Profile', '/profile');
But let's say I change my mind and I now want the URL to be:
/account
How can I change the entire site without changing every instance of /profile to /account?
Alternatively...
Another way to ask my question would be how can I properly code all URLs using Cake array syntax (which I prefer to do rather than hardcode anything):
$this->redirect(array('controller' => 'users', 'action' => 'profile'));
$this->Html->link('Your Profile', array('controller' => 'users', 'action' => 'profile'));
And then ensure that any time that controller/action combination is called, it sends people to the URL:
/profile
And have this rule in one place that can be changed. Something like:
Router::connect(array('controller' => 'users', 'action' => 'profile'), '/profile');
// Later change to
Router::connect(array('controller' => 'users', 'action' => 'profile'), '/account');
Is there any way to do that, and also allow further request parameters to be passed along to be added to the URL?
Have a look at the routing documentation: http://book.cakephp.org/2.0/en/development/routing.html
In your app/routes.php add:
Router::connect('/profile', array('controller' => 'users', 'action' => 'profile'));
Now you can create your links like this:
echo $this->Html->link('Link to profile', array('controller' => 'users', 'action' => 'profile'));
Or if you want to allow additional parameters:
// When somebody comes along without parameters ...
Router::connect('/profile', array('controller' => 'users', 'action' => 'profile'));
// When somebody parses parameters
Router::connect('/profile/*', array('controller' => 'users', 'action' => 'profile'));
And then you will be able to do something like:
$userId = 12;
echo $this->Html->link('Link to other profile', array('controller' => 'users', 'action' => 'profile', $userId));
The $userId will then be available in the controller via:
echo $this->request->params['pass'][0];
// output: 12
This way you can easily change the url's of your website without having to change every single view/redirect or what so ever. Please bare in mind that you should not change your controller names! Because that will mess up a lot. Choose wisely ;-)
http://book.cakephp.org/2.0/en/development/routing.html
http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html

How to redirect in CakePHP with # in url, and not %23?

I am using CakePHP and I am doing this:
$this->redirect(array('controller' => 'users', 'action' => 'view',$id));
output in the browser: .../users/view/42
Since I am using JQueryUI tabs, I want the user to be redirected to the tab he just edited, so it should looks something like :
$this->redirect(array('controller' => 'users', 'action' => 'view',$id."#groups"));
output in the browser: .../users/view/42%23groups
But expected result: .../users/view/42#groups
Q: How to send a correct url with #id in it to send the focus ?
I want, if possible, not use a custom GET param that echo a js in the view.ctp to get the focus asked.
I hope it is a CakePHP issue and don't need to change some .htaccess like (How to rewrite a URL with %23 in it?)
Please read the documentation
http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::url
$this->redirect(array(
'controller' => 'users', 'action' => 'view', $id, '#' => 'groups'));
This is how I achieved it:
// Redirect to the home page.
$this->redirect(array(
'controller' => 'cars',
'action' => 'index',
'#' => 'thankyou'
));

Cakephp route and prefix

I have a problem with Routes in CakePHP. Let me explain.
I'm using authentication through the Auth component. I have a routing prefix called account.
When I want to edit a user, I'm calling the users controller which gives me a URL like:
/account/users/edit/5
What I want is to have a URL like:
/account/edit/5
So I changed my router like this:
Router::connect('/:prefix/edit/:id',
array('controller' => 'users', 'action' => 'edit'),
array('pass' => array('id'), 'id' => '[0-9]+')
);
which worked when I try to access /account/edit/5
My problem is located in my view. How can I access this route using the Html->link helper?
So far, I'm just doing it like this:
'/'.$this->Session->read('Auth.User.role').'/edit/'.$this->Session->read('Auth.User.id')
But it's not really clean in my opinion. I want to use the helper.
Thanks a lot for your help
Using a prefix "account" would mean needing an action like "account_edit" in your controller. That's probably not what you want. Also why put the "id" in url when it's already there in the session? Why not just use url "/account" for all users and get the id (and role if required) from session in the action?
Router::connect('/account',
array('controller' => 'users', 'action' => 'edit')
);
This would be the clean way to generate required url:
$this->Html->link('Account', array(
'controller' => 'users',
'action' => 'edit'
));
// Will return url "/account"
In general always use array form to specify url to benefit from reverse routing.
everything is just fine except router. it should be
Router::connect('/account/*',
array('controller' => 'users', 'action' => 'edit')
);
and creating anchor link in various way using Helper you can CHECK HERE

How can I redirect the default home page to another page in CakePHP?

I need to redirect the default CakePHP home page / or (/pages/home) to /users/dashboard page
I tried
Router::connect('/', array('controller' => 'users', 'action' => 'dashboard'));
and
Router::connect('/pages/home', array('controller' => 'users', 'action' => 'dashboard'));
But both are not working
You should be able to do this by simply replacing this part of app/config/routes.php:
/**
* Here, we are connecting '/' (base path) to controller called 'Pages',
* its action called 'display', and we pass a param to select the view file
* to use (in this case, /app/views/pages/home.ctp)...
*/
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
.. with something like this:
/**
* Here, we are connecting '/' (base path) to controller called 'Users' and
* its action called 'dashboard' (ie. /users/dashboard)...
*/
Router::connect('/', array('controller' => 'users', 'action' => 'dashboard'));
I sense a slight misunderstanding of the topic when you try to map from '/pages/home' to your dashboard. '/pages/home' only seems like the home page because there exists a route for that. If you want to change the homepage, you need to change the existing Router::connect('/', ...) rule. If you create a new rule for '/', underneath, it won't be executed as CakePHP will match the first route it finds.
your first attempt
Router::connect('/', array('controller' => 'users', 'action' => 'dashboard'));
Is the correct way to do it. If you are still having problems then there must be another issue.
What error do you see?

Resources