Cakephp routing only for frontend pages without a prefix - cakephp

I am working on site
http://solarsmart.com.pk/
and I have created a controller and action for pages which gets all the pages data from database on the basis of last two values from the following url
http://solarsmart.com.pk/pages/page/about/about-us
I want to remove /pages/page which are controller and action respectively. if I set the route as follows
Router::connect('/*', array('controller' => 'pages', 'action' => 'page','manager'=>FALSE));
It works but then the problem arises that the admin routing pages also redirect to pages/page I want them to remain as they are right now

I had the same problem and what I did following
I got the url from the Router Class like
$curUrl = Router::url();// returns the current url of the page
$curUrl = explode('/', $curUrl); // exploding on the base of '/'
then I checked that if the url has the required prefix or not
which in your case will be like the following
if (!in_array('admin', $curUrl)) {
Router::connect('/*', array('controller' => 'pages', 'action' => 'page', 'admin' => FALSE));
}

Related

Kohana 3.2 routing issue

I have set up my routes so that most classes are called in the standard controller/action style. However for my front end I don't want users to see the action being called, so all front end pages have their own controller and use the index action. These are my routers in bootstrap:
Route::set('normal', '<controller>(/<action>(/<arguments>))',
array(
'arguments' => '.*'
))
->defaults(array(
'controller' => 'admin',
'action' => 'index',
));
Route::set('default', '(<controller>(/<arguments>))',
array(
'arguments' => '.*',
))
->defaults(array(
'controller' => 'home',
'action' => 'index',
));
I currently have three front end pages, home, about_us and services. They all work great if I don't pass any arguments in through the URL, but the problem occurs if I try to pass an argument in through the URL into arguments. In services there is only action_index() to display the page and it checks for any arguments, and displays results based on the argument. However if I try to browse to /services/1 to pass in 1 as an argument I get this 404 error:
Kohana_HTTP_Exception [ 404 ]: The requested URL services/1 was not found on this server.
It just uses the first route, normal. Once it can't find the action it doesn't even try to use the second route, which would work. If I swap the order of the routes then it works, but all my other classes that use the first controller stop working as all my actions get passed to action_index() as arguments.
How can I get this working? Why when the first route doesn't work does Kohana not go on to the second route?
You do not need to create controller per route. You can create custom routes (route names) and specify controller and action name. Read the documentation for further explanation. Routing
For arguments try this:
Route::set('default', '(<controller>(/<arguments>))',
->defaults(array(
'controller' => 'home',
'action' => 'index',
));

CakePHP routing to controller and page

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

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

CakePHP Routing - [home]/slug as URL

I'm trying to get to grips with Cake's routing, but I'm having no luck finding a solution to my particular problem.
I want to map www.example.com/slug to www.example.com/venues/view/slug, where slug is the URL friendly name of a record for a particular venue.
I also want to then map www.example.com/slug/events to www.example.com/events/index/venue:slug.
After reading the CakePHP documentation on Routing, a few times over, I'm none the wiser. I understand how I would create these routes for each individual venue, but I'm not sure how to get Cake to generate the routes on the fly.
You want to be careful mapping something to the first path after the domain name. This means that you would be breaking the controller/action/param/param paradigm. You can do this, but it may mean that you need to define every url for your site in your routes file rather than using Cake's routing magic.
An alternative may be to use /v/ for venues and /e/ for events to keep your url short but break up the url for the normal paradigm.
If you still want to do what you requested here, you could do something like the following. It limits the slug to letters, numbers, dashes, and underscores.
Router::connect(
'/:slug',
array(
'controller' => 'venues',
'action' => 'view'
),
array(
'slug' => '[a-zA-Z0-9_-]+'
)
);
Router::connect(
'/:slug/:events',
array(
'controller' => 'events',
'action' => 'index'
),
array(
'slug' => '[a-zA-Z0-9_-]+'
)
);
In your controller, you would then access the slug with the following (using the first route as an example).
function view(){
if(isset($this->params['slug'])){
//Do something with your code here.
}
}
First off, you're not connecting www.example.com/slug to www.example.com/venues/view/slug, you're connecting /slug to a controller action. Like this:
Router::connect('/:slug',
array('controller' => 'venues', 'action' => 'view'),
array('pass' => array('slug'));
To generate the appropriate link, you'd do the same in reverse:
$this->Html->link('Foo',
array('controller' => 'venues', 'action' => 'view', 'slug' => 'bar'))
That should result in the link /bar.
The problem with routing a /:slug URL is that it's a catch-all route. You need to carefully define all other routes you may want to use before this one.

Cakephp, Route old google search results to new home page

I have created a new website for a company and I would like all the previous search engine results to be redirected. Since there were quite a few pages and most of them where using an id I would like to use something generic instead of re-routing all the old pages.
My first thought was to do that:
Router::connect('/*', array('controller' => 'pages', 'action' => 'display', 'home'));
And put that at the very end of the routes.php file [since it is prioritized] so that all requests not validating with previous route actions would return true with this one and redirect to homepage.
However this does not work.
When I use a different path on the Router it redirects successfully. For example if I give it:
Router::connect('/*', array('controller' => 'projects', 'action' => 'browser'));
it works fine. The problem arises when the controller used is pages, action display etc.
I'm pasting my routes.php file [since it is small] hoping that someone could give me a hint:
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/company/*', array('controller' => 'articles', 'action' => 'view'));
Router::connect('/contact/*', array('controller' => 'contacts', 'action' => 'view'));
Router::connect('/lang/*', array('controller' => 'p28n', 'action' => 'change'));
Router::connect('/eng/*', array('controller' => 'p28n', 'action' => 'shuntRequest', 'lang' => 'eng'));
Router::connect('/gre/*', array('controller' => 'p28n', 'action' => 'shuntRequest', 'lang' => 'gre'));
Router::parseExtensions('xml');
Instead of trying to handle everything within the cakePHP route file, I would recommend that you use the .htaccess file to 301 redirect pages as necessary.
What you have above will not transfer the rankings over because as far as i can see there is no 301 redirect being outputted in any of the routes.php based solutions you proposed.
The bigger problem is that a Route doesn't redirect, it connects URLs with responses. In other words, it makes sure that your now invalid URLs still yield a valid page. Which is exactly the opposite of what you want to achieve.
You want to tell visitors that a URL that used to be valid isn't anymore. You do this by issuing appropriate HTTP response codes, 301 Moved Permanently in this case. Without doing this the URLs will still appear valid to search engines and they won't update their index.
You'd either have to connect all the invalid URLs via Routes to some controller action that'll issue a $this->redirect('...', 301) or you could use some .htaccess rules to redirect. Which one to use depends on the complexity of the redirect, but you'll probably be able to use simple .htaccess mod_rewrite rules.
There are enough examples on SO: https://stackoverflow.com/search?q=htaccess+301+redirect

Resources