I'm trying to create SEO friendly routing. I have a website with hotels and hotel rooms. I want to create a route progression that routes to different controllers/actions.
I want my urls to look like www.hotelwebsite.com/language/hotel-name/room-name
Here are the three routes I need:
If the url has a language parameter + 2 parameters:
$routes->connect('/:language/:hotelname/:room/', ['controller' => 'rooms', 'action' => 'viewRoom']);
where
public function viewRoom($hotel_slug, $room_slug)
in which
:hotelname == $hotel_slug and :room == $room_slug
If the url has a language parameter + 1 parameter:
$routes->connect('/:language/:hotelname/', ['controller' => 'hotels', 'action' => 'viewHotel']);
where
public function viewHotel($hotel_slug)
in which
:hotelname == $hotel_slug
Otherwise use my standard route
$routes->connect('/:language/:controller/:action/*');
Is this even remotely possible?
Surely that's possible, the example routes are almost ready to go, you just need to define which elements should be passed as function arguments, and you most probably have to limit what :hotelname
and/or :room
matches, as otherwise the router will not be able to differentiate between:
/:language/:hotelname/:room
and:
/:language/:controller/:action
and the first route would always win.
Passing as arguments can be configured via the pass
option, like:
$routes->connect(
'/:language/:hotelname/:room',
[
'controller' => 'rooms',
'action' => 'viewRoom'
],
[
'pass' => ['hotelname', 'room']
]
);
$routes->connect(
'/:language/:hotelname',
[
'controller' => 'rooms',
'action' => 'viewHotel'
],
[
'pass' => ['hotelname']
]
);
Restricting what an elment matches can be done via regular expressions like:
$routes->connect(
'/:language/:hotelname/:room',
[
'controller' => 'rooms',
'action' => 'viewRoom'
],
[
'pass' => ['hotelname', 'room'],
'hotelname' => '(?:name1|name2|name3)',
'room' => '[0-9]+'
]
);
If you cannot restrict the elements that way because they are dynamic and/or there are too many, then you'll have to try a custom route class that for example matches against the database, check for example Mapping slugs from database in routing.
See also