【问题标题】:Laravel route locale middleware not working with model bindingLaravel 路由语言环境中间件无法与模型绑定一起使用
【发布时间】:2021-02-28 13:08:27
【问题描述】:

我使用这个指南:https://mydnic.be/post/how-to-build-an-efficient-and-seo-friendly-multilingual-architecture-in-laravel-v2

我有这些路由和中间件:

$locale = request()->segment(1);

Route::middleware('localized')->prefix($locale)->group(function() {
     Route::get('/contacts', 'ContactController@index');
     Route::get('/page/{page}', 'PageController@index');
});

以及从 Kernel.php 本地化的中间件 -> routeMiddleware:

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
        $segments = $request->segments();

        $segments = Arr::prepend($segments, config('app.fallback_locale'));

        if($request->session()->has('language')) {
            $segments[0] = session('language');
        }

        return redirect()->to(implode('/', $segments));
    }
    
    return $next($request);
}

当我访问:site.test/contacts 时,他将我重定向到语言环境:site.com/en/contacts 当我访问 site.test/page/test 时,找不到 404,如果我访问:site.com/en/page/test 然后页面工作。带有路由模型绑定的语言环境重定向问题。

在控制器页面中我有:

public function index(Page $page) 
{
    return view('page', compact('page'));
}

在可翻译的.php中:

'locales' => [
    'de' => 'Deutsch',
    'en' => 'English',
],

在 AppServiceProvider 中:

public function boot()
{
    if(array_key_exists(request()->segment(1), config('translatable.locales'))) {
        app()->setLocale(request()->segment(1));
    }
}

【问题讨论】:

  • 您确定上面的示例代码有效吗?当我试图复制“当我访问时:site.test/contacts 他在语言环境中重定向我:site.com/en/contacts”但它对我不起作用,除非我添加语言环境 site.test/fr/contacts ..然后它工作。你的 translatable.php 配置文件是如何设置的?
  • @KolawoleEmmanuelIzzy 我用配置和提供者更新了我的问题。是的,我的代码有效

标签: php laravel


【解决方案1】:

我能够解决这个问题,但这使我们无法访问会话,您检查了会话是否具有“语言”,如果是,那么前置语言环境值应设置为会话中的语言值。以下是我所做的;

在路由文件中

$locale = request()->segment(1);

Route::prefix($locale)->group(function() {
     Route::get('/contacts', function(){
         echo "hello contact";
     });
     Route::get('/page/{page}', function(Request $request, $page){
        return "hello Page {$page}";
     });
});

在 MiddleWare 文件中我做了

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // Remove the session check as we don't have access to session yet
    /*if($request->session()->has('language')) {
        $segments[0] = session('language');
    }*/

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}

现在在中间件的 Kennel.php 文件中,在 $middleware 数组中添加您的中间件类

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];

然后尝试访问 site.test/page/1000 ...它将被重定向到 site.test/{app.fallback_locale}/page/1000。在我的情况下 site.test/en/page/1000

更新

在阅读了这个issue on git for laravel 之后,我想到了在本地化中产阶级之前添加会话并且它起作用了。我不确定这是否是一种好的做法,但它完成了工作。

在 MiddleWare 文件中我做了

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // We can have session back on
    if($request->session()->has('language')) {
        $segments[0] = session('language');
    }

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}

现在在中间件的 Kennel.php 文件中,在本地化中间件类之前添加 Session 中间件

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \Illuminate\Session\Middleware\StartSession::class,
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];

【讨论】:

  • 但是我需要保存会话 :)) 你的解决方案会影响所有路由,但我只需要影响我想要的路由。
  • 是的,但是路由问题仍然存在,我不需要影响所有路由。我有来自 laravel nova 的路线,但我的 nova 不工作。
  • 当我访问:site.com/nova 时,他将我重定向到 site.com/en/nova。我得到 404 not found... 在 /nova 我不需要中间件
  • 您可以使用 if 检查排除这些路由(您已经可以在中间件中访问 Nova(即 $segments[1] )
  • 不.. 我有不应该涉及的路线,我无法全部检查
猜你喜欢
  • 2020-03-29
  • 2018-02-09
  • 1970-01-01
  • 2015-10-26
  • 2020-05-05
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
相关资源
最近更新 更多