CakePHP routing multilingual blog with canonical links - php

I have the following routes set up on my CakePHP site
Router::connect('/:language/blog', array('controller' => 'posts', 'action' => 'index'), array('language' => 'en', 'persist'=>array('language')));
Router::connect('/:language/blogue', array('controller' => 'posts', 'action' => 'index'), array('language' => 'fr', 'persist'=>array('language')));
Router::connect('/:language/blog/:post_id', array('controller' => 'posts', 'action' => 'view'), array('language' => 'en', 'persist'=>array('language', 'post_id')));
Router::connect('/:language/blog/:post_id/:slug', array('controller' => 'posts', 'action' => 'view'), array('language' => 'en', 'persist'=>array('language', 'post_id', 'slug')));
Router::connect('/:language/blogue/:post_id', array('controller' => 'posts', 'action' => 'view'), array('language' => 'fr', 'persist'=>array('language', 'post_id')));
Router::connect('/:language/blogue/:post_id/:slug', array('controller' => 'posts', 'action' => 'view'), array('language' => 'fr', 'persist'=>array('language', 'post_id', 'slug')));
Which gives me URLs like /en/blog or /fr/blogue Is there a way to remove the language from appearing in the URL and have it just display /blog or /blogue (but still persist the language param)?
If that's not possible I can probably live with keeping the language in the url however this next bit is really important. I have something like this in my <head>
echo '<link rel="canonical" href="'. Router::url($this->request->here true) .'">';
where I'd like to include a canonical URL for SEO. I'd like the canonical URL to be simply /blog/123 but it is always showing as whatever the current url is ie. /en/blog/123/article-slug or /fr/blogue/123/article-slug. Does anyone know how I can get the desired behavior? (side question: does removing the slug part from the canonical url defeat the purpose of using friendly URLs for SEO?)

I solved it by changing my routes to these
Router::connect('/blog', array('controller' => 'posts', 'action' => 'index', 'language'=>'en'), array('persist'=>array('language')));
Router::connect('/blog/:post_id', array('controller' => 'posts', 'action' => 'view', 'language'=>'en'), array('persist'=>array('language', 'post_id')));
Router::connect('/blog/:post_id/:slug', array('controller' => 'posts', 'action' => 'view', 'language'=>'en'), array('persist'=>array('language', 'post_id', 'slug')));
Router::connect('/blogue', array('controller' => 'posts', 'action' => 'index', 'language'=>'fr'), array('persist'=>array('language')));
Router::connect('/blogue/:post_id', array('controller' => 'posts', 'action' => 'view', 'language'=>'fr'), array('persist'=>array('language', 'post_id')));
Router::connect('/blogue/:post_id/:slug', array('controller' => 'posts', 'action' => 'view', 'language'=>'fr'), array('persist'=>array('language', 'post_id', 'slug')));
and in my Posts controller View action I added
$this->set('canonical', Router::url(array('controller'=>'posts', 'action'=>'view', 'post_id'=>$post['Post']['id'], 'language'=>'en')));
And in the <head> section of my layout file I added
if (!isset($canonical)) {
$canonical = $this->request->here;
}
if ($canonical !== false) {
echo '<link rel="canonical" href="'. Router::url($canonical, true) .'">';
}

What about just removing the :language and setting it for each?:
Router::connect('/blogue/:post_id/:slug',
array('controller' => 'posts', 'action' => 'view'),
array('language' => 'fr', 'persist'=>array('post_id', 'slug')));
Router::connect('/blog/:post_id/:slug',
array('controller' => 'posts', 'action' => 'view'),
array('language' => 'en', 'persist'=>array('post_id', 'slug')));

Related

Make Cakephp urls more SEO friendly

I know this question is been asked several times, and I went through all other solutions, but I could do not solve the issue.
https://www.example.com/cars/view/161/BMW-X5
to be
https://www.example.com/cars/161/BMW-X5
my routes.php
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/admin',array('controller' => 'users', 'action' => 'login', 'admin' => true));
CakePlugin::routes();
require CAKE . 'Config' . DS . 'routes.php';
You can simply connect with
Router::connect('/cars/*', array('controller' => 'cars', 'action' => 'view'));
CarsController::view() will receive single argument, which should be used to find car by name.
Link with $this->Html->link('My Link', array('controller' => 'cars', 'action' => 'view', $slug));
For more route components, you need to use named parameters:
Router::connect('/cars/:id/:slug',
['controller' => 'cars', 'action' => 'view'],
[
// :id parameter will be passed as argument of CarsController::view()
'pass' => ['id']
]
);
Link with $this->Html->link('My Link', array('controller' => 'cars', 'action' => 'view', 'id' => $id, 'slug' => $slug));

CakePHP: Redirect url in routes.php

I'm not sure what I'm doing wrong but I'm trying to redirect an old url to a new url using routes.php
old url = www.mywebsite.com/old_url
new url = www.mywebsite.com/sub_folder/old_url
here's all the different attempts I've tried independently and all have failed:
Router::connect('/old_url', array('controller' => 'my_controller', 'action' => 'old_url'), array('pass' => array('/sub_folder/old_url')));
Router::connect('/old_url', array('controller' => 'my_controller', 'action' => 'old_url'));
Router::redirect('/old_url', array('controller' => 'my_controller', 'action' => 'old_url'));
Router::redirect('/old_url', array('controller' => 'my_controller', 'action' => 'old_url'), array( 'pass' => '/sub_folder/old_url'));
Router::redirect('/old_url', array('controller' => 'my_controller', 'action' => 'old_url'), array( 'persist' => '/sub_folder/old_url'));
I've looked through the book. Is this possible? Any guidance is appreciated.
Router::connect('/old_url/*', array('controller' => 'my_controller', 'action' => 'old_url'));

Can i hide controller and view name cake php 2?

I am using cake php and due to some reason i want to hide controller and action name from the url . current url us like
http://192.168.1.31/home/this_is_test
where home is controller name and this_is_test is slug which is dynamic . i want the url like
http://192.168.1.31/this_is_test.
my routes.php is
Router::connect('/', array('controller' => 'home', 'action' => 'index'));
Router::connect('/dashboard', array('controller' => 'dashboard', 'action' => 'index'));
Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
Router::connect('/admin/login', array('controller' => 'users', 'action' => 'login', 'admin' => true));
Router::connect('/contents/*', array('controller' => 'contents', 'action' => 'view'));
Router::connect('/home/*', array('controller' => 'Home', 'action' => 'index'));
I have read a couple of solution after googling . also tried this in routes.php . but no luck
Router::connect(
'/:query',
array('controller' => 'Home', 'action' => 'index',1),
array('query' => '[a-zA-Z]+')
);
anybody have idea about this if it is possible??
Your solution
For static text try this:
Router::connect('/this_is_test', array(
'controller' => 'home',
'action' => 'this_is_test OR any_other action name'
));
If it's dynamic
Router::connect('/:id',
array('controller' => 'home', 'action' => 'index'),
array(
'pass' => array('id'),
array('id' => '[A-Za-z]')
)
);
References: Cakephp2.x Route
I hope I knew what you really want to achieve. You can place the Route in the last position. Here is the reference .
Other option would be to use alias for your controller. So you call your controller some thing else and set a new name for your controller then call it in you Route.
If this doesn't work then you would need to write a bespoke Component in order to help you to do that.

301 Redirect CakePHP

I've recently started a new job and I noticed that a page linked to in one of our mailing lists no longer exists. I'm a developer / sysadmin so I thought it would be simple to set up a redirect, however our site is running CakePHP on the backend which I've got no experience with.
I want to redirect oursite.com/page/online-store to just oursite.com
I've tried Router::redirect('/page/online-store', 'http://www.oursite.com', array('status' => 301)); at the bottom of that file but it doesn't seem to be working, it just hangs at page load until I comment that line out.
Relevant lines in routes.php:
// login and register
Router::connect('/login', array('controller' => 'accounts', 'action' => 'login'));
Router::connect('/register', array('controller' => 'accounts', 'action' => 'register'));
// home
Router::connect('/', array('controller' => 'site', 'action' => 'home'));
Router::connect('/admin', array('controller' => 'users', 'action' => 'login', 'admin' => true));
// dashboard
Router::connect('/admin/dashboard', array('controller' => 'pages', 'action' => 'dashboard', 'admin' => true));
// search
Router::connect('/search', array('controller' => 'products', 'action' => 'search'));
// pages
Router::connect('/page/site-map', array('controller' => 'site', 'action' => 'map'));
Router::connect('/page/home', array('controller' => 'site', 'action' => 'home'));
Router::connect('/page/*', array('controller' => 'pages', 'action' => 'index'));
I'd appreciate any help.

Cakephp Nested Routes

I've got a controller called Items and another one called Categories. Items may belong to different Categories.
The routes that I have are
/items
/items/:item_id
/items/categories
/items/categories/:category_id
And this is my routes.php
Router::connect('/items', array('controller' => 'items', 'action' => 'index');
Router::connect('/items/:item_id', array('controller' => 'items', 'action' => 'view'), array('pass' => array('item_id')), array("item_id" => "[0-9]+"));
Router::connect('/items/categories', array('controller' => 'categories', 'action' => 'index'));
Router::connect('/items/categories/:category_id', array('controller' => 'categories', 'action' => 'view', array('pass' => array('category_id')), array("category_id" => "[0-9]+"));
The problem is that the third route fails as it routes to the Items controller which it shouldn't.
How can I fix this problem?
be careful on the order of your routes... cake will match to the first occurrence, so try using your routes like this:
Router::connect('/items', array('controller' => 'items', 'action' => 'index');
Router::connect('/items/categories', array('controller' => 'categories', 'action' => 'index'));
Router::connect('/items/categories/:category_id', array('controller' => 'categories', 'action' => 'view', array('pass' => array('category_id')), array("category_id" => "[0-9]+"));
Router::connect('/items/:item_id', array('controller' => 'items', 'action' => 'view'), array('pass' => array('item_id')), array("item_id" => "[0-9]+"));
good luck
in you config/routes.php
put a line
Router::connect('/items/categories', array('controller' => 'categories',
'action' => 'index'));
or something similar.
it will redirect all you /items/categories to the index action of categories controller.
for admin pages (actions that use admin prefix):
Router::connect('/items/categories', array('controller' => 'categories',
'action' => 'index','admin'=>true));

Categories