Laravel Localization jugando con el parámetro Route Resource

Sep 22 2020

En mi segundo intento he implementado una aplicación Multilingüe para un sitio que estoy trabajando mediante el uso de una Route::groupque prefixesel {locale}en el primer segmento de la URL utilizando routeMiddleware Kernel. Funciona muy bien excepto cuando se recupera la ruta Resourcescon parameters.

La implementación tiene un problema en el sentido de que, por alguna razón, convierte el parameteren %2F{id}(lo cual no es correcto) y no recupera el recurso que PublicGalleriesControllersolicité. No entiendo por qué, porque cuando coloco el cursor sobre el ancla generada, hrefveo el formato de URL correcto. Pero cuando hago clic en él, 404 Not Foundaparece un mensaje con la URL desordenada.

web.php Este es mi grupo de rutas que encapsula todas las rutas con una función

Route::group([
    'prefix' => '{locale}',
    'middleware' => 'setlocale',
], function() {

   // all my routes are within this route group including:
   Route::resource('gallery', 'PublicGalleriesController');

   Auth::routes();

   Route::group(['middleware' => 'auth'], function() {

       ...

   });

});

Aplicación / Http / Middleware / Localisation.php Middleware de ruta que se enruta a travésKernel.php

public function handle($request, Closure $next)
    {
        \App::setLocale($request->segment(1)); return $next($request);
    }

PublicGalleriesController.php Recupera las rutas de las imágenes del modelo y las devuelve a la vista del cliente

    public function show($id)
    {
        // Show gallery group images for given group id
        $pics = null; $path = null;
        $path = GalleryGroup::find($id);
        
        $pics = Gallery::select('imagefilename', 'group_id')->where('group_id', $id)->orderBy('id', 'asc')->get()->toArray();

        return view('gallery.show', compact('pics', 'path'));
    }

Cuando Pase el ratón sobre un enlace foto de grupo galería que es visible en las index.bladese nota en la esquina izquierda del navegador como: localhost/en/gallery/41. El index.bladerecupera las claves primarias del grupo de la galería y crea enlaces de anclaje HTML en un bucle:<a href="{{ url(app()->getLocale(), 'gallery/' . $item['id']) }}">{{$item['descrp']}}</a>

Cuando hago clic en este enlace, debería PublicGalleriesControllerejecutar la showfunción y recuperar todas las fotos del grupo de la galería, pero en su lugar devuelve un 404 Not Foundcon la URL en el navegador localhost/en/gallery%2F41. El %2Fyo creo es una URL codificada barra inclinada.

php artisan route:listmuestra el showrecurso de la siguiente manera:

| Domain | Method    | URI                         | Name         | Action   
         | Middleware                              |
+--------+-----------------------------------------+--------------+-----------------------
|        | GET|HEAD  | {locale}/gallery/{gallery}  | gallery.show | App\Http\Controllers\PublicGalleriesController@show   
         | web,setlocale                           |

¿Alguien puede ayudarme a comprender por qué la URL se está volviendo tan desordenada?

Versión de Laravel: 5.6.39

Respuestas

2 lagbox Sep 22 2020 at 03:49

La firma del urlayudante es:

function url($path = null, $parameters = [], $secure = null)

$parameterses una matriz de parámetros, no una ruta, por lo que está codificando el /que está utilizando, ya que los parámetros son un segmento de la URL, no una ruta.

Puede ajustar la llamada a urlpara tener una ruta más completa o usar la parametersmatriz como segmentos adicionales, no rutas:

url(app()->getLocale() .'/gallery/'. $item['id']); // 1 argument url(app()->getLocale() .'/gallery', [$item['id']]); // 2 arguments
url(app()->getLocale(), ['gallery', $item['id']]);  // 2 arguments

También puede utilizar el routeayudante:

route('gallery.show', ['locale' => app()->getLocale(), 'gallery' => $item['id']]);

Si no desea tener que pasar localetodas las URL que desea generar con el routeasistente, puede ajustar su middleware para establecer un valor predeterminado para este parámetro:

public function handle($request, Closure $next)
{
    App::setLocale($locale = $request->route('locale'));

    URL::defaults(['locale' => $locale]); // set default return $next($request);
}

Ahora no tienes que pasar ese parámetro:

route('gallery.show', ['gallery' => ...]);

Si desea que el localeparámetro no se pase a todas las "acciones" de su ruta (métodos de controlador y cierres), también puede hacerlo. Puede agregar una línea similar a ese middleware antes de devolver la respuesta:

$request->route()->forgetParameter('locale');