I have to support url friendly structure for a project.
There is multiple tables with a slug column, in cakephp how can I route the slug to a controller in the most
I'd suggest to go for a custom route class that handles this. While you could query the data in your routes files, this is
The latter point means that when not connecting all routes, trying to generate a URL from a route array for a non-connected route might trigger an exception, or match the wrong route.
With a custom route class you could simply pass the model in the options when connecting the routes, and in the route class after parsing the URL, query that model for the given slug, and return false
or the parsed data accordingly.It's really simple, just have a look at what the existing route classes do.
Here's a very basic example which should be pretty self-explantory.
src/Routing/Route/SlugRoute.php
namespace App\Routing\Route;
use Cake\Routing\Route\Route;
use Cake\ORM\Locator\LocatorAwareTrait;
class SlugRoute extends Route
{
use LocatorAwareTrait;
public function parse($url)
{
$params = parent::parse($url);
if (!$params ||
!isset($this->options['model'])
) {
return false;
}
$count = $this
->tableLocator()
->get($this->options['model'])
->find()
->where([
'slug' => $params['slug']
])
->count();
if ($count !== 1) {
return false;
}
return $params;
}
}
This example assumes that in the controller, you'd use the slug to retrieve the record. If you'd wanted to have the ID passed, then instead of using count()
, you could fetch the ID and pass it along in the parsed data, like:
$params['pass'][] = $id;
It would then end up being passed as the second argument of the controller action.
routes.php
$routes->connect(
'/:slug',
['controller' => 'Articles', 'action' => 'view'],
[
'pass' => ['slug'],
'routeClass' => 'SlugRoute',
'model' => 'Articles'
]
);
$routes->connect(
'/:slug',
['controller' => 'Categories', 'action' => 'view'],
[
'pass' => ['slug'],
'routeClass' => 'SlugRoute',
'model' => 'Categories'
]
);
// ...
This would first check the Articles
model, then the Categories
model, etc., and stop once one of the routes finds a record for the given slug.
See also