-
timanon
Newbie
-
Posts: 2
Threads: 1
Joined: May 2020
Reputation:
0
I was struggling with a Placeholder for the Controller, what I wanted to achieve is to define the controller in the URL like this:
PHP Code: $routes->get('{locale}/(:segment)', '$1::index');
This doesn't work because of the Router, which replaces the Placeholder with preg_replace and the backslash of the generated Namespace tells it, to ignore the next special character:
input:
\App\Controllers\$1::index
output:
\App\Controllers$1::index
To solve the problem, i did rewrite a small piece of code in the Router.php, line 467:
Old code:
PHP Code: if (strpos($val, '$') !== false && strpos($key, '(') !== false && strpos($key, '/') !== false) { $replacekey = str_replace('/(.*)', '', $key); $val = preg_replace('#^' . $key . '$#', $val, $uri); $val = str_replace($replacekey, str_replace('/', '\\', $replacekey), $val); } elseif (strpos($val, '$') !== false && strpos($key, '(') !== false) { $val = preg_replace('#^' . $key . '$#', $val, $uri); } elseif (strpos($val, '/') !== false) { [ $controller, $method, ] = explode('::', $val);
// Only replace slashes in the controller, not in the method. $controller = str_replace('/', '\\', $controller);
$val = $controller . '::' . $method; }
New code:
PHP Code: if (strpos($val, '$') !== false && strpos($key, '(') !== false) { // Tell preg_replace to consider the backslash as a literal character. $val = str_replace('\\', '\\\\', $val); $val = preg_replace('#^' . $key . '$#', $val, $uri); if (strpos($key, '/') !== false) { $replacekey = str_replace('/(.*)', '', $key); $val = str_replace($replacekey, str_replace('/', '\\', $replacekey), $val); } }
// Replace slashes in the controller with backslashes and capitalize the first letter. [$controller, $method,] = explode('::', $val); $controller = str_replace('/', '\\', $controller); $controller = ucwords($controller, '\\'); $val = $controller . '::' . $method;
In addition to dynamic controllers it's also possible to nest the controllers inside the Namespace.
Following routes are working:
PHP Code: $routes->get('{locale}/(:segment)', '$1::index');
$routes->get('{locale}/(:segment)', 'Home/$1::index');
It would be nice to add this or something similar to the official version.
-
timanon
Newbie
-
Posts: 2
Threads: 1
Joined: May 2020
Reputation:
0
I came to this issue because of the language segment, according to Google SEO it's recommended to have this in the URL. I try to negotiate the language if none is defined and reload the page with the evaluated one. So the first segment is always the {local} segment.
Another solution would be to offset the auto-routing like this:
$routes->setAutoRoute(true, 1); \\ second parameter as the offset, first segment is ignored.
Would that be a better solution? Or is there another/better way without defining all routes?
|